码迷,mamicode.com
首页 > 移动开发 > 详细

手机直播系统偶尔会需要到的:Windows 下视频采集技术

时间:2019-01-02 17:31:07      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:rom   vista   ade   逻辑   底部   获取   1.5   做视频   start   

Windows下视频采集的方法

在 Windows 下主要有两种方法来采集视频: 一种是通过 Media Foundation,另一种是通过 DirectShow。

Meida Foundation 是 Windows 从 vista 之后推出的一套全新的 多媒体SDK,简单方便,从 Win7 开始成熟起来。

另一种是 DirectShow,它主要用于 win7 之前的采集视频。使用 DirectShow 编写代码比较麻烦,主要是因为 Windows 工程师按照逻辑电路的思维方式设计了 DirectsShow 的开发接口,引入了什么 filter, pin之类的概念。这些老掉牙的东西现在估计没几个人能搞明白,除非你是从那个时代过来的,哈哈。

这也解释了为啥现在很少有人学习 Windows 程序开发了,就是因为跟不上时代。你看人家 Android/iOS做视频采集多简单,你整的这么麻烦,谁还愿意学!

Media Foundation的一些概念

DirectShow 方案我们放到以后再分析,今天我们主要讲下 MediaFoundation 如何进行视频采集。

在讲之前,我们先要补充一些基本概念。这些概念大家可以从Media Foundation Programming Guide 找到。下面的文字基本是翻译的 Windows 的官方文档。

MF(MediaFoundation)的整体结构图如下:

 
技术分享图片
 

MF 提供了两种不同的编程模型。第一种是上图的左半部分,媒体数据通过端到端的管道传递。Application首先初始化管道,然后调用相应方法控制管道中的流。第二种如上图的右半部分,Application可以从 Source Reader拉数据,也可以向 Sink Writer 推数据。这种模型对于处理数据非常有用。

Primitives 和 Platfrom

图底部的 Primitives 是一些辅助API:

  • Attributes: 相当于一个 Map, 由 key/value 组成。
  • Media Type: 描述媒体数据流的格式。
  • Media Buffers: 存放一段媒体数据。
  • Media Samples: 存放 Media Buffers 的容器,相当于一个 Buffter List。

MF Platform 提供了一些核心功能的API。例如异步调用、工作队列。

Media Pipeline

Media Pipeline 包括三种类型对象:Media Sources、MFTs(Media Foundation Transfors)、Media Sink。

  • Media Sources: 将数据引入到管道里。数据可以来自本地文件,网络流或都是硬件设备。
  • MFTs: 处理流数据。在 MFTs 里实现了编解码器。
  • Media Sink: 消费数据。显示视频到显示屏上,播放声音或写数据到媒体文件。

Media Session 通过管道控制数据流。如质量控制,音频/视频同步,格式的改变。

Source Reader 和 Sink Writer

Source Reader 和 Sink Writer提供了使用 Media Foundation 的另一种方法(相较于 media source, transforms, media sink)。

  • Source Reader 控制着 media source 和 多个解码器。
  • Sink Writer 控制着 media sink 和 多个编码器。

你可以使用 Source Reader 从 media source 获取到压缩或未压缩的数据,并使用 Sinker Writer 编码数据并发送给 media sink。

下面我们就来看看 MF 是如何采集视频数据的。

采集视频数据

通过上面的介绍,我们基本可以知道 MF 采用 从源采集数据,编解码,输出渲染这种架构来处理多媒体。这种方式通俗易懂,使用起来非常方便。

MF采集视频的基本步骤

MF采集数据使用的是架构中的第二种编程模型,其步骤如下:

  • 初始化 COM 组件。
  • 获取视频设备列表。
  • 激活某个视频设备,获取该设备的 Media Source。
  • 根据请求命令和 Media Source 创建 Source Reader。
  • 为 Source Reader 设置 Media Type。
  • 通过 Source Reader 从设备中读取 Media Type 格式的视频数据。

以上就是 MF 从视频设备采集数所的基本步骤,下面我们来详细介绍每一步。

详细分析

由于每一步的代码都实分简单,我这里就不做过多的文字描述了,通过下面的代码及其注释大家很容易理解其中的每一步。

初始化 COM 组件并启动 MF

CoInitializeEx(NULL, COINIT_APARTMENTTHREAD | COINIT_DISABLE_OLEDDE)
MFStartup(MF_VERSION)

获取所有的视频设备

IMFAttributes *videoCmd = NULL; 
IMFActivate **videoDevices = NULL;
UINT32 videoDeviceCount = 0;

//设置获取视频设备的命令
MFCreateAttributes(videoCmd, 1/*表示只分配一项*/);
videoCmd->setGUID(
                MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,  //key
                MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); //value
//获取视频设备列表  
MFEnumDeviceSources(
                videoCmd,
                &videoDevices, //这里是设备列表
                &videoDeviceCount); //这里存放的是设备的个数

激活某个视频设备

IMFMediaSource *mediaSource = NULL;

//激活第一个视频设备,并为该设置备生成逻辑上的媒体源(Media Source)
videoDevices[0]->ActivateObject(IID_PPV_ARGS(&mediaSource));

创建 Source Reader

IMFSourceReader *soureReader = NULL;

//通过媒体源和请求命令,可以获取source reader。(第二种开发模型)
MFCreateSourceReaderFromMediaSource(
                mediaSource,
                videoCmd,
                &sourceReader);

设置 Media Type

IMFMediaType *mediaType = NULL;

MFCreateMediaType(&mediaType);
//设置媒体为视频
mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
//YUV格式为 I420
mediaType->SetGUID(MF_MT_SUBTYPE, WMMEDIASUBTYPE_I420); 
//每个视频帧的大小为 640 * 480
MFSetAttributeSize(mediaType, MF_MT_FRAME_SIZE, 640, 480);
sourceReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                         NULL,
                         mediaType);

读取数据

IMFSample *sample = NULL;
DWORD index, flags;
LONGLONG llVideoTs;

while(runing){
    sourceReader->ReadSample(
                    MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                    0,
                    &index, //实际流的index
                    &flags, //staus flags
                    &llVideoTs, //时间戳
                    &sample); //存放采集到的视频数据
}

通过上面简单的几步,就可以轻松的从视频设备里取到视频数据了。MF相对于 DirectShow真是简单太多了。

上面介绍的是使用同步方式使用MF采集视频数据,MF还提供了效率更高的异步方式获取视频数据,有兴趣的朋友可以以本篇文章为基础去学习它的异步方式。

小结

今天向大家介绍了在 Windows下使用 MF 如何采集视频的方法。通过以下 6 步即可做到:

  • 初始化 COM 组件。
  • 获取视频设备列表。
  • 激活某个视频设备,获取该设备的 Media Source。
  • 根据请求命令和 Media Source 创建 Source Reader。
  • 为 Source Reader 设置 Media Type。
  • 通过 Source Reader 从设备中读取 Media Type 格式的视频数据。

另外, MF 的采集方案只适用于 Win7 以后的系统,对于之前的系统还是要使用 DirectShow 方案。我也会在后面再为大家介绍如何使用 DirectShow 采集视频。

手机直播系统偶尔会需要到的:Windows 下视频采集技术

标签:rom   vista   ade   逻辑   底部   获取   1.5   做视频   start   

原文地址:https://www.cnblogs.com/CDNfast/p/10209283.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!