秦晓梅 张艺博
摘要:介绍了DirectShow技术的基本概念和Filter Graph及其组成,提出了一个基于DirectShow技术的媒体播放器的设计,并构建了过滤器图表,同时文中详细叙述了软件开发的实现框架。本文以VC + + 6.0和DirectShow技术开发媒体播放器,并给出了关键代码的示例。
关键词:DirecShow;Filter;Filter Graph;媒体播放器
中图分类号:TP37文献标识码:A文章编号:1009-3044(2008)18-2pppp-0c
Media Player Based on DirectShow Technology
QIN Xiao-mei, ZHANG Yi-bo
(Henan Economy and Trade Vocational College,Zhenzhou 450053,China)
Abstract: This thesis mainly introduces the basic concept of DirectShow technology, and Filter Graph with its composition, the thesis suggests a media player based on DirectShow technology one, and designs filter graph. The realization frame of software development is discussed at the same time detailedly in the main body of this thesis. VC + + 6.0 and DirectShow technology is used in the course of programming. the key code of the program is also available.
Key words:DirecShow;Filter;Filter Graph;Media Player
1 引言
DirectX软件开发包是微软公司提供的一套在Windows平台上开发高性能图形、声音、输入输出和网络游戏的编程接口,DirectShow是DirectX家族的成员之一,DirectShow可以实现高质量的音视频采集、编辑、编码、解码和播放。DirectShow是基于COM 的,它为程序人员从Windows平台上音视频信息的网络传输、硬件差异、同步性中解脱出来,软件开发者只要按照DirectShow COM接口来编写程序,不用关心硬件设备、不同媒体格式的差别、编解码的实现细节等,极大地降低了多媒体应用程序开发的复杂度,目前DirectShow在多媒体应用中发挥着重要作用。
2 DirectShow概述
DirectShow是一个开放的应用框架,是一套基于COM的编程接口。图 1是DirectShow的系统功能。图中最大的一块就是DireceShow系统,它的基本工作原理就是流水线:将Filter串联在一起,交由Filter Graph Manager统一管理。系统的输入为文件、硬件板块、网络数据等,系统的输出为声卡、显卡、本地文件系统、网络。
图1 DiretShow系统
3 Filter Graph及其组成
3.1 DirectShow的Filter
DirectShow是基于模块化,每个功能模块都采取COM组件方式,称为Filter。DirectShow提供了一系列标准的模块用于应用开发,开发者也可以开发自己的Filter来扩展DirectShow的应用。下面我们用一个例子来说明如何采取Filter来播放一个AVI的视频文件。从文件读取数据,形成字节流(这个工作由源Filter完成),检查AVI数据流的头格式,然后通过AVI分割Filter将音视频流分开。根据压缩格式的不同,选取不同的Decoder Filters解码视频流,重画视频图像。通过Renderer Filter将音频流送到声卡进行播放,一般采用缺省的 DirectSound Device Filter。流程见下图 2。
图2 AVI文件播放流程
从图 2看,每一个Filter 都和其他的一个或者两个Filter 相连接,连接点也是COM对象,称为Pin。Filter通过Pin将数据从一个Filter传递到另一个Filter,从而可以使数据在Filter的链表中流动。
3.2 Filter Graph Manager
Filter Graph Manager是一个COM对象,用来控制Filter Graph中的所有的Filter,主要有以下的功能:
(1)用来协调Filter之间的状态改变,从而使Graph中的所有的Filter的状态的改变应该一致。Graph中的Filter的状态改变应该一致,应用程序并不将状态改变的命令直接发给Filter,而是将相应的状态改变的命令发送给Filter Graph Manager,由manager将命令分发给Graph中每一个Filter。
(2)建立一个参考时钟。Graph中的Filter都采用同一个时钟,称为参考时钟(reference clock),参考时钟可以确保所有的数据流同步。Filter Graph Manager应该选择一个参考时钟,可以选择声卡上的时钟,也可以选择系统时钟。
(3)将Filter的消息返回给应用程序。Graph管理器采用事件机制将Graph中发生的事件通知给应用程序,这个机制类似于windows消息循环机制。
(4)提供方法建立Filter Graph。Graph管理器给应用程序提供了将Filter添加进Graph的方法,连接Filter的方法,断开Filter连接的方法。
3.3 媒体类型
DirectShow需要一种方式来描述Filter Graph每一个点的数据格式,例如,我们还以播放AVI文件为例,数据以RIFF块的形式进入Graph中,然后被分割成视频和音频流,视频流有一系列的压缩的视频帧组成,解压后视频流由一系列的无压缩的位图组成,音频流也要走同样的步骤。
3.4 硬件在Graph中的作用
为了提高系统的稳定性,Windows操作系统对硬件操作进行了隔离。DirectShow包装Filter,这种Filter能工作在用户模式下,外观、控制方法跟普通Filter 一样,而包装Filter内部完成与硬件驱动程序的交互。使得编写DirectShow应用程序从支持硬件而做出的特殊处理中解脱出来。
4 基于DirectShow技术的媒体播放器
4.1 配置开发环境
本媒体播放器(MyPlayer)使用VC++6.0开发,采用DirectX SDK9.0编程接口。DirectX SDK安装在C: DX90SDK目录下。软件开发之前必须先完成以下准备工作。
(1)编译基类源代码,用VC打开C:DX90SDKSamplesC++DirectShow
BaseClassesaseclass.dsw,编译生成两个静态库文件:Debug版本生成strmbasd.lib,Release版本生成strmbase.lib。
(2)配置VC的编译环境:Include目录和Lib目录分别添加以下内容:
C:DX90SDKINCLUDE
C:DX90SDKSAMPLESC++DIRECTSHOWBASECLASSES
C:DX90SDKSAMPLESC++COMMON
C:DX90SDKLIB
C:DX90SDKSAMPLESC++DIRECTSHOWBASECLASSESDebug
C:DX90SDKSAMPLESC++DIRECTSHOWBASECLASSESRelease
(3)配置DirectShow应用程序开发项目需要连接的库文件。执行VC的菜单命令Project|Setttings,在弹出的对话框中单击Link标签,在Object/library modules文本框中,Debug版本输入strmbasd.lib Winmm.lib,Release版本输入strmbase.lib Winmm.lib。
4.2 功能设计
主要功能包括:播放、暂停、停止、快放、慢放、全屏播放。MyPlayer是在C:DX90SDKSamplesC++DirectShowPlayerPlayWnd基础上修改完成的。程序界面如图 3。
图3 程序界面
MyPlayer是一个标准的Win32应用程序。程序入口函数为WinMain,总的执行流程如下:CoInitializeEx|创建主窗口|发送消息弹出一个对话框以选择要播放的媒体文件|主线程的消息循环|CoUninitialize。主线程的消息循环中完成:播放、暂停、停止、全屏、快放、慢放等。
(1)播放功能实现方法为:选择媒体文件、初始化程序窗口、初始化视频播放窗口、调用HRESULT PlayMovieInWindow(LPTSTR szFile)函数完成播放。PlayMovieInWindow函数主要实现代码和功能如下:
1)创建一个Filter Graph组件CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGB);
2)智能连接构建Filter Graph组件pGB->RenderFile(wFile, NULL);
3)获取Filter Graph的各个控制接口
//得到播放器控制接口、定位接口等
pGB->QueryInterface(IID_IMediaControl, (void **)&pMC);
pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME);
pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS);
pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP);
// 得到视频相关接口
pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW);
pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV);
// 得到音频相关接口
pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA);
//完成其他窗口的初始化
UpdateWindow(ghApp);
4)播放Filter Graph
pMC->Run();
5)更新当前状态
g_psCurrent=Running;
SetFocus(ghApp);
(2)暂停和停止功能实现为pMC->Pause();pMC->Stop();
(3)全屏功能实现为pVW->put_FullScreenMode(OATRUE);
(4)快放和慢放pMP->put_Rate(dNewRate);
5 结束语
本文简要介绍了DirectShow技术的基本概念和基于DirectShow技术的媒体播放器,并用VC++6.0实现。DirectShow提供的良好开发环境,使得媒体播放器开发实现比较方便,并且具有广泛的通用性和可扩展性。
参考文献:
[1]智慧的鱼.DirectShow SDK学习笔记[EB/OL].http://www.chinavideo.org.
[2]陆其明.DirectShow发指南[M].北京:清华大学出版社,2004.
[3]陆其明.DirectShow实务精选[M].北京:科海电子出版社,2004.
收稿日期:2008-04-02
作者简介:秦晓梅(1980-),女,河南郑州人,助教,华中科技大学在读硕士,研究方向:数据库技术、多媒体技术、软件工程;张艺博(1973-),男,河南三门峡人,讲师,华中科技大学硕士,研究方向:计算机信息安全,软件工程和程序设计方向。