我已经标记了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;
答案 0 :(得分:2)
错误代码VFW_E_CANNOT_CONNECT
是过滤器无法协商媒体类型以流式传输数据的情况。可能存在导致提到错误情况的几个问题。
首先,您将展示如何构建媒体类型。这很重要,但源过滤器的GetMediaType
和CheckMediaType
方法也很重要。首先必须正确地公开这种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.
当您看到它的渲染器无法连接并拒绝连接时,您有兴趣检查它拒绝的媒体类型以及完整的详细信息。