2

ビデオ キャプチャをファイルに保存する directshow を使用して C++ アプリケーションを作成しようとしています。コードの手順は次のとおりです。 1. Capture Graph Builder を作成する 2. System Device Enumerator を作成する 3. System Device Enumerator を作成する - キャプチャ フィルタを取得するため 4. ビデオ キャプチャ カテゴリの列挙子を作成する 5. へのクエリを作成するビデオをキャプチャ

コードの取り付け

// gets the device filter
HRESULT getDeviceFilter(REFCLSID clsid, int order, IBaseFilter **pCap)
{

ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;

// Create the System Device Enumerator.
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
                              CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
                              reinterpret_cast<void**>(&pDevEnum));

if (SUCCEEDED(hr))
{
    // Create an enumerator for the video capture category.
    hr = pDevEnum->CreateClassEnumerator( clsid, &pEnum, 0);
}

IMoniker *pMoniker = NULL;

if (pEnum->Next(1, &pMoniker, NULL) == S_OK)
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)pCap);

return hr;
}


int main()
{
IGraphBuilder *pGraph = 0;
ICaptureGraphBuilder2 *pBuild = 0;
IBaseFilter *pCap = 0;
HRESULT hr = CoInitialize(NULL);

// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, 
                              NULL, 
                              CLSCTX_INPROC_SERVER, 
                                  IID_ICaptureGraphBuilder2, 
                              (void**)&pBuild );


ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;

// Create the System Device Enumerator.
hr = CoCreateInstance(CLSID_SystemDeviceEnum, 
                      NULL,
                      CLSCTX_INPROC_SERVER, 
                      IID_ICreateDevEnum,
                      reinterpret_cast<void**>(&pDevEnum));



IBaseFilter *pMux = 0;
hr = pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
                               L"C:\\Example.avi", // File name.
                               &pMux,              //     Receives a pointer to the mux.
                               NULL);              //     (Optional) Receives a pointer to the file sink.


// gets the first device, VDM tv card
hr = getDeviceFilter(CLSID_VideoInputDeviceCategory, 0, &pCap);


hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, // Pin category.
                          &MEDIATYPE_Video,      // Media type.
                          pCap,                  // Capture filter.
                          NULL,                  // Intermediate filter (optional).
                          pMux);                 // Mux or file sink filter.

// Release the mux filter.
pMux->Release();

IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
if (SUCCEEDED(hr))
{
    pConfigMux->SetMasterStream(1);
    pConfigMux->Release();
}

return 0;
}

ただし、RenderStreamを呼び出すと、E_INVALIDARGエラーが発生します。

助言がありますか?

ありがとう

4

1 に答える 1

1

このトピックを見てください。いくつかの手順を逃したようです。

まず第一に、あなたはpGraphどこにも使用していません。グラフマネージャーを作成してから、 SetFilterGraphを使用してグラフマネージャーへのポインターを提供することにより、グラフビルダーを初期化する必要があります。

// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
    IID_IGraphBuilder, (void**)&pGraph);
if (SUCCEEDED(hr))
{
    // Initialize the Capture Graph Builder.
    pBuild->SetFiltergraph(pGraph);

    // ...
}

次に、グラフマネージャーによって管理されていないフィルターを使用しています。ここから引用:

メソッドを呼び出す前に、pSource、pIntermediate、およびpSinkで指定されたすべてのフィルターをグラフに追加する必要があります。

AddFilterを使用して、フィルターを追加し、pCappMuxに作成したグラフマネージャーに追加する必要があります。RenderStreamを呼び出す前にこれを行う必要があります。これは、RenderStreamが最終的にマネージャーの接続メソッドを呼び出すためです。


上記の手順で問題が解決しない場合は、他にもいくつか試すことができます。

デバイスフィルター。の最初のデバイスを使用していますがCLSID_VideoInputDeviceCategory、これが正しいデバイスであると確信していますか?ウェブカメラなどもこのカテゴリに含まれます。同じカテゴリの他のデバイスが接続されていないことを確認して、再試行してください。

接続。すべてのデバイスは異なります。デバイスをマルチプレクサに直接接続できない可能性があります。この場合、その理由を理解し、追加のフィルター(デコーダーなど)を接続する必要があるかどうかを判断する必要があります。GraphEditは、これらのフィルターを見つけるための非常に高速な方法です。

ピンカテゴリ/メディアタイプ。私の経験では、E_INVALIDARGは、の最初の2つのパラメーターによって引き起こされる時間の90%ですRenderStream。ピンカテゴリまたはメディアタイプをに設定してみてくださいNULL

システムデバイス列挙子:あなた自身が説明したように、システムデバイス列挙子を2回作成しています。これは私には奇妙に思えますが、両方の目的で1つを使用してみませんか?


それでもコードが機能しない場合は、詳細情報を提供してください。GraphEditを使用して、目標を達成しましたか?VDM TVカードフィルターはどのように見えますか(ピン、メディアタイプ)?

于 2012-12-06T12:39:07.413 に答える