Windows使用Media Foundation采集摄像头数据

2023-05-16

文章目录

  • 前言
  • 一、头文件
  • 二、MF对象
  • 三、示例
  • 总结


前言

在Windows上采集摄像头的数据的方法有几种,vfw、directshow、mf。vfw过于老旧,directshow使用比较复杂,mf就是今天要讲的Media Foundation,其使用方法相对容易些,但是官方的例子略微复杂,对于想要实现简单的摄像头数据采集,并不需要那么多个对象及方法耦合在一起变成一个错综复杂的流程。本文将提供Media Foundation最简单的摄像头采集实现,在此基础上根据自己的需求慢慢添加功能显然是比改造一堆复杂的代码要容易的。


一、头文件

最简单的例子只需要3个头文件

#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>

lib需要如下几个

#pragma comment(lib, "Mfplat.lib")  
#pragma comment(lib, "Mf.lib") 
#pragma comment(lib, "mfreadwrite.lib") 
#pragma comment(lib, "mfuuid.lib") 

二、MF对象

主要对象如下3个

//摄像头设备对象
IMFActivate** devices = NULL;
//底层媒体源对象
IMFMediaSource* source = NULL;
//上层数据读取对象
IMFSourceReader* reader = NULL;

三、示例

#include<exception>
#include <Windows.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#pragma comment(lib, "Mfplat.lib")  
#pragma comment(lib, "Mf.lib") 
#pragma comment(lib, "mfreadwrite.lib") 
#pragma comment(lib, "mfuuid.lib") 
int main(int argc, char* argv[])
{
	CoInitialize(NULL);
	IMFAttributes* attributes = NULL;
	IMFMediaSource* source = NULL;
	IMFSourceReader* reader = NULL;
	IMFActivate** devices = NULL;
	IMFMediaType* mediaType = NULL;
	UINT32 width;
	UINT32 height;
	GUID   subtype;
	UINT32 count = 0;
	DWORD index = 0;
	DWORD flag = 0;
	LONGLONG timestamp = 0;
	bool exitFlag = false;
	//枚举设备
	auto hr = MFCreateAttributes(&attributes, 1);
	if (FAILED(hr))
	{
		throw std::exception("create attributes error!");
	}
	hr = attributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
	if (FAILED(hr))
	{
		throw std::exception("set guid error!");
	}
	hr = MFEnumDeviceSources(attributes, &devices, &count);
	if (FAILED(hr))
	{
		throw std::exception("enum device error!");
	}
	//枚举设备-end
	if (count < 1)
	{
		throw std::exception("can not find any video device!");
	}
	//根据第一个设备创建MediaSource
	hr = MFCreateDeviceSource(devices[0], &source);
	if (FAILED(hr))
	{
		throw std::exception("create device source error!");
	}
	//创建SourceReader
	hr = MFCreateSourceReaderFromMediaSource(source, NULL, &reader);
	if (FAILED(hr))
	{
		throw std::exception("create source reader error!");
	}
	//获取当前默认视频格式(作为最简单例子不展示设置视频格式)
	hr = reader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &mediaType);
	if (FAILED(hr))
	{
		throw std::exception("get media type error!");
	}
	//获取图像格式
	hr = mediaType->GetGUID(MF_MT_SUBTYPE, &subtype);
	if (FAILED(hr))
	{
		throw std::exception("get subtype error!");
	}
	//获取分辨率
	hr = MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height);
	if (FAILED(hr))
	{
		throw std::exception("get frame size error!");
	}
	//开始采集(同步)
	while (!exitFlag)
	{
		IMFSample* sample;
		hr = reader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &index, &flag, &timestamp, &sample);
		if (FAILED(hr))
		{
			throw std::exception("read sample error!");
		}
		if (sample)
		{
			DWORD count = 0;
			BYTE* data;
			DWORD len;
			IMFMediaBuffer* buffer = NULL;
			sample->GetBufferCount(&count);
			for (int i = 0; i < count; i++)
			{
				sample->GetBufferByIndex(i, &buffer);
				if (buffer)
				{
					hr = buffer->Lock(&data, NULL, &len);
					if (FAILED(hr))
					{
						throw std::exception("buffer lock error!");
					}
					//此处获取到图像数据,判断subtype后对数据进行处理
					if (IsEqualGUID(subtype, MFVideoFormat_I420))
					{
						//显示(data,len)
					}
					else if (IsEqualGUID(subtype, MFVideoFormat_YUY2))
					{					
						//显示(data,len)
					}
					hr = buffer->Unlock();
					if (FAILED(hr))
					{
						throw std::exception("buffer unlock error!");
					}
					buffer->Release();
				}
			}
			sample->Release();
		}
	}
	//解除引用
	attributes->Release();
	source->Release();
	reader->Release();
	mediaType->Release();
	for (int i = 0; i < count; i++)
	{
		devices[i]->Release();
	}
    return 0;
}

