网页功能: 加入收藏 设为首页 网站搜索  
DirectShow PIN 連接教學
发表日期:2007-01-18作者:[转贴] 出处:  

一個寫作機會,順便看了一下 DirectShow 發現它.. 太強大了...
但覺得還是自己用 PIN 連接較好用,雖有點不方便,但 DEBUG 容易。
CODE 很簡單。我用最簡單的幾個 Filter 寫了一個 AVI PLAYER..
利用 DirectX 所提供的 GraphEdit 來做出自己要的 Filter Model 在依照其來建立連接。

PS: 弟沒有使用任何的 Avi Decoder 所以只能解基本的 AVI 格式及音樂。

1. pGraphBuilder->Render(OutPin); & RenderFile() 都會自動建立起一些基本的 Filter。
2. 善用 GraphEdit 中的 "Connect Remote Graph Filter" 功能,會得到很多答案的。






void Test(char *File)
{
    WCHAR *wfile;
   
int length;
   
IGraphBuilder *pGraphBuilder;
   
IEnumFilters *pEnum;
   
IBaseFilter *pSource;
   
IBaseFilter *pAviSplitter;
   
IBaseFilter *pVideoRenderer;
   
IBaseFilter *pSound;
   
IMediaControl *pMediaControl;
   
IMediaEvent *pMediaEvent;
   
IVideoWindow *pVideoWindow;
   
IMediaSeeking *pSeek;
   
IMediaFilter *pMediaFilter;
   
IEnumPins *EnumPins;
   
IPin *OutPin;
   
IPin *InPin;
   
ULONG fetched;
   
PIN_INFO pinfo;
   
HRESULT hr;
   
FILTER_INFO FilterInfo;
   
char szName[256];

   
CoInitialize( NULL );

    // create graph
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraphBuilder);

    length = strlen(File)+1;
    wfile = new WCHAR[length];
    MultiByteToWideChar(CP_ACP, 0, File, -1, wfile, length);

    // find the SourceFilter from RenderFile created
    /*pGraphBuilder->EnumFilters(&pEnum);                            (编辑者:此句可能有误)
    while(pEnum->Next(1, &pSource, &fetched) == S_OK)
    {
        pSource->QueryFilterInfo(&FilterInfo);
        WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName, -1, szName, 256, 0, 0);
        FilterInfo.pGraph->Release();
        if(strstr(szName, "avi") != NULL) break;
        pSource->Release();
    }
    pEnum->Release();

    // create filter
    CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSource);
    CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pAviSplitter);
    CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVideoRenderer);

    IFileSourceFilter* FileSource=NULL;
    pSource->QueryInterface(IID_IFileSourceFilter, (void**)&FileSource);
    FileSource->Load(wfile, NULL);
    FileSource->Release();

    // Add filter to graph
    pGraphBuilder->AddFilter(pSource, L"MM_FileSource");
    pGraphBuilder->AddFilter(pAviSplitter, L"MM_AviSplitter");
    pGraphBuilder->AddFilter(pVideoRenderer, L"MM_VideoRenderer");

   
// find source output
    pSource->EnumPins(&EnumPins);
    EnumPins->Reset();
    EnumPins->Next(1, &OutPin, &fetched);
    EnumPins->Release();

   
// set the GraphBuilder output pin
   
//pGraphBuilder->Render(OutPin);

    // find the Avisplitter input
    pAviSplitter->EnumPins(&EnumPins);
    EnumPins->Reset();
    EnumPins->Next(1, &InPin, &fetched);
    InPin->QueryPinInfo(&pinfo);
    pinfo.pFilter->Release();
    while(pinfo.dir != PINDIR_INPUT)
    {
        InPin->Release();
        EnumPins->Next(1, &InPin, &fetched);
        InPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();
    }
    EnumPins->Release();

    // connect input & output pin
    pGraphBuilder->Connect(OutPin, InPin);
    InPin->Release();
    OutPin->Release();

    // find the Avisplitter output pin
    pAviSplitter->EnumPins(&EnumPins);
    EnumPins->Reset();
    EnumPins->Next(1, &OutPin, &fetched);
    OutPin->QueryPinInfo(&pinfo);
    pinfo.pFilter->Release();
    while(pinfo.dir != PINDIR_OUTPUT)
    {
        OutPin->Release();
        EnumPins->Next(1, &OutPin, &fetched);
        OutPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();
    }
    EnumPins->Release();

    // find the VideoRenderer input pin
    pVideoRenderer->EnumPins(&EnumPins);
    EnumPins->Reset();
    EnumPins->Next(1, &InPin, &fetched);
    EnumPins->Release();

    // connect
    pGraphBuilder->Connect(OutPin, InPin);
    InPin->Release();
    OutPin->Release();

    pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&pMediaEvent);
    pGraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&pVideoWindow);

    RECT rc;
    HWND hwnd = m_hWnd;
    GetClientRect(hwnd, &rc);
    pVideoWindow->put_Owner((OAHWND)hwnd);
    pVideoWindow->put_WindowStyle(WS_CHILD);
    pVideoWindow->put_Left(0);
    pVideoWindow->put_Top(0);
    pVideoWindow->put_Width(rc.right - rc.left);
    pVideoWindow->put_Height(rc.bottom - rc.top);
    pVideoWindow->put_Visible(OATRUE);

    hr = AddGraphToRot(pGraphBuilder, &g_dwGraphRegister);
    if (FAILED(hr))
    {
        g_dwGraphRegister = 0;
    }

    pMediaControl->Run();

    long evCode;
    pMediaEvent->WaitForCompletion(INFINITE, &evCode);


    pMediaControl->Stop();
    pVideoWindow->put_Visible(OAFALSE);
    pVideoWindow->put_Owner(NULL);

    pVideoWindow->Release();
    pMediaEvent->Release();
    pMediaControl->Release();

    if (g_dwGraphRegister) RemoveGraphFromRot(g_dwGraphRegister);

    pSource->Release();
    pAviSplitter->Release();
    pVideoRenderer->Release();
    pGraphBuilder->Release();

    CoUninitialize();
}

就像前面說的,因為 RenderFile 會自動建立 Filter 因此更簡單的方法是都不建 Filter。


 


void Test(char *File)
{
    WCHAR *wfile;
    int length;
    IGraphBuilder *pGraphBuilder;
    IEnumFilters *pEnum;
    IBaseFilter *pSource;
    IBaseFilter *pSound;
    IMediaControl *pMediaControl;
    IMediaEvent *pMediaEvent;
    IVideoWindow *pVideoWindow;
    IEnumPins *EnumPins;
    IPin *OutPin;
    IPin *InPin;
    ULONG fetched;
    PIN_INFO pinfo;
    HRESULT hr;
    FILTER_INFO FilterInfo;
    char szName[256];


    CoInitialize( NULL );

    // create graph
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraphBuilder);

    length = strlen(File)+1;
    wfile = new WCHAR[length];
    MultiByteToWideChar(CP_ACP, 0, File, -1, wfile, length);

    // load file source and create some filter by itself
    // include the follow filter will auto created
    // Source, AviSplitter, VideoRenderer, SoundRenderer
    hr = pGraphBuilder->RenderFile(wfile, NULL);

    // find the SourceFilter from RenderFile created
    pGraphBuilder->EnumFilters(&pEnum);
    while(pEnum->Next(1, &pSource, &fetched) == S_OK)
    {
        pSource->QueryFilterInfo(&FilterInfo);
        WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName, -1, szName, 256, 0, 0);
        FilterInfo.pGraph->Release();
        if(strstr(szName, "avi") != NULL) break;
        pSource->Release();
    }
    pEnum->Release();

    // find the SoundFilter
    pGraphBuilder->EnumFilters(&pEnum);
    while(pEnum->Next(1, &pSound, &fetched) == S_OK)
    {
        pSound->QueryFilterInfo(&FilterInfo);
        WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName, -1, szName, 256, 0, 0);
        FilterInfo.pGraph->Release();
        if(strstr(szName, "Sound") != NULL) break;
        pSound->Release();
    }
    pEnum->Release();

    // find the sound input pin
    pSound->EnumPins(&EnumPins);
    EnumPins->Reset();
    EnumPins->Next(1, &InPin, &fetched);
    EnumPins->Release();
    // disconnect the sound renderer pin
    pGraphBuilder->Disconnect(InPin);
    InPin->Release();

    pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&pMediaEvent);
    pGraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&pVideoWindow);

    pVideoWindow->put_Caption((BSTR)"123");

    pMediaControl->Run();
    long evCode;
    pMediaEvent->WaitForCompletion(INFINITE, &evCode);

    pVideoWindow->put_Visible(OAFALSE);
    pVideoWindow->put_Owner(NULL);

    pVideoWindow->Release();
    pMediaEvent->Release();
    pMediaControl->Release();
    pGraphBuilder->Release();

    CoUninitialize();
}



[Download]

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 DirectShow PIN 連接教學
本类热点文章
  DirectShow应用——支持Windows Media格..
  DirectShow PIN 連接教學
  游戏UI设计1
  PSD格式文件的读取
  将RGB值转换为灰度值的简单算法
  貼圖 filtering 與 MIP map 簡介
  读取万能图片以及DShow的另类用法
  TGA图像文件格式资料
  DirectShow初探
  PNG格式
  DirectShow应用——支持DVD播放
  DirectShow的中文资料之建立一个捕捉程序
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00373