解析DirectShow SDK提供的播放器例子源码PlayWnd

来源:互联网 发布:软件工程学不学高数 编辑:程序博客网 时间:2024/05/16 23:59

本例在DirectX 9.0b版本下,位于DXSDK90b\Samples\C++\DirectShow\Players\PlayWnd。网上也许也能下载到。

 

此播放器实现的功能:

打开文件、推出

播放、暂停、停止

窗口1倍显示、0.5倍显示、2倍显示、全屏、画面跟随窗口变形

窗口标题栏显示所播放文件的名称和播放状态

快放、慢放

按帧播放

静音等

 

源码对应于不同的功能设置了各个全局变量,如下:

HWND      ghApp=0;

HMENU     ghMenu=0;

HINSTANCE ghInst=0;

TCHAR     g_szFileName[MAX_PATH]={0};

BOOL      g_bAudioOnly=FALSE, g_bFullscreen=FALSE;

LONG      g_lVolume=VOLUME_FULL;

DWORD     g_dwGraphRegister=0;

PLAYSTATE g_psCurrent=Stopped;

double    g_PlaybackRate=1.0;

 

要实现一个播放器,有如下步骤:

1.       要用CoInitializeEx初始化,并对各个变量初始化;

2.       通过API函数CoCreateInstance()创建一个Filter Graph Manager 实例;

3.       通过调用QueryInterface ( )函数来获取组件的指针;

4.       对Filter Graph进行控制和对事件作出响应,涉及到以下接口:

IGraphBuilder 构造Filter Graph Manager

IMediaControl 控制流媒体,如启动、停止、暂停等

IMediaEventEx 播放事件接口,创建事件的标志信息并传送给应用程序

IVideoWindow显示窗口控制接口

IBasicAudio声音控制接口

IBasicVideo图像控制接口(波特率,宽度,长度等信息)

IMediaSeeking 播放的位置和播放速度控制接口

IMediaPosition 播放的位置和速度控制接口(控制播放位置只能为设置时间控制方式)

IVideoFrameStep控制单帧播放的接口;

5.       实现主窗口显示功能,消息处理完后,用CoUninitialize反初始化。

 

我们来看一下这个例子中的一些主要函数,按照播放流程一步步往下分析。

 

WinMain函数:实现COM的初始化和反初始化,即上述步骤的第一步和第五步。注册窗口类并调用WndMainProc

 

OpenClip函数:这是程序调试成功后立刻实现的函数,它也在ID_FILE_OPENCLIP产生后关闭当前播放的文件回到初始状态(详见WndMainProc)再被调用。当未指定播放文件时,调用InitPlayerWindow设置窗口。指定播放文件后,GetClipFileName取得文件名,获取相应字符串,IsWindowsMediaFile判断是否支持媒体格式,都成功后调用PlayMovieInWindow进行下一步设置,失败则CloseClip

 

WndMainProc函数:将消息通知给程序,调用各类函数实现菜单栏及快捷键的功能,如MoveVideoWindow改变窗口尺寸、StepOneFrameStepFrames按帧播放、ModifyRateSetRate设置播放速度、ToggleMute静音、ToggleFullScreen全屏、CloseClip停止播放、PauseClip暂停播放、InitVideoWindowCheckSizeMenu实现窗口缩放等;

 

PlayMovieInWindow函数:首先编码转换,清理对话残余,之后调用CoCreateInstance创建GraphBuilder,用QueryInterface查询各类接口。用CheckVisibility判断音频和视频,如果是音频,则设置相应的父类窗口和窗口格式,如果是视频,调用InitPlayerWindow取得窗口默认值,并调用EnablePlaybackMenu实现工具栏各个功能。继续初始化,要调用CheckSizeMenu等窗口函数采用默认值,UpdateMainTitle显示最初的标题。如果Graph还未注册,则需要调用AddGraphToRot将Graph添加到注册组件中。准备好以上一切后,才运行该媒体文件;

 

CloseClip函数:停止媒体文件的播放后,运行为停止状态,窗口显示为音频窗口,关闭全屏,调用CloseInterfaces函数(其中调用了RemoveGraphFromRot解除Graph的注册,并释放各个接口)关闭各个接口,文件名清零,运行回到初始状态。调用UpdateMainTitle显示最初标题,InitPlayerWindow显示初始化窗口。

 

以上就是播放器实现的主要函数,对应这源码看就能明白这个播放器的大致播放流程。黑体标出的都是源码自己构建的函数,这一例子中的除个别函数外都已在上面表述过了,各个小功能函数的实现没有做多叙述,看一看就能明白。

原创粉丝点击