DirectShow技术介绍(长篇)-2

原创 2011年01月10日 10:06:00

2. 开始DirectShow旅程

     这个章节的内容主要是编写DirectShow应用所需的一些基本概念,可以把它当作一个高级介绍,理解这些内容只需具备一般的编程和有关多媒体的知识。

2.1. 设置DirectShow开发的编译环境

     这节内容描述了如何来编译DirectShow应用。你可以使用命令行形式来编译一个工程,也可以在Microsoft Visual Studio集成环境下(包含VC++)实现。

     头文件:

     所有的DirectShow应用都需要Dshow.h这个头文件,某些DirectShow接口需要附加的头文件,参考接口的说明视具体情况定。

     库文件:

     DirectShow使用以下库文件:

     Strmiids.lib 输出类标识(CLSID)和接口标识(IID),所有DirectShow应用均需此库。

     Quartz.lib    输出AMGetErrorText函数,如果不调用此函数,此库不是必需的。

     有了以上这些头文件和库文件,你已经可以编写DirectShow应用了,但是微软建议使用DirectShow基类库来编写filter,这样可以大大减少程序编写的工作量。要使用DirectShow基类库,需要先编译它,基类库位于SDKSamples/Multimedia/DirectShow/BaseClasses文件夹下,包含两个版本的库:发布版(retail versionStrmbase.lib和调试版(debug versionStrmbasd.lib。具体参见"创建DirectShow Filter"一节。

2.2. DirectShow应用程序编程简介

     这节介绍DirectShow用到的一些基本术语和概念,看完这节后,你将能够编写你的第一个DirectShow应用程序。

FilterFilter Graph

 

     一个DirectShow应用程序是由一个个称为filter的软件构件组合而成的,filter执行一些多媒体流的操作,如:读文件、从视频采集设备中获得视频、将不同的格式的流解码如MPEG1、将数据送到图形卡或声卡中去。

     Filter接收输入并产生输出。举个例子,一个解码MPEG1视频流的filter,输入MPEG1格式的视频流,输出一系列未压缩的视频帧。

     DirectShow中,应用程序要实现功能就必须将这些filter链接在一起,因而一个filter的输出就变成了另一个filter的输入。这一系列串在一起的filter称为filter graph。例如,下图就显示了一个播放avi文件的filter graph:

     File Source(Async) filter从硬盘中读取avi文件;AVI Splitter filter分析文件并将其分解成两个流:一个压缩的视频流和一个音频流;AVI Decompressor filter将视频帧解码,Video Renderer filter将解码后的视频帧通过DirectDrawGDI显示出来;Default DirectSound Device filter使用DirectSound播放音频流。

     应用程序没有必要对这些数据流进行管理,而是通过一个叫Filter Graph Manager这个上层组件来控制这些filter。应用程序调用上层API"Run"(通过graph移动数据)或"Stop"(停止移动数据)。如果你需要对数据流作更多的操作,你可以通过COM接口直接进入filterFilter Graph Manager同样也输出事件通知给应用程序。

     Filter Graph的另一个用途是将filter连在一起创建一个filter graph

     编写一个DirectShow应用程序大体需要三个步骤:

     1.创建一个Filter Graph Manager的实例

     2.使用Filter Graph Manager创建一个filter graph,此时,需要已经具备所有必需的filter

     3.使用Filter Graph Manager控制filter graph和通过这些filter的流,在这个过程中,应用程序会收到Filter Graph Manager发送的事件。

     完成这些后,应用程序需发布这个Filter Graph Manager和所有的filter

2.3. 播放一个文件

     这一章以本节这个有趣的例子来结束,这个例子是一个播放音频或视频文件的简单控制台程序。程序只有寥寥数行,但却展示了DirectShow编程的强大能力。

     正如上一节所讲的创建DirectShow应用程序的三个步骤,第一步,首先,需要调用CoInitialize来作初始化,然后调用CoCreateInstance创建Filter Graph Manager

     HRESULT hr = CoInitialize(NULL);

     if (FAILED(hr))

     {

         return;

     }

 

     IGraphBuilder *pGraph;

     HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,

         CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

 

     如上所示,类标识符(CLSID)是CLSID_FilterGraphFilter Graph Manager由进程内DLLin-process DLL)提供,因此参数3dwClsContext的值为CLSCTX_INPROC_SERVER。由于DirectShow运行自由线程模式(free-threading model),所以你同样可以使用COINIT_MULTITHREADED参数来调用CoInitializeEx

     第二步是创建filter graph,调用CoCreateInstance得到的IGraphBuilder接口包含了大部分创建filter graph的方法。在这个例子中还需要另外两个接口:IMediaControlIMediaEvent

     IMediaControl控制数据流,它包含开启和停止graph的方法;IMediaEvent包含从Filter Graph Manager获取事件的方法,在这个例子中,这个接口用来得到回放结束事件。

     所有这些接口由Filter Graph Manager提供,使用得到的IGraphBuiler接口指针来查询得到。

 

     IMediaControl *pControl;

     IMediaEvent    *pEvent;

     hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);

     hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

 

     现在你可以创建filter graph了,对于文件回放只需要一个简单的调用:

 

    hr = pGraph->RenderFile(L"C://Example.avi", NULL);

    IGraphBuilder::RenderFile方法创建了一个能够播放指定文件的filter graph,事实上,原本需要做的一些如创建filter实例及将这些filter连接起来的工作,都由这个方法自动完成了,如果是视频文件,这个filter graph看起来应该是这个样子:

     [file source]->[如果是缩格式,这里是个解码器]->[Video Renderer]

     要开始回放,调用IMediaControl::Run方法:

       hr = pControl->Run();

 

     filter graph运行时,数据经过各个filter最后回放为视频或音频。回放发生在一个单独的线程中。你可以通过调用IMediaEvent::WaitForCompletion方法来等待回放的结束:

 

       long evCode = 0;

     pEvent->WaitForCompletion(INFINITE, &evCode);

 

     这个方法在播放期间被阻塞,直至播放结束或超时。

     当应用程序结束时,需要释放接口指针并关闭COM库:

 

     pControl->Release();

     pEvent->Release();

     pGraph->Release();

     CoUninitialize();

 

     下面是这个例子的完整代码:

     #include <dshow.h>

