Question

I am trying to basically render a preview from a capture card (720p) from a PS3 to the enhanced video render.

Ideally, I would like something like this:

GraphStudio

I used to do this:

hr = m_pCapture->RenderStream (&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pSrcFilter, NULL, NULL);

But I find that it only renders to an old default renderer, which is not adequate enough to stretch the image to 1080p (image becomes pixelated). [http://msdn.microsoft.com/en-us/library/aa930715.aspx ]

I want to use the enhanced video render as the sink but I have no idea how to. I viewed the tutorials here: http://msdn.microsoft.com/en-us/library/windows/desktop/ff625867%28v=vs.85%29.aspx And tried to put my code in but it would not render.

Here is a snippet of the code that sets the source. Assume that setResolution will set the AM_MEDIA_TYPE format and that getVideoSourceByKeyword will get the AVermedia capture card device.

HRESULT DShowPlayer::SetPreviewDevice(PCWSTR keyname)
{
    IBaseFilter *pSource = NULL;

    // Create a new filter graph. (This also closes the old one, if any.)
    HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pCapture));
    if (FAILED(hr))
    {
        goto done;
    }

    hr = InitializeGraph();
    if (FAILED(hr))
    {
        goto done;
    }

    // Add the source filter to the graph.
    hr = getVideoSourceByKeyword(keyname, &pSource);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = m_pGraph->AddFilter(pSource, L"Source filter");
    if (FAILED(hr))
    {
        goto done;
    }

    setResolution(pSource, 1280, 720);

    // Try to render the streams.
    hr = RenderStreams(pSource);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = m_pControl->Run();

done:
    if (FAILED(hr))
    {
        TearDownGraph();
    }
    SafeRelease(&pSource);
    return hr;
}

When the code runs RenderStreams, this is the code (from http://msdn.microsoft.com/en-us/library/windows/desktop/ff625878%28v=vs.85%29.aspx):

// Enumerate the pins on the source filter.
hr = pSource->EnumPins(&pEnum);
if (FAILED(hr))
{
    goto done;
}

// Loop through all the pins
IPin *pPin;
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
    PIN_INFO pInfo;
    pPin->QueryPinInfo(&pInfo);

    // Try to render this pin. 
    // It's OK if we fail some pins, if at least one pin renders.
    HRESULT hr2 = pGraph2->RenderEx(pPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);

    pPin->Release();
    if (SUCCEEDED(hr2))
    {
        bRenderedAnyPin = TRUE;
    }
}

In visual studio I debugged at the pin to get the source name ("Capture" pin name of the AVermedia capture card). It said it was successful to attach to the render at RenderEx however at

hr = m_pControl->Run();

It fails and there error is device is not connected.

I also tried to get the EVR renderer directly and tried to render the stream:

    IBaseFilter* render;
    m_pVideo->getRender(&render);
    m_pGraph->AddFilter(render, L"EVR Filter");
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSource, NULL, render);
    if (FAILED(hr))
    {
        goto done;
    }

But it fails and says that VFW_E_NOT_IN_GRAPH.

What I am asking: I am still pretty new at learning Directshow and I would like to be able to preview the capture card with EVR. I found no comprehensive tutorials or source code to do this. If you need anymore information, I can add more.

Thanks in advance.

Was it helpful?

Solution

EVR can be used programmatically very much the same way as VMR-7/9. The only difference is that EVR needs "windowless" mode, while earlier renderers supported also "windowed" mode where you need minimal initialization of the renderer.

I suppose you can see video on EVR in GraphEdit? You should be able to do so, just use Preview pin, not Capture. Or, connect Capture through Smart Tee filter and its preview output.

The error codes suggest that you don't build graph correctly. In particular, VFW_E_NOT_IN_GRAPH says your filter is not in graph and hence invalid argument. You don't need to use getRender, just CoCreateInstance the EVR the usual and straightforward way. At the first moment you get an error you are interested in putting everything on hold and reviewing the filter graph topology you have at the moment.

Windows SDK samples contain \Samples\multimedia\directshow\vmr9\windowless which shows VMR-9 in windowless mode, this is supposedly the closest starting point to just switch from VMR-9 to EVR.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top