我正在研究从 CTransformFilter 派生的自定义视频转换过滤器。它不会做任何 DirectShow 术语中不寻常的事情,例如媒体样本的额外内部缓冲、输出样本的排队或动态格式更改。
按下播放时,graphedit 中的图表包含我的过滤器的两个实例,首尾相连(第一个输出连接到第二个输入)。该图绝对没有挂在 ::Transform 方法覆盖中。第二个过滤器实例不直接连接到视频渲染器。
如果在两个滤镜之间插入颜色转换器,则不会发生此问题。如果我将请求的缓冲区数量(ALLOCATOR_PROPERTIES::cBuffers)从 1 增加到 3,那么问题就会消失。下面是原始的 DecideBufferSize 覆盖,与许多其他示例 DirectShow 过滤器代码类似。
在 DirectShow 过滤器(转换或其他方式)中设置请求缓冲区数量的稳健策略是什么?对于现代需求,请求一个缓冲区的代码是否已过时?我的问题是缓冲区太少还是增加了缓冲区的数量来掩盖不同的问题?
HRESULT MyFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
AM_MEDIA_TYPE mt;
HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
if (FAILED(hr)) {
return hr;
}
BITMAPINFOHEADER * const pbmi = GetBitmapInfoHeader(mt);
pProp->cbBuffer = DIBSIZE(*pbmi);
if (pProp->cbAlign == 0) {
pProp->cbAlign = 1;
}
if (pProp->cBuffers == 0) {
pProp->cBuffers = 3;
}
// Release the format block.
FreeMediaType(mt);
// Set allocator properties.
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProp, &Actual);
if (FAILED(hr)) {
return hr;
}
// Even when it succeeds, check the actual result.
if (pProp->cbBuffer > Actual.cbBuffer) {
return E_FAIL;
}
return S_OK;
}