总结

以上就是今天要讲的内容,之所以发这篇文章,主要是因为笔者自己实现此功能的时候,查找的示例代码都比较复杂,一度以为directshow可能会好用些。经过分析理清示例代码后才发现mf确实要比directshow简单很多,对代码精简后就变得比较好理解了,流程也很清晰了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows使用Media Foundation采集摄像头数据 的相关文章

  • 用于打开大(巨型、巨大、大)文本文件的文本编辑器[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Windows下Kafka托管在Docker中删除主题时出现异常

    我在 Windows 的 Docker 中托管 Kafka 威斯迈斯特 卡夫卡 https hub docker com r wurstmeister kafka 使用 docker 镜像 Kafka 数据存储在本地 Windows 文件夹
  • 避免 Inno Setup 中的“无法展开 shell 文件夹常量 userdocs”错误

    我将一些示例文档安装到 Windows 上标准 我的文档 文件夹的 PerfectTablePlan 子文件夹中 这对于 99 以上的用户来说效果很好 但是 如果用户没有 我的文档 文件夹 我会收到许多以下形式的丑陋错误消息 内部错误 无法
  • 在 Windows 11 上无需管理员权限即可运行 Visual Studio 2022

    我在 Windows 11 上安装了 Visual Studio 2022 当我启动它时 它始终以管理员权限运行 我想在没有管理员权限的情况下运行它 我的 Windows 只有一个帐户 该帐户具有管理员权限 x 我做了什么 确认VS2022
  • 为什么我们从 MultiByte 转换为 WideChar?

    我习惯于处理 ASCII 字符串 但现在使用 UNICODE 我对一些术语感到非常困惑 什么是多字节字符以及什么是widechar有什么不同 多字节是指在内存中包含多个字节的字符吗 widechar只是一个数据类型来表示吗 为什么我们要从M
  • CSS 中 media="screen" 是什么意思?

    下面的 CSS 代码中 media screen 是什么意思
  • 在OpenCV中将YUV转换为BGR或RGB

    我有一个电视采集卡 其输入内容为 YUV 格式 我在这里看到了与此问题类似的其他帖子 并尝试尝试所述的所有可能的方法 但它们都没有提供清晰的图像 目前最好的结果是 OpenCVcvCvtColor scr dst CV YUV2BGR 函数
  • 以编程方式最小化/恢复窗口,跳过动画效果

    我需要对窗口列表执行多项操作 最小化其中一些 恢复其他 以便立即在两组或多组窗口之间切换 这样做的问题是最小化和恢复窗口时可以看到的动画 整个过程看起来很糟糕 所有这些动画都进进出出 上下移动 但是 我无法禁用这些动画 因为这是针对其他计算
  • 更改 mingw' 启动目录或创建 mingw 符号链接

    设置 mingw 控制台启动目录的最简单方法是什么 我只使用 mingw 进行编译 但由于缺乏编辑器甚至符号链接 我很困惑如何告诉 mingw 控制台出现在不同的目录而不是常规的主目录中 如果有人知道如何像 cygwin 那样将 真正的 符
  • 由于图形处理单元配置,不支持 Windows Phone 模拟器(Mac 上的 Windows 7)

    启动 Windows Phone 模拟器时出现错误 不支持 Windows Phone 模拟器 因为您的计算机没有所需的图形处理单元配置 如果没有图形处理单元 XNA 框架页面将无法运行 您想继续启动模拟器吗 当我尝试访问网页 任何网页 时
  • 从命令行运行 R 代码 (Windows)

    我在名为 analysis r 的文件中有一些 R 代码 我希望能够从命令行 CMD 运行该文件中的代码 而无需通过 R 终端 并且我还希望能够传递参数并在我的代码中使用这些参数 例如就像下面的伪代码 C gt execute r scri
  • 如何在Windows上分离“Git bash”中启动的“git gui”?

    例如 我开始 git bash 我导航到某个目录 I start git gui 我关闭控制台窗口或按 Ctrl C Git gui 的窗口消失了 即使我用过git gui disown 即使当我按 Ctrl C 时它不在前台 如何正确分离
  • Git 扩展 - 无法在 Windows 上推送到网络驱动器中的 git bare 存储库

    我正在 Windows 上学习 git 我已经安装了 Git 扩展 版本 2 47 3 并使用了它 我在我的 C 单元中创建了一个裸存储库 作为中央存储库 并在硬盘中的其他任何位置创建了个人存储库 我对硬盘中的这两个存储库进行提交 推送和拉
  • 如何使用来自 Microsoft-Windows-NDIS-PacketCapture 提供程序的实时 ETW 事件?

    更大的问题是一般如何使用实时 ETW 网络堆栈事件 但我特别感兴趣Microsoft Windows NDIS PacketCapture 提供程序 所有其他网络堆栈提供程序都部分工作 但 NDIS PacketCapture NDIS P
  • 需要 TensorFlow 依赖项。如何在 Windows 上运行 TensorFlow

    我有兴趣让 TensorFlow 在 Windows 上运行 但目前我意识到这是不可能的 因为某些依赖项无法在 Windows 上使用 例如巴泽尔 之所以出现这种需求 是因为据我目前了解 从 TensorFlow 访问 GPU 的唯一方法是
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 如何从Windows阻止社交媒体[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我想根据时间阻止我的电脑上的社交媒体 晚上 9 点后屏蔽 上午 11 点后解锁 如家长控制 我尝试过关注但失败了 创建了
  • 如何在批处理文件中回显换行符?

    如何从批处理文件输出中插入换行符 我想做类似的事情 echo hello nworld 这会输出 hello world Use echo hello echo echo world
  • Windows C++ 中的键盘钩子还是什么?

    我希望构建自己的应用程序 它可以将键盘命令 消息 发送到 Windows 操作系统 例如 当我按下组合键 ctrl shift n 时 我希望启动 notepad exe 我怎样才能做到这一点 您对所使用的概念有什么建议吗 我读过 何时使用

随机推荐

  • 泰勒(Taylor)展开式(泰勒级数)

    目录 泰勒公式 余项 1 佩亚诺 Peano xff09 余项 xff1a 2 施勒米尔希 罗什 Schlomilch Roche xff09 余项 xff1a 3 拉格朗日 xff08 Lagrange xff09 余项 xff1a 4
  • 【计算机视觉基础】4.仿射变换

    主要看这个哦 xff1a 马同学 xff1a 如何通俗地讲解 仿射变换 这个概念 xff1f 知乎 简单来说 xff0c 仿射变换 就是 xff1a 线性变换 43 平移 目录 1 线性变换 1 1 旋转 1 2 推移 xff08 图像学中
  • MySQL提升课程 全面讲解MySQL架构设计

    var 课程地址 61 34 http icourse8 com mysqlguanli html 34 let 全选地址右键前往 61 34 http icourse8 com mysqlguanli html 34 目录 第1章 实例和
  • CUDA之nvidia-smi命令详解

    nvidia smi是用来查看GPU使用情况的 我常用这个命令判断哪几块GPU空闲 xff0c 但是最近的GPU使用状态让我很困惑 xff0c 于是把nvidia smi命令显示的GPU使用表中各个内容的具体含义解释一下 这是服务器上特斯拉
  • NMS和softnms代码

    NMS的python代码 import numpy as np def py cpu nms dets thresh 34 34 34 Pure Python NMS baseline 34 34 34 x1 61 dets 0 y1 61
  • Android Webview 大型H5 秒开方案探讨+VasSonic实现h5首页加速

    前言 现在许多app都嵌入了H5页面 然而WebView加载速度慢这个问题却一直影响着用户的体验 所以本文就如何提高H5页面的加载速度展开讨论 问题原因 首先我们需要知道为什么WebView的加载速度那么慢 H5页面的渲染速度其实主要取决于
  • C#学习记录——统一窗体中控件的字体设置

    实例说明 当窗体上有很多控件时 xff0c 如果逐个设置字体属性 xff0c 会非常繁琐 xff0c 这时 xff0c 可以将字体属性设置一致的控件选中进行统一设置 xff0c 这样可以大大节省开发程序的时间 实例运行效果如图1所示 设计过
  • C#学习记录——Visual Studio为项目添加DLL文件引用

    实例说明 DLL文件引用就是在当前项目中引用别的DLL文件 xff0c 可以是用C 编写的类库 xff0c 也可以是别的语言编写的类库 xff0c 这样主要是为了提高程序的开发效率 xff0c 将DLL文件中的一些已有功能直接进行使用 xf
  • C#学习记录——C#编写串口程序

    因为电气自动化专业出差太多 xff0c 考虑学点其他的看能不能实现转行 xff0c 也没太清晰的路线 xff0c 看网上好多推荐电气自动化转C 上位机开发的 xff0c 也抽时间学习了解下C xff0c 因为非软件专业 xff0c 对计算机
  • C#项目实战——【实战】图书馆管理系统

    参考 零基础学C 3 0 学习实现 本篇练习记录一个开发图书馆管理系统示例 1 实现功能简介 图书管理系统利用VS2019集成开发环境进行程序的编程和调试 数据库采用SQL Server 2008 图书管理系统框图如图 普通用户模块具有以下
  • C#项目实战——Windows计算器的制作【实例】

    参考 C 从入门到项目实践 边学习 边练习实现 Windows计算器的制作 此次练习的计算器应用软件在Visual Studio 2019编程环境中开发 是一个简单的窗体应用程序 实现简单的计算器功能 1 系统功能描述 Windows计算器
  • 【触摸屏功能测试】昆仑通态MCGS——物联网功能测试

    测试触摸屏 xff1a 型号 xff1a TPC7022Ni 测试内容 xff1a 物联网产品设备的无线通信和远程调试功能 物联网 1 功能概述 物联网产品设备可通过无线通讯的方式 xff0c 进行远程调试和操作 物联网产品设备支持以下功能
  • 【KingSCADA】如何建立硬件系统及相关变量

    小伙伴们大家好 xff0c 我是雷工 xff01 本篇学习了解KingSCADA3 8如何建立硬件系统及相关变量 xff0c 以下为学习过程和操作记录 一 前言 本篇主要讲解如何定义设备 xff0c 如何定义变量 KingSCADA3 8的
  • 解决Exception: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z 等一系列问题

    一 xff0e 简介 Windows下的 Eclipse上调试Hadoop2代码 xff0c 所以我们在windows下的Eclipse配置hadoop eclipse plugin 2 6 0 jar插件 xff0c 并在运行Hadoop
  • July 16th 模拟赛C T4 奶牛排队 Solution

    空降题目处 点我点我点我 Description 奶牛在熊大妈的带领下排成了一条直队 显然 xff0c 不同的奶牛身高不一定相同 现在 xff0c 奶牛们想知道 xff0c 如果找出一些连续的奶牛 xff0c 要求最左边的奶牛A是最矮的 x
  • AI 工具合辑盘点(十三)持续更新 之 面向宠物爱好者的 AI 工具和面向电影爱好者的 AI 工具

    亲爱的宠物爱好者 xff0c 这个部分是专门为你准备的 x1f43e 不论你是爱狗人士还是铲屎官 xff0c AI 都能满足你 访问地址 xff1a This Cat Does Not Exist 猫咪生成器 你知道喜欢猫的爱好有个专门的名
  • 【KingSCADA】什么是精灵图以及如何创建精灵图

    大家好 xff0c 我是雷工 xff01 本篇学习精灵图的制作 xff0c 以下为学习内容及相关笔记 一 什么是精灵图 精灵图是一种在外观上类似组合图 xff0c 但内部嵌入了比较丰富的动画链接与逻辑控制 xff0c 工程开发人员只要将其从
  • 【数据库】SQL Server2022安装教程

    大家好 xff0c 我是雷工 xff01 最近需要安装SQLServer数据库 xff0c 此次安装的是sql server 2022 developer版本 xff0c 以下记录安装及配置过程 大家可以参考指正 一 安装SQL Serve
  • 网络ip段计算,网络地址计算,广播地址计算,主机号计算规则

    ip网段格式 一个ip段的范围通常是从网络地址 广播地址 xff0c 一般去除网络地址和广播地址后的范围就是一个可用的ip段 xff0c 也就是网络地址 43 1 至 广播地址 1 怎么计算ip的网络地址 xff1f 计算规则 使用ip的二
  • Windows使用Media Foundation采集摄像头数据

    文章目录 前言一 头文件二 MF对象三 示例总结 前言 在Windows上采集摄像头的数据的方法有几种 xff0c vfw directshow mf vfw过于老旧 xff0c directshow使用比较复杂 xff0c mf就是今天要