No combination between pins when both accept ARGB32 media type

3

I have tagged both directshow as well as directshow.net because I'm using both C++ and C# to create a source filter (for loading up bitmaps in memory) and c# is supplying the bitmap.

I've been stumped on the problem "There is no common media type between these pins" for days now as the source filter and the renderer used to connect and then it didn't. The source filter is largely based off of the GSSF sample.

In my source filter, I allow 1 media type:

AMOVIESETUP_MEDIATYPE sudMediaTypes[] =
{
    { &MEDIATYPE_Video, &MEDIASUBTYPE_ARGB32 }
};

and then set the media type given the bitmap info header:

HRESULT CPushPinBitmap::CreateMediaTypeFromBMI(BITMAPINFOHEADER *bmi, LONGLONG lFPS)
{
    auto pvi = reinterpret_cast<VIDEOINFOHEADER*>(m_amt.AllocFormatBuffer(SIZE_PREHEADER + bmi->biSize));

    if (pvi == nullptr)
    {
        return E_OUTOFMEMORY;
    }

    ZeroMemory(pvi, m_amt.cbFormat);
    pvi->AvgTimePerFrame = lFPS;
    memcpy(&pvi->bmiHeader, bmi, bmi->biSize);
    m_lBufferSize = GetBitmapSize(&pvi->bmiHeader);
    pvi->bmiHeader.biSizeImage = m_lBufferSize;
    pvi->dwBitRate = m_lBufferSize * static_cast<DWORD>(static_cast<float>(UNITS) / pvi->AvgTimePerFrame) * 8;

    SetRectEmpty(&pvi->rcSource);
    SetRectEmpty(&pvi->rcTarget);

    m_amt.SetType(&MEDIATYPE_Video);
    m_amt.SetSubtype(&MEDIASUBTYPE_ARGB32);
    m_amt.SetFormatType(&FORMAT_VideoInfo);
    m_amt.SetSampleSize(bmi->biSizeImage);
    m_amt.SetTemporalCompression(FALSE);

    return S_OK;
}

CreateMediaTypeFromBMI is called from C#:

public void SetMediaType(ISourceConfig sourceConfig)
{
    var bmi = new BitmapInfoHeader();

    if (bitmap == null)
    {
        int i;
        GetImage(0, IntPtr.Zero, 0, out i);
    }

    bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
    bmi.Width = bitmapData.Width;
    bmi.Height = bitmapData.Height * -1;
    bmi.Planes = 1;
    bmi.BitCount = 32;
    bmi.Compression = 0;
    bmi.ImageSize = bmi.Width * bmi.Height * bmi.BitCount / 8;
    bmi.XPelsPerMeter = 0;
    bmi.YPelsPerMeter = 0;
    bmi.ClrUsed = 0;
    bmi.ClrImportant = 0;

    var hr = sourceConfig.SetMediaTypeFromBitmap(bmi, fps);
    DsError.ThrowExceptionForHR(hr);
}

After calling ConnectDirect I get 0x80040207. If I call RenderStream instead I get 0x80040217 which is telling me the same thing, that media types are invalid.

So then comes the renderer filter, being a decklink renderer provided by BlackMagicDesign for capture and rendering. This renderer supports 5 different types of media, where its 4th type denotes the subtype guid for ARGB32.

So my question, if the render supports ARGB32 and I'm telling the source filter that its output pin is ARGB32 using video, then how can directshow tell me that there is no common media type between these pins?

Oh, and I should note that fps variable = 10000000 / 30;

video
directshow
directshow.net
asked on Stack Overflow Sep 8, 2016 by bl4kh4k • edited Sep 8, 2016 by Roman R.

1 Answer

3

The error code VFW_E_CANNOT_CONNECT is typical for cases where filters are unable to negotiate media types to stream data. There might be several problems leading to mentioned error scenario.

First, you show how you build the media type. It is important but it is also important what GetMediaType and CheckMediaType methods of source filter do. There first has to correctly expose this RGB media type, and the other should accept it back.

You can check this part of of your application with GraphEdit/GraphStudioNext verifying that video from your pin is renderable to standard video renderer (non-Decklink).

Second, you are doing top-to-bottom RGB frames (negative biHeight), and my best guess would be that Decklink renderer does not accept this layout. Typical RGB ordering is reverse, bottom-to-top. When stock renderers are often helping you and offer compatible media types trying to negotiate something acceptable for both (or through conversion), Decklink renderer is not that flexible and might reject this RGB media type just for this reason. You might need to try bottom-to-top, at least to rule this out.

Third, apart from Decklink renderer inflexibility mentioned above, this hardware expects video in formats directly compatible with video parameters on wire. It won't scale video like VMR/EVR filters and the video should be strictly per specification, resolution and frame rate. You have to be sure your are giving accurate values in the media type. For example, the hardware might be able to accept 1280x720 only at rates 50, 59.94, 60 and it won't accept media types with 25 or 30 fps. If it's NTSC SD video, then the rate should be 29.97 and not 30.

When you see that it's renderer failing to connect and rejecting the connection, you are interested in checking the media type it rejects with full details exactly.

answered on Stack Overflow Sep 8, 2016 by Roman R.

User contributions licensed under CC BY-SA 3.0