如何发挥文件
本文的目的是给你的DirectShow编程的味道。 它给出了一个简单的控制台应用程序,播放音频或视频文件。 该方案是只有几行,但它演示了一些的DirectShow编程的力量。
由于DirectShow应用程序编程的文章介绍介绍,DirectShow应用程序总是执行相同的基本步骤:
- 创建一个过滤器图表管理器的实例。
- 使用Filter图表管理器建立一个过滤器图。
- 运行图,导致数据移动通过过滤器。
开始调用 CoInitialize初始化COM库:
HRESULT,HR = CoInitialize的(NULL);(FAILED(HR)){/ /添加错误处理代码在这里。 (为清楚起见,省略。)}
为了简单起见,这个例子忽略返回值,但您应经常检查任何方法调用的HRESULT值。
接下来,调用CoCreateInstance创建的筛选器图形管理:
IGraphBuilder * pGraph; HRESULT,HR = CoCreateInstance的(CLSID_FilterGraph,NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(无效**)&pGraph);
如上所示,类标识符(CLSID)CLSID_FilterGraph。 筛选器图形管理器是由一个进程DLL提供的,所以执行上下文是CLSCTX_INPROC_SERVER。 DirectShow支持自由线程模型,所以你也可以调用CoInitializeEx的 COINIT_MULTITHREADED标志。
调用 CoCreateInstance返回IGraphBuilder接口,主要包含用于构建筛选器图形的方法。 其它两种接口都需要在这个例子:
- IMediaControl控制流。 它包含用于停止和启动图形的方法。
- IMediaEvent从过滤器图表管理器的事件的方法。 在这个例子中,接口是用来等待播放完成。
这两个接口是由Filter图表管理器暴露。 使用返回IGraphBuilder指针查询:
IMediaControl * pControl; IMediaEvent * pEvent; HR = pGraph -> QueryInterface的(IID_IMediaControl,(无效**)&pControl); HR = pGraph>的QueryInterface(IID_IMediaEvent,(无效**)&pEvent);
现在,您可以建立筛选器图形。 文件的播放,这是通过一个方法调用:
HR = pGraph>的RenderFile(L“C:\ \ Example.avi”,NULL);
IGraphBuilder::的RenderFile方法建立一个过滤器,可以播放指定的文件的图。 第一个参数是文件名,作为一个宽字符(2字节)的字符串表示。 第二个参数是保留的,必须等于NULL。
这种方法可能会失败,如果指定的文件不存在,或无法识别的文件格式。 然而,假设的方法成功,筛选器图形现在是准备用于播放。 要运行图,调用IMediaControl::运行方法:
HR = pControl -> Run()方法;
当过滤器的图形运行时,通过过滤器的数据移动和呈现视频和音频。 发生在一个单独的线程播放。 您可以等待播放完成调用IMediaEvent:WaitForCompletion方法:
长evCode = 0; pEvent> WaitForCompletion(无限的,evCode);
此方法一直阻塞,直到该文件播放,或直到指定的时间间隔已经过去。 价值无限意味着应用程序无限期地阻塞,直到该文件是播放。 对于事件处理的一个更现实的例子, 请参见响应事件。
当应用程序完成后,释放接口指针并关闭COM库:
pControl - >(); pEvent - >(); pGraph - >(); CoUninitialize();
示例代码
下面是本文中所描述的例子的完整代码:
#包括<dshow.h> 无效的主要(无效) { IGraphBuilder * pGraph = NULL; IMediaControl * pControl = NULL; IMediaEvent * pEvent = NULL; / /初始化COM库。 HRESULT,HR = CoInitialize的(空); (FAILED(HR)) { printf的(“错误 - 无法初始化COM库”); 回报; } / /创建的筛选器图形管理器接口和查询。 HR = CoCreateInstance的(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER IID_IGraphBuilder,(无效**)&pGraph); (FAILED(HR)) { printf的(“错误 - 无法创建筛选器图形管理器”。); 回报; } HR = pGraph -> QueryInterface的(IID_IMediaControl,(无效**)&pControl); HR = pGraph>的QueryInterface(IID_IMediaEvent,(无效**)&pEvent); / /生成图形。 要点:这个字符串更改您的系统上的文件。 HR = pGraph>的RenderFile(L“C:\ \ Example.avi”,NULL); (SUCCEEDED(HR)) { / /运行图。 HR = pControl -> Run()方法; (SUCCEEDED(HR)) { / /等待完成。 长evCode; pEvent> WaitForCompletion(无限的,evCode); / /注意:不要使用无限在实际应用中,因为它 / /可以无限期地阻塞。 } } pControl - >(); pEvent - >(); pGraph - >(); CoUninitialize(); }
另请参见