2

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. https://msdn.microsoft.com/en-us/library/windows/desktop/dd318627(v=vs.85).aspx

When I run through the RenderStream method fails and the HRESULT_CODE is 16387.

Here is my code. I've read lots of examples and can't quite get my head around it all. I'd love to get something really basic working so I can expand it on my own.

I realize it won't be best practice etc. I am very rusty with C++ and new to DirectShow so please don't be too critical and feel free to explain like I'm a bit simple!

Here is the code I have:

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);
        }
    };
    IBaseFilter *pCap = 0;
    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:\\Example.avi", // File name.
                &pMux,              // Receives a pointer to the mux.
                NULL);              // (Optional) Receives a pointer to the file sink.

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

                    IConfigInterleaving *pInterleave = NULL;
                    hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
                    if (SUCCEEDED(hr))
                    {
                        pInterleave->put_Mode(INTERLEAVE_CAPTURE);
                        pInterleave->Release();
                    }
                }
                else
                {
                    DWORD error = HRESULT_CODE(hr);
                }
            }
            else
            {
                DWORD error = HRESULT_CODE(hr);
            }
        }
    }
    else
    {
        DWORD error = HRESULT_CODE(hr);
    }
}
tux3
  • 7,171
  • 6
  • 39
  • 51
JustinC
  • 29
  • 5
  • 1
    You cannot write to C:\ root folder. – Andrew Komiagin Apr 13 '15 at 19:54
  • Please also use better error handling: `_com_error err(hr); LPCTSTR errMsg = err.ErrorMessage();` So we can find out what's going on here. – Andrew Komiagin Apr 13 '15 at 19:57
  • Thanks for the feedback guys. I have changed to AVI location to the temp folder and the improved error handling returned - "+ errMsg 0x0556FEB0 "Invalid pointer" wchar_t* ".. This seems to match the suggestion from Martin below, I think, so will work to figure out adding the capture device and enumerating. – JustinC Apr 14 '15 at 06:57

2 Answers2

2

As Andrew Komiagin already suggested in the comment. Do not use "c:\Example.avi" as a target file. It may lead to unnecessary problems if you do not have the access rights for root.

Also, in your code you do nowhere define a capture device (input device). The variable pCap in

pBuild->RenderStream

is set to 0(NULL) in your code. It has to be a capture device. RenderStream is expecting a capture device or a renderer, never NULL. If you search for errorcode, use the hex. 16387 is 0x4003 which is a problem with the input pin. No wonder, it is zero.

Look here

https://msdn.microsoft.com/en-us/library/windows/desktop/dd377566(v=vs.85).aspx

to learn how to get a capture device.

Martin Schlott
  • 4,369
  • 3
  • 25
  • 49
  • starting as Admin or adjusting that folders permissions should still have it working. – deW1 Apr 13 '15 at 20:04
  • @deW1 I change the text. – Martin Schlott Apr 13 '15 at 20:06
  • So I have implemented enumeration of devices and selected the first audio and video device found just to get it going. Unfortunately now I get the error + errMsg 0x09910DB8 "The parameter is incorrect." wchar_t* – JustinC Apr 16 '15 at 08:37
  • @JustinC 0x09910DB8 looks more like a pointer. It is not a valid HRESULT. Without seeing your new code it is impossible to give an answer. I guess to much has changed so it may be better to open a new question. If only a small portion has changed, update your question. Make sure that you mark the changes as **UPDATE** otherwise the answers I and other made until now will not match anymore (which can result in downvotes). If you are not sure , open a new question, reduce your code down to a small sample only showing the bug, not the whole renderpipe. – Martin Schlott Apr 16 '15 at 09:31
  • Thanks Martin, I had changed a fair bit of code between so posted a new question including the updated code.. http://stackoverflow.com/questions/29670733/directshow-renderstream-the-parameter-is-incorrect – JustinC Apr 16 '15 at 09:38
1

The problem here is the same as in your newer question: Directshow RenderStream "the parameter is incorrect" and it is unintentional second creation of CLSID_CaptureGraphBuilder2 instance (details).

Also note that error code is the HRESULT value. This is what explains the status of operation. Once you attempt to obtain a string and get a pointer to characters, the pointer (0x055..., 0x099...) is not an error code, it is just some random address with no special meaning. The code is the key.

Community
  • 1
  • 1
Roman R.
  • 68,205
  • 6
  • 94
  • 158