当前位置: 首页 > article >正文

DirectShow 概念介绍

设置DirectShow开发的编译环境

头文件

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

库文件

   DirectShow使用以下库文件:

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

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

   有了以上这些头文件和库文件,你已经可以编写DirectShow应用了,但是微软建议使用DirectShow基类库来编写filter,这样可以大大减少程序编写的工作量。要使用DirectShow基类库,需要先编译它,基类库位于SDK的Samples/Multimedia/DirectShow/BaseClasses文件夹下,包含两个版本的库:发布版(retail version)Strmbase.lib和调试版(debug version)Strmbasd.lib。

 

DirectShow应用程序编程简介

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

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

   在DirectShow中,应用程序要实现功能就必须将这些filter链接在一起,因而一个filter的输出就变成了另一个filter的输入。这一系列穿在一起的filter称为filter graph。

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

    应用程序没有必要对这些数据流进行管理,而是通过一个叫Filter Graph Manager这个上层组件来控制这些filter。应用程序调用上层API如"Run"(通过graph移动数据)或"Stop"(停止移动数据)。如果你需要对数据流作更多的操作,你可以通过COM接口直接进入filter。Filter 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。

 

播放一个文件

   第一步,首先需要调用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_FilterGraph。Filter Graph Manager由进程内DLL(in-process DLL)提供,因此参数3,dwClsContext的值为CLSCTX_INPROC_SERVER。由于DirectShow运行自由线程模式(free-threading model),所以你同样可以使用COINT_MULTITHREADED参数来调用CoInitializeEx。

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

  IMediaControl控制数据流,它包含开启和停止graph的方法;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);

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

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

   IGraphBuilder::RenderFile方法创建了一个能够播放指定文件的file 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();
}

参考:

https://www.yuque.com/docs/share/f20ed91e-308c-40b9-8d1d-cbafa3f8dfa8

http://www.lryc.cn/news/2419568.html

相关文章:

  • bind9新手入门
  • 人本主义流派,罗杰斯人本主义理论,马斯洛的人本主义人格理论
  • CGO中使用ReadProcessMemory读取其他进程内存
  • linux构建widi显示服务,如此简单 Intel WiDi无线高清设置教程
  • Lua userdata详解
  • 典型相关分析 CCA
  • Makefile中常用到的函数总结
  • 2024年最新网络安全人士必备的13个漏洞库_通用漏洞数据库,2024年最新网络安全开发基础机构
  • 在浏览器中输入www.baidu.com后执行的全部过程
  • 博客管理系统设计与实现
  • 第二幕:C语言基础篇之基本数据类型(基本整型、短整型、长整型、双长整型、字符型、单精度浮点型、双精度浮点型、复数浮点型、无符号类型、布尔型、格式符(占位符))
  • 探索Python实用工具库:Boltons
  • VLAN的配置
  • selenium开发环境部署Maven官方依赖porm文件分享
  • 欧美风格网站设计的网页字体风格选择
  • 史上最污技术解读...啊哈~“好变态”~~~
  • AVPlayer 播放在线视频和本地文件(数据库)设置
  • 【RDMA】9. RDMA之Queue Pair
  • C基础-12
  • 书单(含资源链接,快撸!)
  • 网关配置入门:打造连接网络的桥梁
  • Python3.7 运行的时候提示缺少 zlib1.dll 最简单解决办法
  • HDU杭电OJ基础100题2000-2099(C语言版)
  • Win10下Windows Mobile设备中心无法连接斑马PDA 、无法拷贝文件———— Windows 设备中心64位安装包
  • 网站导航颜色停留_良好的网站导航设计有助于提升网站排名
  • 小向まな美
  • YOLO V7网络实现细节(2)—网络整体架构总结
  • PHP函数strip_tags的一个bug浅析
  • 图片外链网站需要什么样服务器,10个支持外链图片服务的免费图床网站
  • 启动应用程序出现opengl32.dll文件丢失问题解决