使用 MPEG2 捕获设备进行预览和录制






4.39/5 (14投票s)
2004年6月7日
8分钟阅读

222735

9738
本文介绍了如何使用MPEG2采集设备进行预览和录制。适用于所有视频渲染器。可以抓取画面并配置MPEG2解复用器。
引言
众所周知,MPEG2采集设备与RAW电视调谐器采集设备不同。
USB摄像头、电视调谐器等RAW采集设备输出的是YUV未压缩数据,可以在Windows Direct Show下轻松查看,如下所示:
将RAW采集设备添加到图中,然后渲染其输出采集引脚
YUV采集设备和MPEG采集设备同属WDM采集设备系列,在枚举Direct Show滤镜列表时,它们会出现在同一个列表中。
例如,当MSN Messenger、Netmeeting、Yahoo Messenger、Windows Movie Maker等知名应用程序,或Sonic MyDVD、InterVideo WINDVD Creator2等第三方应用程序搜索可用的采集设备时,它们会找到MPEG采集设备并将其显示在选择列表中。
但是问题是,它们支持吗?答案是否定的,为什么呢?
因为,要使用MPEG采集设备,不像RAW采集设备那样,你不能将其添加到图中并选择渲染输出引脚。
AMCap
尝试使用render stream构建图,但我可以肯定地说,它并非总是奏效。
在MPEG采集设备中,你需要手动构建一个不同的图,或者使用图构建器的RenderStream
。
确实,MPEG采集设备需要有自己的设置,但它也可以使用默认设置工作。本文档提到MPEG采集设备可以在没有任何配置的情况下使用默认设置工作。
采集设备的安装可以将其设置为默认模式。当我们启动图的Run时,采集设备将以默认模式工作。
有多种方法可以配置编码器参数,例如,使用IEncoderAPI
(参见DirectX9)。
在本文中,我将展示如何以两种模式构建MPEG2采集图:
- DirectX8.1 – 指的是之前的视频渲染器。
- DirectX9 – 和VMR – 使用Video Mixing Renderer9(Windows 2000)和Video Mixing Renderer(VMR - Windows XP)。
这是因为这些视频渲染器在使用上存在差异,例如全屏、窗口重绘、设置视频窗口等。
例如:一个MPEG2采集图
源代码简介
在这个演示项目中,我们还将做以下工作:
- 如何配置颜色(调节)亮度、色调、色度饱和度和对比度。
- 如何配置输入源 – Composite和SVIDEO。
- 在下一篇文章中,我将介绍如何在MPEG WDM采集设备中使用调谐器。
- 配置Microsoft MPEG2-(推送模式)解复用器。
- 使用三个视频渲染器。
- 切换到三个视频渲染器的全屏模式。
使用GraphEdit
在我们深入研究代码之前,我想向不熟悉GraphEdit工具(Directx SDK\bin\utils)的人解释如何使用GraphEdit构建MPEG2图。
打开GraphEdit,然后从Video Capture Sources中选择
正如你在这里看到的,USB摄像头是RAW采集设备,BeCapture采集设备是MPEG采集设备,它们位于同一个位置。
添加你的MPEG采集设备。
添加Microsoft MPEG2- Demultiplexer。(它位于设备树下的DirectShow Filters条目中。)右键单击以将属性页调出到MPEG2- Demux的前面。
请注意,如果出现错误,则无法显示属性页。这意味着你没有安装DirectX SDK,并且可能只安装了DirectX运行时(redist.)。
打开MPEG2 Demux的属性页后,你会看到这个
在Name中输入Video,然后选择MPEG2 Program Video。(本文将使用节目流,而不是传输流。)
然后点击Create按钮
已创建视频引脚。
对音频引脚做同样的操作。选择你的采集设备的正确音频流。
然后点击创建音频引脚。
结果是我们现在有一个配置为单个音频引脚和单个视频引脚的MPEG2 Demux。
- 创建输出引脚后,你需要配置stream_id Mappings。
- 创建stream ID映射应该在你将采集设备连接到MPEG2解复用器之后进行。所以在这个阶段,关闭属性页(OK)并连接两个滤镜。
- 然后再次打开并转到stream_id Mappings选项卡。
配置stream ID映射前的Stream_id Mappings.
如何配置stream ID映射
我假设你知道你的节目流的stream ID。这些值是编码器设置的一部分。stream ID的值可以设置为0xE0到0xEF(视频流)和0xC0到0xCF(音频流)。
大多数具有单个通道的编码器会将视频和音频stream ID设置为0xE0和0xC0,我们现在将按此进行配置。在stream ID组合框中选择0xE0,在Pin组合框中选择Video,然后在Elementary Stream (A/V only)中选择,如下图所示。
然后按下Map将视频流0xE0映射,如下图所示。
对音频引脚做同样的操作。
我们步骤的结果是这样。
MPEG2采集设备连接到MPEG2解复用器并进行配置.
从这里开始就很容易了,你可以渲染音频和视频引脚,或者从Direct Show列表中添加你喜欢的音频解码器和视频解码器。
我在此指出,从性能的角度来看,选择正确的音频和视频解码器很重要。
并非所有视频和音频解码器的性能都一样,所以尽量选择最好的。
示例代码。
代码在从列表中选择MPEG2采集设备后构建MPEG2图。
如果只有一个MPEG2 WDM采集设备,它会选择那个并启动主应用程序。
代码手动构建整个图。我尝试使用这种方法,因为最终,你的应用程序将使用你选择的用于工作的视频和音频解码器(以简单的方式渲染它)。
代码还展示了如何使用Video Renderer(DirectX 8.1)、Video Mixing Renderer9(Directx9 – Windows2000)和VMR(DirectX9 on Windows XP)。
- 应用程序主类
CMPEGHandler
CDirectShowGraph
此外,我们将视频窗口托管在一个可皮肤化的类中:CActivewindow
。
为了手动选择音频和视频解码器,我们创建了一个抽象类并选择了两个视频和音频组件。
CMSFTAudioDecoder
CeVideoDecoder
为了选择要使用的视频渲染器,请使用全局参数use_vmr9
,如下所示:
- 0 - DirectX 8.1
- 1 - DirectX 9 Windows 2000 VMR9
- 2 - DirectX 9 Windows XP VMR
主窗口
结合GraphEdit,Preview按钮将构建此图:
预览图
代码
预览
快捷方式 – 窗口将是Direct Show窗口。
MPEG2Handler = new CMPEG2Handler(this); MPEG2Handler->Preview(); MPEG2Handler->Run();
按下Record按钮时,我们将构建此图。
Record
快捷方式 – 窗口将是Direct Show窗口。
MPEG2Handler = new CMPEG2Handler(this); MPEG2Handler->Record(); MPEG2Handler->Run();
应用程序菜单
使用菜单,现在你可以抓取画面。这使用了DirectX9的新VMR9和VMR。这在采集设备上已成为非常常见的任务。第二个问题是函数SetVideoClippingWindow
。此函数应在将视频渲染器连接到视频解码器之前设置。否则,在运行图时,它将使用默认的Direct Show视频窗口。DirectX->DX Window显示了这种行为。对于DX8.1 Video renderer的put_Owner
函数也是如此。
Pause
Pause应该被特别关注,尤其是在采集驱动程序本身。有些采集设备上的Pause可能无法完成你请求的任务,因为Live源上的Pause与已存在文件上的Pause不同。
调试
要调试DirectShow滤镜图,你需要使用AddGraphToRot函数进行注册,该函数可以在DirectX SDK示例中搜索到(这也是一个众所周知的任务)。
添加此代码后(别忘了移除),运行你的应用程序并打开GraphEdit工具。点击此按钮。
你创建的滤镜图将出现在此窗口中。
选择它,你构建的图就会打开。此任务可能会失败(异常终止)。忽略它并重复调试步骤,直到成功为止。
反馈和改进
请在下方论坛上发布评论、问题和故事,以便大家受益。我会尽量关注论坛。如果我一段时间没有查看论坛,请随时发送帖子副本或提醒给我。
欢迎将您的补丁和改进提交至support@becapture.com。如果它们符合项目范围,我将集成它们,认可您的工作,并在本页上发布更新后的项目供大家使用。
如果我看到大家积极参与并有需求,我将提交更多版本。这是第二篇文章(第一篇是关于在Code Project上处理MPEG2 WDM采集设备中的Stream Buffer引擎)。我希望听到大家的想法,以及关于一些新类的建议,例如从MPEG2转换为DIVX、MPEG2转换为MP3、MPEG2转换为WMV(Windows Media Encoder)。
最终,我将把我的所有文章整合到一个大型应用程序中,创建一个具有许多功能的完整应用程序。
Visual Basic用户
我的建议是将本文和"Working with SBE.dll"文章合并到一个DLL中,然后在Visual Basic中使用它。(我已经做过了,所以如果你想要适用于Visual Basic或Java的DLL,我很乐意连同文档一起转发)。