Chinaunix首页 | 论坛 | 博客
  • 博客访问: 947337
  • 博文数量: 261
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 3420
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-24 12:10
个人简介

https://smart888.taobao.com/ 立观智能监控

文章分类

全部博文(261)

文章存档

2011年(1)

2010年(4)

2009年(256)

我的朋友

分类: WINDOWS

2009-10-16 15:44:25

可能到现在为止,还没有哪个玩过游戏的人没有接触过Microsoft的DirectX的。因为现今大多数的游戏都是用DirectX开发出来的。
相比之下,DirectShow只是DirectX的一个子集。DirectX中还包括DirectSound、Direct3D等集合。DirectShow主要用来处理一些与音视频有关的多媒体任务,比如音视频采集、回放等。过年回来后,在一个项目中要求在WIN32下采集视频信号,以前做过GDI的,不过效率低下,而且效果也很烂,所以决定加速,怎样加速,答案就在DirectShow。
1、DirectShow的结构
我们知道,Windows操作系统只用了CPU中的两个特权级(0和3)。0是内核模式,它可以直接访问硬件;3是用户模式,它不能直接访问硬件。DirectShow的基本工作单元是Filter(过滤器),过滤器的就像一个筛子,它一般有输入引脚(PIN)和输出引脚,数据从输入引脚流入而从输出端口流出。DirectShow中的过滤器一般分为下列3类:
       1) Source Filter (用于提供原始的多媒体数据,比如一个视频文件)
       2)Transform Filter(用于处理从Source Filter 传过来的多媒体数据,比如MPEG-4解码器)
       3)Rendering Filter(用于显示、回放和存储多媒体数据给用户,比如文件写入器)
要完成特定的多媒体功能,必须用相应的Filter组成特定的Filter Graph。多媒体数据在Graph中流动,到达Rendering Filter时回放给用户。
用户应用程序怎么样控制Filter Graph呢?他必须创建一个相应的Filter Graph Manager,应用程序向Manager发送相应的命令(Command),然后从Manager那接收相应的Event,最后做出相应的响应。
每个Filter都有操作硬件的能力,这就是为什么DirectShow能如此高效的使用多媒体了。
DirectShow的结构原理图如下:
2、使用DirectShow编写一个简单的应用程序
      使用DirectShow编写应用程序的一般步骤如下:
      1)根据系统完成的功能构建相应的Filter Graph。
      2)构建Graph中的每个Filter,并将它们连接起来。
      3)创建Filter Graph Manager,运用Application控制Manager,从而控制整个的流程。
       4)DirectShow是基于COM(组件对象模型)的,所以在编写Filter前必须初始化COM库。
      下面是一个完整的播放AVI文件的小程序,其中的注解说明了编程的步骤。
#include
#include     //DirectShow必须包含的头文件,LIB库为Strmiids.lib 和 Quartz.lib
int main()
{
 IGraphBuilder *pGraph = NULL;      //  用于创建Filter Graph的接口
 IMediaControl *pControl = NULL;    //  用于向Filter Graph Manager发送Command
 IMediaEvent   *pEvent = NULL;        //   用于接收Filter Graph Manager发出的Event
 // Initialize the COM library.
 HRESULT hr = CoInitialize(NULL);   //初始化COM Library
 if( FAILED(hr) )
 {
  fprintf(stderr,"could not init the COM library!");
  return 0;
 }
//创建Filter Graph Manager
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void **)&pGraph);     
 if( FAILED(hr) )
 {
  fprintf(stderr,"could not create Filter Graph Manager!");
  return 0;
 }
 //查询并获得接口指针
 hr = pGraph->QueryInterface(IID_IMediaControl,(void **)&pControl);
 hr = pGraph->QueryInterface(IID_IMediaEvent,(void **)&pEvent);
 // RenderFile库函数是少数几个能够自动创建Graph的成页,所以这里省去了创建Graph这一步
 hr = pGraph->RenderFile(L"e:\\football.avi",NULL);
 if( SUCCEEDED(hr) )
 {
  hr = pControl->Run();
  if( SUCCEEDED(hr) )
  {
   // 等待视频结束
   long evCode;
   pEvent->WaitForCompletion(INFINITE, &evCode);
   // 无限等待
  }
 
 }
 pControl->Release();
 pEvent->Release();
 pGraph->Release();
//释放接口
 CoUninitialize();   //御载COM 库

 return 0;
}
 
 
阅读(803) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~