DirectShow入门-3应用程序编程HelloWorld源代码

http://xujingli88.blog.163.com/blog/static/4117861920080761514962/

3.1. 播放文件例程

这里提供一个控制台应用程序去播放一个音、视频文件。这个程序只有几行长。

在前面介绍了一个基于DirectShow的应用程序,必须要进行如下几个基本步骤:

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

2.使用Filter Graph Manager 建立一个filter graph.

3.运行这个graph

 

调用CoInitialize 去初始化一个这个COM 库。

HRESULT hr = CoInitialize(NULL);

if (FAILED(hr))

{

    // 在这里加入错误处理

}

 

这里,我们跳过了对返回值的检查,当你调用了任何方法的时候都应该对返回值进行检查。下面调用CoCreateInstance创建Filter Graph Manager

IGraphBuilder *pGraph;

HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,

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

IDCLSID_FilterGraph,由于Filter Graph Manager是动态链接库提供(dll),所以使用CLSCTX_INPROC_SERVER

 

CoCreateInstance 将返回IgraphBuilder接口,在该例子中还需要两个接口:

l         IMediaControl 用于控制数据流。它提供停止和开始的操作方法。

l         IMediaEvent   可以获得Filter Graph Manager 事件。例如,可以获得播放完成事件。

 

这两个接口都由Filter Graph Manager提供,可以通过IgraphBuilder指针去获得它们:

 

IMediaControl *pControl;

 

IMediaEvent   *pEvent;

 

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

 

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

 

现在,你可以建立过滤器图表(Fileter Graph)。对于文件播放,这里只需要调用一个方法就可以了:

 

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

 

IGraphBuilder::RenderFile方法将建立一个过滤器图表,通过它来播放指定的文件。第一个参数指定要播放的文件名称,它是个宽字符字符串。第二个参数是系统保留,必须为NULL。如果指定文件不存在或文件格式未知,那么该方法调用将失败。

 

现在过滤器图表已经准备好了去播放文件,但是还必须调用IMediaControl::Run方法去播放。

 

hr = pControl->Run();

 

当过滤器图表开始运行,数据从通过过滤器播放出来。播放动作将在一个独立的线程中进行。调用IMediaEvent::WaitForCompletion 方法可以等待文件播放完成。

 

long evCode = 0;

 

pEvent->WaitForCompletion(INFINITE, &evCode);

 

这个方法将一直等待文件播放结束才返回。INFINITE就表示不能确定文件的播放时间长度。当应用程序完成播放后,应该释放掉接口指针和关闭COM库。

 

pControl->Release();

 

pEvent->Release();

 

pGraph->Release();

 

CoUninitialize();

 

 

3.2. 全部源码如下:

// ControlTest.cpp : 定义控制台应用程序的入口点。

//HelloWord的作用主要是提供一个控制台应用程序去播放一个音、视频文件。

 

#include "stdafx.h"

#include <dshow.h>

int _tmain(int argc, _TCHAR* argv[])

{

 

     IGraphBuilder *pGraph = NULL;

     IMediaControl *pControl = NULL;

     IMediaEvent   *pEvent = NULL;

     // 初始化COM 

     HRESULT hr = CoInitialize(NULL);

 

     if (FAILED(hr))

     {

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

         return 0;

 

     }

     // 建立过滤器图表管理器

     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 0;

     }

 

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

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

     // 建立过滤器图表

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

     if (SUCCEEDED(hr))

     {

         // 播放

         hr = pControl->Run();

         if (SUCCEEDED(hr))

         {

              // 等待播放结束

              long evCode;

              pEvent->WaitForCompletion(INFINITE, &evCode);

         }

     }

     pControl->Release();

     pEvent->Release();

     pGraph->Release();

     CoUninitialize();

     return 0;

}

你可能感兴趣的:(DirectShow入门-3应用程序编程HelloWorld源代码)