Directshow RenderStream“参数不正确"; [英] Directshow RenderStream "the parameter is incorrect"

查看:101
本文介绍了Directshow RenderStream“参数不正确";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图按照Windows开发人员中心上的DirectShow示例制作自己的应用程序,以捕获屏幕和音频到视频的内容:

I am trying to follow through the DirectShow examples on the windows dev center to make my own application that can capture screen and audio to video: Capturing Video to an AVI File

以下代码运行时,它在第一个RenderStream调用上失败,并显示以下错误: + errMsg 0x09910DB8参数不正确." wchar_t *

When the below code runs it fails on the first RenderStream call with the error: + errMsg 0x09910DB8 "The parameter is incorrect." wchar_t*

有人知道如何找出哪个参数不正确吗?

Does anybody have any clue how to figure out which parameter is incorrect?

void AudioVideoBuilder::AVBuilder::MakeVideo()
{
    IGraphBuilder *pGraph = NULL;
    ICaptureGraphBuilder2 *pBuild = NULL;

    // Create the Filter Graph Manager.
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
        CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

    if (SUCCEEDED(hr))
    {
        // Create the Capture Graph Builder.
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
            CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
            (void **)&pBuild);
        if (SUCCEEDED(hr))
        {
            pBuild->SetFiltergraph(pGraph);
        }
    };
    if (SUCCEEDED(hr))
    {
        // Create the Capture Graph Builder.
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_ICaptureGraphBuilder2,
            (void**)&pBuild);
        IBaseFilter *pMux;
        if (SUCCEEDED(hr))
        {
            hr = pBuild->SetOutputFileName(
                &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
                L"C:\\Temp\\Example.avi", // File name.
                &pMux,              // Receives a pointer to the mux.
                NULL);              // (Optional) Receives a pointer to the file sink.

            if (SUCCEEDED(hr))
            {
                IBaseFilter *audioFilter;
                IBaseFilter *videoFilter;
                //GetAudioAndVideoFilters(audioFilter, videoFilter);

                IEnumMoniker *pEnum;
                CaptureDeviceSelector deviceSelector;
                HRESULT hr = deviceSelector.EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
                if (SUCCEEDED(hr))
                {
                    IMoniker *pMoniker = NULL;
                    while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
                    {
                        IPropertyBag *pPropBag;
                        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
                        if (FAILED(hr))
                        {
                            pMoniker->Release();
                            continue;
                        }
                        VARIANT var;
                        VariantInit(&var);

                        // Get description or friendly name.
                        hr = pPropBag->Read(L"Description", &var, 0);
                        if (FAILED(hr))
                        {
                            hr = pPropBag->Read(L"FriendlyName", &var, 0);
                        }
                        //if (var == "screen-capture-recorder")
                        hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&videoFilter);
                        if (SUCCEEDED(hr))
                        {
                            break;
                        }
                    }
                    hr = deviceSelector.EnumerateDevices(CLSID_AudioInputDeviceCategory, &pEnum);
                    if (SUCCEEDED(hr))
                    {
                        while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
                        {
                            IPropertyBag *pPropBag;
                            HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
                            if (FAILED(hr))
                            {
                                pMoniker->Release();
                                continue;
                            }
                            VARIANT var;
                            VariantInit(&var);

                            // Get description or friendly name.
                            hr = pPropBag->Read(L"Description", &var, 0);
                            if (FAILED(hr))
                            {
                                hr = pPropBag->Read(L"FriendlyName", &var, 0);
                            }
                            hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&audioFilter);
                            if (SUCCEEDED(hr))
                            {
                                break;
                            }
                        }
                    }
                }
                            //ADDED BASED ON MARTIN'S SUGGESTED ANSWER
            hr = pGraph->AddFilter(audioFilter, NULL);
            if (FAILED(hr))
            {
                _com_error err(hr);
                LPCTSTR errMsg = err.ErrorMessage();
                return;
            }
            hr = pGraph->AddFilter(videoFilter, NULL);
            if (FAILED(hr))
            {
                _com_error err(hr);
                LPCTSTR errMsg = err.ErrorMessage();
                return;
            }       
                hr = pBuild->RenderStream(
                    &PIN_CATEGORY_CAPTURE, // Pin category.
                    &MEDIATYPE_Audio,      // Media type.
                    audioFilter,                  // Capture filter.
                    NULL,                  // Intermediate filter (optional).
                    pMux);                 // Mux or file sink filter.

                if (SUCCEEDED(hr))
                {
                    hr = pBuild->RenderStream(
                        &PIN_CATEGORY_CAPTURE, // Pin category.
                        &MEDIATYPE_Video,      // Media type.
                        videoFilter,                  // 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(0);
                        pConfigMux->Release();
                    }

                    IConfigInterleaving *pInterleave = NULL;
                    hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
                    if (SUCCEEDED(hr))
                    {
                        pInterleave->put_Mode(INTERLEAVE_CAPTURE);
                        pInterleave->Release();
                    }
                }
                else
                {
                    _com_error err(hr); 
                    LPCTSTR errMsg = err.ErrorMessage();
                }
            }
            else
            {
                DWORD error = HRESULT_CODE(hr);
            }
        }
    }
    else
    {
        DWORD error = HRESULT_CODE(hr);
    }
}

推荐答案

除了代码中的其他问题(请参见注释)之外,主要问题是复制/粘贴问题:您创建了两次CLSID_CaptureGraphBuilder2.

Apart from other issues in your code (see comments), the primary problem is copy/paste problem: you create CLSID_CaptureGraphBuilder2 twice.

因此,您首先创建对象并将其与过滤图相关联,然后再创建另一个.您将源过滤器添加到第一个图,并请求在另一个图中创建多路复用器过滤器链.那些绝对不能连接,属于不同的图,因此也出错.

So you create the object first and associate it with your filter graph, and then you create the other one. You add source filters to the first graph, and you request multiplexer filter chain to be created in the other. Those definitely cannot connect, belong to different graphs and hence the error.

评论第二部分,您可以继续:

Comment the second section, and you can move on:

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

由于您将要处理DirectShow过滤器图形一段时间,因此我建议您学习如何使用GraphEdit在运行时浏览图形(或者,我宁愿建议使用GraphStudioNext).

Since you are going to deal with DirectShow filter graphs for some time, I suggest that you learn how to explore your graphs on runtime using GraphEdit (or, I would rather recommend GraphStudioNext instead).

您可以在代码中的任意位置添加MessageBox调用,并保持弹出消息窗口的状态,您可以在应用程序中查看图形并立即发现问题.

You can add a MessageBox call at any point in your code and keeping the message window popped up you would look at graphs in your application and see the problem immediately.

这篇关于Directshow RenderStream“参数不正确";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