void main(void)

{

     IGraphBuilder *pGraph = NULL;

     IMediaControl *pControl = NULL;

     IMediaEvent    *pEvent = NULL;

     // Initialize the COM library.

     HRESULT hr = CoInitialize(NULL);

     if (FAILED(hr))

     {

         printf("ERROR - Could not initialize COM library");

         return;

     }

 

     // Create the filter graph manager and query for interfaces.

     hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,

                         IID_IGraphBuilder, (void **)&pGraph);

     if (FAILED(hr))

     {

         printf("ERROR - Could not create the Filter Graph Manager.");

         return;

     }

 

     hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);

     hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

 

     // Build the graph. IMPORTANT: Change this string to a file on your system.

     hr = pGraph->RenderFile(L"C://Example.avi", NULL);

     if (SUCCEEDED(hr))

     {

         // Run the graph.

         hr = pControl->Run();

         if (SUCCEEDED(hr))

         {

             // Wait for completion.

             long evCode;

             pEvent->WaitForCompletion(INFINITE, &evCode);

 

             // Note: Do not use INFINITE in a real application, because it

             // can block indefinitely.

         }

     }

     pControl->Release();

     pEvent->Release();

     pGraph->Release();

     CoUninitialize();

}

DirectShow技术介绍(长篇)-3

3.2.5. 硬件如何参与Filter Graph     这一节描述了DirectShow如何与音频和视频硬件交互。         外壳filter(Wrapper Filter)     所...
  • bisword
  • bisword
  • 2011年01月10日 10:09
  • 1172

DirectShow技术介绍(长篇)-1

DirectShow 用于控制多媒体数据流;它可以在运行时允许用户播放数字电影和对不同格式的声音进行解码,包括MPEG-1。这种播放性能可以让音视频卡支持Microsoft DirectX?的API,...
  • bisword
  • bisword
  • 2011年01月10日 10:05
  • 2438

DirectShow技术介绍(长篇)-5

3.4. Filter Graph中的数据流     这一节主要描述媒体数据是如何在filter graph中流动的。如果你只是为了编写DirectShow应用程序,你不需要知道这些细节,当然,知道...
  • bisword
  • bisword
  • 2011年01月10日 10:12
  • 769

DirectShow技术介绍(长篇)-9

3.8. 插件发布者(Plug-in Distributors)    Plug-in Distributors(PIDs)是扩展filter graph manager的一种方法。一个PID是f...
  • bisword
  • bisword
  • 2011年01月10日 10:21
  • 627

介绍长篇文档排版技巧2 标准版

  • 2008年12月03日 14:28
  • 448KB
  • 下载

介绍长篇文档排版技巧1 标准版

  • 2008年12月03日 14:26
  • 711KB
  • 下载

DirectShow技术简介

1 DirecX介绍DirectX软件开发包是微软公司提供程序员的一套在Windows操作平台上开发高性能图形、声音、输入、输出和网络游戏的编程接口。微软将DirectX定义为“硬件设备无关性”,即使...

DirectShow技术说明

1 DirectShow的使用: (1):头文件和库 要包含dshow.h头文件,并且链接Strmiids.lib和Quartz.lib库文件。 (2):初始化 DirectShow程序开始的...
  • stardtx
  • stardtx
  • 2012年01月31日 09:40
  • 555

车牌识别技术详解二--directShow采集详解,Video采用FFMPEG做采集解码详解

为系统第一部分:摄像头采集,这里以USB摄像头通过directShow采集为例进行介绍。一个线程做采集,一个线程做检测识别。 http://blog.csdn.net/dansin/article...

DirectShow入门之构建Graph图常用技术(下)

如何查找和某个filter的上下相连的filter   给你一个filter,你可以沿着graph图找到和它相联结的filter。首先枚举filter的pin,检查每一个pin是否有其他的pin...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DirectShow技术介绍(长篇)-2
举报原因:
原因补充:

(最多只允许输入30个字)