您的位置:首页 > 其它

基于DIRECTSHOW平台的视频程序开发

2010-04-29 08:55 591 查看
1)directshow初识(2009.12.05)

创建DirectShow应用程序步骤:

第一步,首先,需要调用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),所以你同样可以使用COINIT_MULTITHREADED参数来调用CoInitializeEx

PS:HRESULT 是一种简单的数据类型,通常被属性和 ATL 用作返回值。

下表说明各种不同的值。头文件 winerror.h 中包含更多的值。

  名称 说明 值

  S_OK 操作成功 0x00000000

  E_UNEXPECTED 意外的失败 0x8000FFFF

  E_NOTIMPL 未实现 0x80004001

  E_OUTOFMEMORY 未能分配所需的内存 0x8007000E

  E_INVALIDARG 一个或多个参数无效 0x80070057

  E_NOINTERFACE 不支持此接口 0x80004002

  E_POINTER 无效指针 0x80004003

  E_HANDLE 无效句柄 0x80070006

  E_ABORT 操作已中止 0x80004004

  E_FAIL 未指定的失败 0x80004005

  E_ACCESSDENIED 一般的访问被拒绝错误 0x80070005

  不能简单地把返回值与 S_OK 和 S_FALSE 比较,而要用 SUCCEEDED 和 FAILED 宏进行判断。

第二步,创建filter graph

调用CoCreateInstance得到的IGraphBuilder接口包含了大部分创建filter graph的方法。在这个例子中还需要另外两个接口:IMediaControl和IMediaEvent。IMediaControl控制数据流,它包含开启和停止graph的方法;IMediaEvent包含从Filter Graph Manager获取事件的方法,在这个例子中,这个接口用来得到回放结束事件。所有这些接口由Filter Graph Manager提供,使用得到的IGraphBuiler接口指针来查询得到。

IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

第三步,创建filter graph

对于文件回放只需要一个简单的调用:

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

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

创建简单的directshow播放程序过程的完整代码如下所示:

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

PS:

1.这里所使用的fiter graph manag构建graph filter采用igraphbuilder::renderfile方法构建一个完成的文件回放graph

2.该程序只支持.avi格式视频播放,只有播放直至结束的回放功能。



二 VS2005 C++ 项目添加“依赖”、“库目录”和“包含目录”2009-12-08
1. 添加编译所需要(依赖)的 lib 文件

“项目->属性->配置属性->连接器->输入->附加依赖项”里填写“winsock.lib”,多个 lib 以空格隔开。
(等同于“#pragma comment(lib, "winsock.lib") ”语句)

2. 添加库(Libs)文件目录

方法 1“项目->属性->配置属性->连接器->常规->附加库目录”
方法 2:[菜单]“工具->选项->项目和解决方案->C++ 目录”,选择对应平台,然后添加所需“库文件”目录

3. 添加包含(include)文件目录

方法 1:[解决方案资源管理器]“项目->属性->配置属性->C/C++->常规->附加包含目录”
方法 2:[菜单]“工具->选项->项目和解决方案->C++ 目录”,选择对应平台,然后添加所需“包括文件”目录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: