文章目录

  • 前言
  • 一、头文件
  • 二、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!");}//枚举设备-endif (count < 1){throw std::exception("can not find any video device!");}//根据第一个设备创建MediaSourcehr = MFCreateDeviceSource(devices[0], &source);if (FAILED(hr)){throw std::exception("create device source error!");}//创建SourceReaderhr = 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简单很多,对代码精简后就变得比较好理解了,流程也很清晰了。

Windows使用Media Foundation采集摄像头数据相关推荐

  1. 关于Windows media foundation打开摄像头无法获取到数据问题

    之前开发应用的时候一直使用的是direct show接口,后面想着使用windows media foundation接口试试,结果始终获取不到数据,关键代码如下: 这里我采用的是异步的方式去读取数据 ...

  2. linux下使用ffmpeg采集摄像头数据并编码成h264文件

    本文讲述如何在linux下,使用ffmpeg采集视频数据,并编码成h264文件. 打算分成3部分讲解: 需要具备的软硬件环境 ffmpeg命令采集摄像头数据并编码成h264文件 ffmpeg代码采集摄 ...

  3. 怎么通过media foundation将图像数据写入虚拟摄像头_[Camera]摄像头镜像

    platform:RK3399 OS:Android 7.1 参考: 1.石先 https://www.jianshu.com/p/7d88ec1347b6 2.KrisFei https://blo ...

  4. 怎么通过media foundation将图像数据写入虚拟摄像头_千倍成本压缩!特斯拉开发虚拟激光雷达,替代最贵自动驾驶传感器...

    「谁用激光雷达,谁完蛋!」 在去年特斯拉举办的 Autonomy Day 上,特斯拉 CEO Elon Musk 言辞激烈地炮轰激光雷达. 「昂贵的传感器是不必要的,这就像是一大堆昂贵的附属品.」 「 ...

  5. 怎么通过media foundation将图像数据写入虚拟摄像头_不知道怎么挑手机?性价比神机绝对适合你...

    阅读本文前,请您先点击上面的蓝色字体,再点击"关注",这样您就可以继续免费收到最新文章了.每天都有分享.完全是免费订阅,请放心关注.注:本文转载自网络,不代表本平台立场,仅供读者参 ...

  6. rk3399 采集摄像头数据_[Camera]摄像头镜像

    platform:RK3399 OS:Android 7.1 参考: 1.石先 https://www.jianshu.com/p/7d88ec1347b6 2.KrisFei https://blo ...

  7. ffmpeg 采集摄像头yuv数据

    本文讲述在linux下,如何使用ffmpeg采集摄像头yuv数据,并保存为文件. 分为4个部分进行讲解 需要的软硬件环境 使用ffmpeg命令采集yuv数据. 使用ffmpeg代码采集yuv数据. 查 ...

  8. 使用live555 直播来自v4l2的摄像头数据

    使用live555 直播来自v4l2的摄像头数据,在我的这个工程中,基本思路是:使用V4L2采集摄像头数据,然后使用x264库对摄像头数据进行编码,编成H264数据格式,然后把数据写入到命名管道中.最 ...

  9. V4L2视频采集与H264编码1—V4L2采集JPEG数据

    最近在做视频编码,经过一段时间的折腾,终于可以把V4L2采集到的图片数据编码成H264视频,并且成功将工程移植到了ARM开发板上.无奈开发板性能太低,每秒钟只能编码一帧数据,查看CPU已经跑到100% ...

最新文章

  1. YOLO-Z | 记录修改YOLOv5以适应小目标检测的实验过程
  2. vscode php调试插件,构建VSCode开发调试环境(强大且实用的插件推荐)
  3. 2021年值得关注的人工智能与机器学习的五大趋势
  4. 修炼九阴真经Windows Phone开发 (11):计划任务PeriodicTask和ResourceIntensiveTask概述和示例...
  5. 传递list对象作为参数_24.scala的隐式参数
  6. 【设计模式】单例模式-生成器模式-原型模式
  7. BeanUtils.copyProperties
  8. 第一次参加项目个人工作总结 (转)
  9. 修改表名的sql语句_SQL第一关——入门
  10. 2020年11月连云港计算机考试,2019年江苏省连云港市下半年全国计算机等级考试考务通知...
  11. 表单标签(HTML)
  12. Exp3 免杀原理与实践 20154328 常城
  13. 小程序服务器装rsshub,RssHub 部署
  14. 京淘项目实战开发-01
  15. Activity基础 - 任务栈
  16. java类型的数组初始化_java数组初始化详解
  17. 人身险信息库大数据开闸 消费者可货比三家
  18. 网管的自我修养-电脑维护
  19. 2018年总结, 2019年规划
  20. 火狐浏览器历史版本下载

热门文章

  1. 客厅这样做 谁不喜欢?
  2. 如何通过短视频拍摄手法提升播放量?原来是用了这5点!
  3. 利用Bootstrap card 制作母亲节小礼物
  4. 前端监听页面显示隐藏 visibilitychange
  5. 生成 .chm 格式帮助文档
  6. 辐射4 中文武器命名方法, 不用winhex, 直接游戏内操作
  7. iOS4.3导致iPhone续航能力下降
  8. 酒店正负向点评可视化
  9. 卷积神经网络(CNN)反向传播算法推导
  10. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java基于用户激励的图书管理系统fx8il