【问题标题】:How to write an avi file with DirectShow如何使用 DirectShow 编写 avi 文件
【发布时间】:2013-01-24 15:35:53
【问题描述】:

我正在尝试根据我的 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);

【问题讨论】:

标签: c++ winapi video directshow


【解决方案1】:

互联网上有数十个(如果不是数百个)关于如何使用 DirectShow 写入 AVI 的示例。

这个特殊的代码 sn-p 甚至没有开始编写。它只准备管道,你甚至没有做IMediaControl::Run,这是你应该做的。再进一步,你应该等到你写够了,然后停止录制,然后才释放接口指针。

看看这个问题:Using a DirectShow filter without registering it, via a private CoCreateInstance,了解您在开始实际捕获和写入时缺少什么(特别是IMediaControl::RunSleep)。

【讨论】:

  • 我只想用我的设备记录 10 秒
  • 我添加了另一个问题的链接供您查看。
  • @Roman 感谢您的帮助,我根据其他问题编辑了代码,但仍然无法正常工作(请参阅我编辑的问题
  • 你应该做一些调试并得到错误代码。您可能还想看看 Blackmagic 的 SDK。它是公开下载的,并且有 DirectShow 项目的示例代码,请参阅 \Blackmagic DeckLink SDK 9.5\Win\Samples 那里。预构建的可执行文件也在那里。除了已经提到的,可能还有其他原因不能录制视频,例如在 Decklink 板上设置了错误的捕获格式。
  • 我的代码不适用于网络摄像头和 Decklink SDI 卡。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 2010-09-27
  • 1970-01-01
相关资源
最近更新 更多