两者都接受ARGB32媒体类型时,引脚之间没有组合

时间:2016-09-08 16:12:15

标签: video directshow directshow.net

我已经标记了directshow和directshow.net,因为我使用C ++和C#来创建源过滤器(用于在内存中加载位图),而c#正在提供位图。

我已经厌倦了问题“这些引脚之间没有常见的媒体类型”,因为源过滤器和渲染器用于连接然后它没有。源过滤器主要基于GSSF样本。

在我的源过滤器中,我允许1种媒体类型:

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

然后在给定位图信息标题的情况下设置媒体类型:

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;
}

从C#调用CreateMediaTypeFromBMI:

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);
}

调用ConnectDirect后,我得到0x80040207。如果我调用RenderStream而得到0x80040217,它告诉我同样的事情,媒体类型无效。

然后是渲染器过滤器,它是由BlackMagicDesign提供的用于捕获和渲染的decklink渲染器。此渲染器支持5种不同类型的媒体,其第4种类型表示ARGB32的子类型guid。

所以我的问题是,如果渲染器支持ARGB32并且我告诉源过滤器它的输出引脚是使用视频的ARGB32,那么directshow如何告诉我这些引脚之间没有共同的媒体类型?

哦,我应该注意fps变量= 10000000/30;

1 个答案:

答案 0 :(得分:2)

错误代码VFW_E_CANNOT_CONNECT是过滤器无法协商媒体类型以流式传输数据的情况。可能存在导致提到错误情况的几个问题。

首先,您将展示如何构建媒体类型。这很重要,但源过滤器的GetMediaTypeCheckMediaType方法也很重要。首先必须正确地公开这种RGB媒体类型,而另一种应该接受它。

您可以使用GraphEdit / GraphStudioNext检查应用程序的这部分内容,验证您的引脚中的视频是否可以渲染到标准视频渲染器(非Decklink)。

其次,你正在进行从上到下的RGB帧(负biHeight),我最好的猜测是Decklink渲染器不接受这种布局。典型的RGB排序是反向的,从底部到顶部。当股票呈现器经常帮助您并提供兼容的媒体类型试图协商两者(或通过转换)可接受的内容时,Decklink呈现器不那么灵活,并且可能因此而拒绝此RGB媒体类型。您可能需要尝试从下到上,至少要排除这一点。

第三,除了上面提到的Decklink渲染器不灵活性之外,该硬件还希望视频格式与线上的视频参数直接兼容。它不会像VMR / EVR滤波器那样缩放视频,视频应严格按照规格,分辨率和帧速率进行。您必须确保您在媒体类型中提供准确的值。例如,硬件可能只能以50,59.94,60的速率接受1280x720,并且它不接受25或30 fps的媒体类型。如果它是NTSC SD视频,那么速率应该是29.97而不是30.

当您看到它的渲染器无法连接并拒绝连接时,您有兴趣检查它拒绝的媒体类型以及完整的详细信息。