3

インターネットで調べた後、Decklink SDIカードのストリーミングに基づいてaviビデオファイルを書き込もうとしていますが、ここで私がこのコードを書いたのは、プログラムがファイルを書き込んでいないという問題です。コードは次のとおりです。

#include <Windows.h>
#include <DShow.h>
#include <iostream>


 int main(void)
{
IGraphBuilder* pGraph = NULL;
ICaptureGraphBuilder2* pBuild = NULL;
IMediaControl* pControl = NULL;

ICreateDevEnum* pDevEnum = NULL;
IEnumMoniker* pEnum = NULL;
IMoniker *pMoniker = NULL;
IMoniker* goodMoniker = NULL;
IBaseFilter* pCap;
HRESULT hr;

//Initialize pGraph
hr = CoInitialize(NULL);
   hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **) &pGraph);
if(FAILED(hr))
{
    printf("ERROR - Could not initialize COM library");
    return 1;
}

//Initialize pBuild


 hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**) &pBuild);
if(FAILED(hr))
{
    printf("ERROR - Could not create the Filter Graph Manager.");
    return 2;
}
pBuild->SetFiltergraph(pGraph);



hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&pDevEnum));
if(SUCCEEDED(hr))
{
    hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
}


HWND hList;

while(pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
    IPropertyBag* pPropBag;
    hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
    if(FAILED(hr))
    {
        pMoniker->Release();
        continue;
    }

    VARIANT varName;
    VariantInit(&varName);
    hr = pPropBag->Read(L"Description", &varName, 0);
    if(FAILED(hr))
    {
        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
    }
    if(SUCCEEDED(hr))
    {
        for(int i=0;i<20;i++)
        {
           std::cout<<(char)*(varName.bstrVal + i);
        }

        char yn;
        std::cin>>yn;

        if(yn=='Y')
        {
            std::cout<<"SUCCESSFUL"<<std::endl;
            goodMoniker = pMoniker;
            VariantClear(&varName);
        }
    }
    pPropBag->Release();
    if(pMoniker != goodMoniker)
    {
        pMoniker->Release();
    }
}


hr = goodMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)(&pCap));

if(SUCCEEDED(hr))
{
    hr = pGraph->AddFilter(pCap, L"Capture Filter");

}

IBaseFilter *pMux = NULL;

//  hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);

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

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.  


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

printf("START ");
hr = pControl->Run();

Sleep(100000);
hr = pControl->Stop();
CoUninitialize();


pGraph->Release();
pBuild->Release();
pCap->Release();

}

デバッグしようとしたときに表示されるエラーメッセージは次のとおりです。

  Unhandled exception at 0x776015de in STREAMMMMM.exe: 0xC0000005: Access violation reading location 0x00000000.

プログラムは次の行でクラッシュします。

 r = pCap->QueryInterface(IID_IMediaControl,(void**) pControl);
4

1 に答える 1

3

インターネット上の DirectShow を使用して AVI に書き込む方法については、数百とは言わないまでも数十の例があります。

この特定のコード スニペットは、書き込みを開始していません。それはパイプラインを準備するだけで、あなたがやるIMediaControl::Runべきことさえしていません。さらに、書き込みが十分になるまで待ってから、記録を停止し、インターフェイス ポインターを解放する必要があります。

この Q: Using a DirectShow filter without register it, via a private CoCreateInstance on what you'll get to start to 実際のキャプチャと書き込み (IMediaControl::Run特にSleep)。

于 2013-01-24T15:43:47.940 に答える