406工作室

对于数字音频和视频的DirectShow编程(三)

人工建立一个Filter Graph

自己手动产生一个Filter Graph,首先要产生一个Filter Graph Manager的对象,然后产生两个基本点Filters: a source filter(指向媒体文件),a audio renderer filter.之后我们要使用智能化connect来连接source filter里的输出接口和audio renderer的输入接口.产生一个必要的中间的transform filter用来提供在sourcerenderer之间的路径.一旦这个路径被建立了,这个Filter Graph就开始执行了,它会播放媒体文件直到结束,然后停止.

 

以下的程序是在DSBuild.cpp,它有四个方法.其中三个都和DSRender.cpp里的犯法是一样.这里额外的方法就是GetPin,它会在“Locating Pins and GetPins“里被详细的检查.

// DSBuild implements a very simple program to render audio files

// or the audio portion of movies.

//

int main(int argc, char* argv[])

{

IGraphBuilder *pGraph = NULL;

IMediaControl *pControl = NULL;

IMediaEvent *pEvent = NULL;

IBaseFilter *pInputFileFilter = NULL;

IBaseFilter *pDSoundRenderer = NULL;

IPin *pFileOut = NULL, *pWAVIn = NULL;

// Get the name of an audio or movie file to play.

if (!GetMediaFileName()) {

return(0);

}

// Initialize the COM library.

HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

if (FAILED(hr))

{

printf("ERROR - Could not initialize COM library");

return hr;

}

// Create the Filter Graph Manager object and retrieve its

// IGraphBuilder interface.

hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,

IID_IGraphBuilder, (void **)&pGraph);

if (FAILED(hr))

{

printf("ERROR - Could not create the Filter Graph Manager.");

CoUninitialize();

return hr;

}

// Now get the media control interface...

hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);

if (FAILED(hr)) {

pGraph->Release();

CoUninitialize();

return hr;

}

// And the media event interface.

hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

if (FAILED(hr)) {

pControl->Release();

pGraph->Release();

CoUninitialize();

return hr;

}

// Build the graph.

// Step one is to invoke AddSourceFilter

// with the file name we picked out earlier.

Seite 11 von 15 Chapter 3: Programming DirectShow Applications

30.10.2005 file://C:\Dokumente%20und%20Einstellungen\awolf2\Lokale%20Einstellungen\Tem...

// Should be an audio file (or a movie file with an audio track).

// AddSourceFilter instantiates the source filter,

// adds it to the graph, and returns a pointer to the filter's

// IBaseFilter interface.

#ifndef UNICODE

WCHAR wFileName[MAX_PATH];

MultiByteToWideChar(CP_ACP, 0, g_PathFileName, -1, wFileName, MAX_PATH);

hr = pGraph->AddSourceFilter(wFileName, wFileName, &pInputFileFilter);

#else

hr = pGraph->AddSourceFilter(wFileName, wFileName, &pInputFileFilter);

#endif

if (SUCCEEDED(hr)) {

// Now create an instance of the audio renderer

// and obtain a pointer to its IBaseFilter interface.

hr = CoCreateInstance(CLSID_DSoundRender, NULL,

CLSCTX_INPROC_SERVER, IID_IBaseFilter,

(void **)&pDSoundRenderer);

if (SUCCEEDED(hr)) {

// And add the filter to the filter graph

// using the member function AddFilter.

hr = pGraph->AddFilter(pDSoundRenderer, L"Audio Renderer");

if (SUCCEEDED(hr)) {

// Now we need to connect the output pin of the source

// to the input pin of the renderer.

// Obtain the output pin of the source filter.

// The local function GetPin does this.

pFileOut = GetPin(pInputFileFilter, PINDIR_OUTPUT);

if (pFileOut != NULL) { // Is the pin good?

// Obtain the input pin of the WAV renderer.

pWAVIn = GetPin(pDSoundRenderer, PINDIR_INPUT);

if (pWAVIn != NULL) { // Is the pin good?

// Connect the pins together:

// We use the Filter Graph Manager's

// member function Connect,

// which uses Intelligent Connect.

// If this fails, DirectShow couldn't

// render the media file.

hr = pGraph->Connect(pFileOut, pWAVIn);

}

}

}

}

}

if (SUCCEEDED(hr))

{

// Run the graph.

hr = pControl->Run();

if (SUCCEEDED(hr))

{

// Wait for completion.

long evCode;

pEvent->WaitForCompletion(INFINITE, &evCode);

Seite 12 von 15 Chapter 3: Programming DirectShow Applications

30.10.2005 file://C:\Dokumente%20und%20Einstellungen\awolf2\Lokale%20Einstellungen\Tem...

// Note: Do not use INFINITE in a real application

// because it can block indefinitely.

}

hr = pControl->Stop();

}

// Before we finish, save the filter graph to a file.

SaveGraphFile(pGraph, L"C:\\MyGraph.GRF");

// Now release everything we instantiated--

// that is, if it got instantiated.

if(pFileOut) { // If it exists, non-NULL

pFileOut->Release(); // Then release it

}

if (pWAVIn) {

pWAVIn->Release();

}

if (pInputFileFilter) {

pInputFileFilter->Release();

}

if (pDSoundRenderer) {

pDSoundRenderer->Release();

}

pControl->Release();

pEvent->Release();

pGraph->Release();

CoUninitialize();

return 0;

}

一开始所有做的一切都是为了建立filter graph.在这点上,我们需要使用一个IGraphBuilder的新方法AddSourceFilter,这个方法是把文件名作为一个参数并且返回一个指向IbaseFilter的指针.

紧接着我们使用CoCreateInstance来建立audio renderer filter,其中我们使用Class ID CLSID_DsoundRender作为参数并且返回IBaseFilter接口.一旦filter被成功地建立起来之后,我们就使用IGraphBuilder::AddFilter将它添加到filter graph里去.

AddFilter里有两个参数.第一个是要被添加的指向IbaseFilter的指针.

现在我们在filter graph里有两个filters:一个只指向文件的source filter,一个是输出文件的audio output filter.它们需要通过transform filter被连接到一起.我们使用智能化的connect来达成这一目的.

首先我们需要获得Ipin接口,对于source filter的输出和render的输入都需要.我们使用GetPin方法来获得我们想要连接的Pins上的接口.一旦我们得到了,我们就可以执行IGraphBuilder::Connect. Connect里面的两个参数是你想连接的两个Pins.如果成功的话,这两个Pins就会通过一系列的中间filters被连接起来.如果失败的话,就不能够建立起sourcerenderer之间的路径.有可能是因为source file中的媒体类型不被DirectShow所支持或者是因为文件里本身不包括任何audio.

DSRender一样.这个应用程序也使用IMediaControl::Run来开始filter graph的执行...................

posted on 2007-12-14 08:21 xulichen 阅读(1694) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

公告

welcome to 406studio.

常用链接

留言簿(2)

随笔档案(2)

文章档案(4)

资料

最新随笔

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