2013年6月9日日曜日

フィルタグラフ内のフィルタの列挙

ファイルの再生ではDirectShowがすべて処理してくれるので、
File Source しか指定していないので表示させてみる。

【表示結果】
Video Renderer
Color Space Converter
AVI Splitter
G:\\sampleMovie\\cap.avi



#include <dshow.h>

HRESULT EnumFilters (IFilterGraph *pGraph);

void main(void)
{
 IGraphBuilder *pGraph = NULL;
 IMediaControl *pControl = NULL;
 IMediaEvent   *pEvent = NULL;
 IFilterGraph  *pFGraph = NULL;

 // COM ライブラリを初期化する。
 HRESULT hr = CoInitialize(NULL);
 if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return;
    }

    // フィルタ グラフ マネージャを作成し、インターフェイスを問い合わせる。
    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);

    // グラフを作成する。 重要 : この文字列をシステム上のファイルに置き換える。
    hr = pGraph->RenderFile(L"G:\\sampleMovie\\cap.avi", NULL);

 hr = pGraph->QueryInterface(IID_IFilterGraph, (void**)&pFGraph);

    if (SUCCEEDED(hr))
    {
        // グラフを実行する。
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // 完了するまで待機する。
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // 注 : 実際のアプリケーションでは INFINITE を使用しないこと。
            // 無期限にブロックする場合がある。
        }
    }
 
 EnumFilters(pFGraph);

    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();
}

HRESULT EnumFilters (IFilterGraph *pGraph) 
{
 IEnumFilters *pEnum = NULL;
 IBaseFilter *pFilter;
 ULONG cFetched;

 // COM ライブラリを初期化する。
 HRESULT hr = CoInitialize(NULL);
 if (FAILED(hr))
 {
  printf("ERROR - Could not initialize COM library");
  return 0;
 }

 hr = pGraph->EnumFilters(&pEnum);
 if (FAILED(hr)) return hr;

 while(pEnum->Next(1, &pFilter, &cFetched) == S_OK)
 {
  FILTER_INFO FilterInfo;
  hr = pFilter->QueryFilterInfo(&FilterInfo);
  if (FAILED(hr))
  {
   MessageBox(NULL, TEXT("Could not get the filter info"),
    TEXT("Error"), MB_OK | MB_ICONERROR);
   continue;  // 次は正しく動く可能性がある。
  }

#ifdef UNICODE
  MessageBox(NULL, FilterInfo.achName, TEXT("Filter Name"), MB_OK);
#else
  char szName[MAX_FILTER_NAME];
  int cch = WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName,
   MAX_FILTER_NAME, szName, MAX_FILTER_NAME, 0, 0);
  if (chh > 0)
   MessageBox(NULL, szName, TEXT("Filter Name"), MB_OK);
#endif

  // FILTER_INFO 構造体はフィルタ グラフ マネージャへのポインタを保持する。
  // その参照カウントは解放しなければならない。
  if (FilterInfo.pGraph != NULL)
  {
   FilterInfo.pGraph->Release();
  }
  pFilter->Release();
 }

 pEnum->Release();
 return S_OK;
}

0 件のコメント:

コメントを投稿