首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用DirectShow将视频捕获到AVI文件

用DirectShow将视频捕获到AVI文件
EN

Stack Overflow用户
提问于 2012-12-06 11:53:54
回答 1查看 2.7K关注 0票数 2

我试图用directshow编写一个C++应用程序,该应用程序可以将视频捕获保存到文件中。代码中的步骤如下: 1.创建捕获图形生成器2.创建系统设备枚举器3.创建系统设备枚举器--以获得捕获过滤器4.为视频捕获类别5创建枚举器.创建用于捕获视频的查询

附加代码

代码语言:javascript
复制
// 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错误

有什么建议吗?

谢谢

EN

回答 1

Stack Overflow用户

发布于 2012-12-06 12:39:07

看看本题。你好像错过了一些步骤。

首先,您没有在任何地方使用pGraph。您应该创建一个图形管理器,然后使用SetFilterGraph为图形生成器提供指向图形管理器的指针,从而初始化它。

代码语言:javascript
复制
// 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指定的所有筛选器添加到图中。

您必须将过滤器pCappMux添加到前面使用AddFilter创建的图形管理器中。在调用RenderStream之前,您应该这样做。这是因为RenderStream最终会调用管理器上的连接方法。

如果以上步骤不能解决您的问题,您还可以尝试其他几种方法。

设备过滤器。您正在使用CLSID_VideoInputDeviceCategory的第一个设备,但您确定这是正确的设备吗?网络摄像机等也属于这一类别。确保没有连接相同类别的其他设备,然后再试一次。

连接。每个设备都是不同的。它可能是你的设备不能直接连接到穆克斯。在这种情况下,我们必须找出原因,并确定是否需要连接额外的过滤器(如解码器)。GraphEdit是查找这些过滤器的一种非常快速的方法。

针类/媒体类型。根据我的经验,E_INVALIDARG是由RenderStream的前2个参数引起的90%的时间。尝试将引脚类别或媒体类型设置为NULL

系统设备枚举器:正如您自己描述的那样,您要创建两次系统设备枚举器。这在我看来很奇怪,为什么不同时使用一种呢?

如果您的代码仍然不能工作,您应该向我提供更多的信息。当你使用GraphEdit时,你实现了你的目标吗?你的VDM电视卡过滤器看起来怎么样(插脚,媒体类型)?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13743076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档