#include <dshow.h> void main(void) { IGraphBuilder *pGraph; IMediaControl *pMediaControl; ICaptureGraphBuilder2 *pBuild; // 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; } // MediaControlインターフェース取得 pGraph->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl); IBaseFilter *pVmr = NULL; //CoCreateInstance を呼び出し、VMR-9 を作成する。 hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVmr); // VMR-9 をフィルタ グラフに追加する。 hr = pGraph->AddFilter(pVmr, L"VMR9"); // ビデオ ファイル用のソース フィルタを追加する。 IBaseFilter *pSource; hr = pGraph->AddSourceFilter(L"G:\\sampleMovie\\avi_divx5_mp3.avi", L"Source", &pSource); // CaptureGraphBuilder2というキャプチャ用GraphBuilderを生成する hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (LPVOID *)&pBuild); // FilterGraphをセットする hr = pBuild->SetFiltergraph(pGraph); // ビデオ ストリームを VMR にレンダリングする。 hr = pBuild->RenderStream(0, 0, pSource, 0, pVmr); //オーディオ ストリームをレンダリングする。 hr = pBuild->RenderStream(0, &MEDIATYPE_Audio, pSource, 0, NULL); // 再生開始 pMediaControl->Run(); MessageBox(0,0,0,0); pMediaControl->Release(); pBuild->Release(); pGraph->Release(); // COM終了 CoUninitialize(); }フィルタを表示させてみた
こんな感じか?
フィルタを表示させたときのソース
#include <dshow.h> HRESULT EnumFilters (IFilterGraph *pGraph); void main(void) { IGraphBuilder *pGraph; IMediaControl *pMediaControl; ICaptureGraphBuilder2 *pBuild; // 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; } // MediaControlインターフェース取得 pGraph->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl); IBaseFilter *pVmr = NULL; //CoCreateInstance を呼び出し、VMR-9 を作成する。 hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVmr); // VMR-9 をフィルタ グラフに追加する。 hr = pGraph->AddFilter(pVmr, L"VMR9"); // ビデオ ファイル用のソース フィルタを追加する。 IBaseFilter *pSource; hr = pGraph->AddSourceFilter(L"G:\\sampleMovie\\avi_divx5_mp3.avi", L"Source", &pSource); // CaptureGraphBuilder2というキャプチャ用GraphBuilderを生成する hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (LPVOID *)&pBuild); // FilterGraphをセットする hr = pBuild->SetFiltergraph(pGraph); // ビデオ ストリームを VMR にレンダリングする。 hr = pBuild->RenderStream(0, 0, pSource, 0, pVmr); //オーディオ ストリームをレンダリングする。 hr = pBuild->RenderStream(0, &MEDIATYPE_Audio, pSource, 0, NULL); // 再生開始 pMediaControl->Run(); EnumFilters(pGraph); MessageBox(0,0,0,0); pMediaControl->Release(); pBuild->Release(); pGraph->Release(); // COM終了 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); //printf(FilterInfo.achName); wprintf(L"%s\n", FilterInfo.achName); #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; }msdnのページでは、Capture Graph Builder を使いたくない場合の方法も書いてあったので、
とりあえずやってみた。
未整理のソースコード、一応動く程度
#include <dshow.h> void main(void) { IGraphBuilder *pGraph; IMediaControl *pMediaControl; // 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; } // MediaControlインターフェース取得 pGraph->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl); IBaseFilter *pVmr = NULL; //CoCreateInstance を呼び出し、VMR-9 を作成する。 hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVmr); // VMR-9 をフィルタ グラフに追加する。 hr = pGraph->AddFilter(pVmr, L"VMR9"); // ビデオ ファイル用のソース フィルタを追加する。 IBaseFilter *pSource; hr = pGraph->AddSourceFilter(L"G:\\sampleMovie\\cap.avi", L"Source", &pSource); // CaptureGraphBuilder2というキャプチャ用GraphBuilderを生成する //hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, // IID_ICaptureGraphBuilder2, // (LPVOID *)&pBuild); // FilterGraphをセットする /*hr = pBuild->SetFiltergraph(pGraph);*/ // ビデオ ストリームを VMR にレンダリングする。 // hr = pBuild->RenderStream(0, 0, pSource, 0, pVmr); //オーディオ ストリームをレンダリングする。 //hr = pBuild->RenderStream(0, &MEDIATYPE_Audio, pSource, 0, NULL); //ピンの列挙 IFilterGraph* pFGraph; hr = pGraph->QueryInterface(IID_IFilterGraph, (void**)&pFGraph); IEnumFilters *pEnum = NULL; IBaseFilter *pFilter; ULONG cFetched; hr = pGraph->EnumFilters(&pEnum); if (FAILED(hr)) return; //フィルタの列挙 while(pEnum->Next(1, &pFilter, &cFetched) == S_OK) { IPin *pPin = NULL; FILTER_INFO FilterInfo; hr = pFilter->QueryFilterInfo(&FilterInfo); wprintf(L"%s", FilterInfo.achName); printf(" フィルターが見つかった\n"); //ピンを探しに行く IFilterGraph2 *pGraph2 = NULL; hr = pGraph->QueryInterface(IID_PPV_ARGS(&pGraph2)); { IEnumPins *pEnum; IPin *pPin; IPin* pConnectedPin = NULL; hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) { return ; } while(pEnum->Next(1, &pPin, 0) == S_OK) { // ピンが列挙される printf("pinの列挙--"); PIN_DIRECTION PinDirThis; hr = pPin->QueryDirection(&PinDirThis); if ((hr == S_OK)&&(PinDirThis == PINDIR_INPUT)) { printf("入力ピン--");// hr = pPin->ConnectedTo(&pConnectedPin);//接続済みか調べる if (hr == S_OK) { printf("接続済み\n");// }else{ printf("未接続\n");// } } if ((hr == S_OK)&&(PinDirThis == PINDIR_OUTPUT)) { printf("出力ピン--");// hr = pPin->ConnectedTo(&pConnectedPin);//接続済みか調べる if (hr == S_OK) { printf("接続済み\n");// }else printf("未接続\n");// hr = pGraph2->RenderEx(pPin,AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL); } } } // 見つかったピンを何かに使用 if (pPin) { pPin->Release(); } pFilter->Release(); } // 再生開始 pMediaControl->Run(); MessageBox(0,0,0,0); pMediaControl->Release(); // pBuild->Release(); pGraph->Release(); // /COM終了 CoUninitialize(); }
AM_RENDEREX_RENDERTOEXISTINGRENDERERS フラグを使って、IFilterGraph2::RenderEx を呼び出すと、既にグラフにあるレンダリング フィルタ のみを使い、出力ファイルがレンダリングされるそうです。
音は出ない。どうすればいいのだろうか?
サウンドフィルタの追加
/*サウンド部分*/ IBaseFilter *pAudioRenderer = NULL; hr = CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAudioRenderer); hr = pGraph->AddFilter(pAudioRenderer, L"Audio Renderer");
0 件のコメント:
コメントを投稿