您的位置:首页 > 其它

directshow 学习心得一

2011-03-30 16:39 246 查看
   大家好!从今天起我将持续发表一些关于DIRECTSHOW的文章,目的是与大家一起学习如何使用DIRECTSHOW极其相关COM组件!当然如果能深入到FILETER的一些创建,我将会尽力而为,文章中的大部分内容来自微软的MSDN,如果E文好的朋友想学习DIRECTSHOW又苦于没有好的参考资料,MSDN将是一个不二的选择,里面涵盖DIRECTSHOW所有的技术文章和组件的使用方法!

 

  

  DirectShow是微软公司在ActiveMovie和Video for Windows的基础上推出的新一代基于COM(Component Object Model)的流媒体处理的开发包,与DirectX开发包一起发布。DirectShow使用一种叫Filter Graph的模型来管理整个数据流的处理过程,运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。这样使在多媒体数据库管理系统(MDBMS)中多媒体数据的存取变得更加方便。它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等,为多媒体流的捕捉和回放提供了强有力的支持。

 

    DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。

  DirectShow使用一种叫Filter Graph的模型来管理整个数据流的处理过程;参与数据处理的各个功能模块叫做Filter;各个Filter在Filter Graph中按一定的顺序连接成一条“流水线”协同工作。大家可以看到,按照功能来分,Filter大致分为三类:Source Filters、Transform Filters和Rendering Filters。Source Filters主要负责取得数据,数据源可以是文件、因特网、或者计算机里的采集卡、数字摄像机等,然后将数据往下传输;Transform Fitlers主要负责数据的格式转换、传输;Rendering Filtes主要负责数据的最终去向,我们可以将数据送给声卡、显卡进行多媒体的演示,也可以输出到文件进行存储。值得注意的是,三个部分并不是都只有一个Filter去完成功能。恰恰相反,每个部分往往是有几个Fitler协同工作的。比如,Transform Filters可能包含了一个Mpeg的解码Filter、以及视频色彩空间的转换Filter、音频采样频率转换Filter等等。除了系统提供的大量Filter外,我们可以定制自己的Filter,以完成我们需要的功能。

(以上部分引用百度百科旨在介绍DIRECTSHOW)


另附一张经典的DIRECTSHOW的工作流程图!

      DIRECTSHOW的最新版本为DIRECTSHOW 9.0,目前已经脱离DIRECTX SDK 成为WINDOWS SDK的一部分,也就是说在WINDOWS VISTA 以后的版本都集成DIRECTSHOW的头文件,库文件和一些工具函数的文件!DirectShow 9.0相对于以前的版本做了很多增强,主要体现在以下几方面:

 

       DirectX Video Acceleration (DXVA) 2.0  (DIRECTX视频加速器)

       The Enhanced Video Renderer (EVR)    (增强视频渲染器)

       支持最新的WINDOWS VISTA DISPLAY MODEL(WDDM) CAPTURE

        等等

      DIRECTSHOW 9.0支持的文件和压缩格式:

     

File types:

Windows Media® Audio (WMA)*

Windows Media® Video (WMV)*

Advanced Systems Format (ASF)*

Motion Picture Experts Group (MPEG)

Audio-Video Interleaved (AVI)

QuickTime (version 2 and lower)

WAV

AIFF

AU

SND

MIDI

Compression formats:

Windows Media Video*

ISO MPEG-4 video version 1.0*

Microsoft MPEG-4 version 3*

Sipro Labs ACELP*

Windows Media Audio*

MPEG Audio Layer-3 (MP3) (decompression only)

Digital Video (DV)

MPEG-1 (decompression only)

MJPEG

Cinepak

    

      下面我们通过MSDN的一个例子(渲染AVI视频)来学习如何简单的使用DIRECTSHOW!

       首先我们创建DIRECTSHOW的编译环境,这里我选择的工具是微软的VISUAL STUDIO  2008 这个小例子不用创建窗口模式的应用程序,只需命令行模式即可完成!

       我们需要的头文件 Dshow.h 这个头文件所有的DIRECTSHOW应用程序都需要!除此之外我们还需要两个库文件,一个是Strmiids.lib 这个库文件导出DIRECTSHOW组件中的类标识符和接口标识符(即CLSID和IID),另一个并不是必须的库,Quartz.lib提供了AMGetErrorText函数,从函数名可以看出这个库是得到错误提示的一些函数,当我们想得到一些错误信息的时候我们应该使用这个库!

        我把这个例子的流程给大家叙述一下:

        第一步,我们从存储设备中读取文件

        第二步,我们从视频捕捉设备中得到视频数据

        第三步,解码各种流格式,例如MPEG-1

        第四步,把数据传送的声卡和显卡进行处理!

        这里我们将碰到一个重要的概念 FILTERS (过滤器),它接收数据并产生输出,例如一个filter 解码MPEG-1视频,输入方是MPEG-1编码流,而输出则是一系列的未压缩的视频帧!

         在DIRECTSHOW中,应用程序通过连接链和过滤器一起执行任务,也就是说一个输出过滤器也将成为另一个输入过滤器,为了直观在给大家看一张过滤器的链接图:

        


 

         文件源过滤器从硬盘中读取AVI文件,通过AVI分离过滤器将文件分成两个流,压缩视频流和音频流,然后传输视频流给AVI解压缩组件,解压缩过滤器把AVI视频解码成帧格式,并提供给视频渲染器到屏幕,而将音频流传输给DIRECTSOUND设备进行声音播放!

 

         要想管理这些数据流我们需要创建一个Filter Graph Manager,来控制数据流的 “停止” “暂停”和”开始“等状态,你可以直接访问相关的COM接口,Filter Graph Manager通过事件消息的形式通知应用程序!总体上说,我们的应用程序必须完成以下三个任务:

         第一 我们创建一个Filter Graph Manager 的实例

         第二 我们通过刚才创建的Filter Graph Manager 创建一个图形过滤器(Filter graph)

         第三  应用程序用我们创建的Filter Graph Manager来管理流数据通过其它过滤器

     下面我们就来完成这个事例程序:

 

       
#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;
4000

}

// 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();
}


   这里我忽略了一些COM的基础用法,如果大家想学习COM的一些知识可以通过搜索引擎工具查找相关的资料,在以后的学习中我将深入DIRECTSHOW的一些常用组件给大家介绍如何学习,并介绍它们的作用!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息