Winapi 分配器_PROPERTIES::cBuffers中有多少缓冲区足够?
我正在开发一个自定义视频转换过滤器,它是从CtrTransformFilter派生的。在DirectShow术语中,它不会做任何不寻常的事情,例如媒体样本的额外内部缓冲、输出样本的排队或动态格式更改 graphedit中包含两个端到端连接的my filters实例的图形(第一个的输出连接到第二个的输入)在按下play时挂起。该图肯定不在::Transform方法覆盖内。第二个过滤器实例未直接连接到视频渲染器 如果在两个滤光片之间插入颜色转换器,则不会出现问题。如果我将请求的缓冲区数量(分配器_PROPERTIES::cBuffers)从1增加到3,那么问题就消失了。下面是原始的DecideBufferSize覆盖,它与许多其他示例DirectShow筛选器代码类似 在DirectShow筛选器(转换或其他)中设置请求的缓冲区数量的可靠策略是什么?对于现代需求,请求一个缓冲区的代码是否已过时?我的问题是缓冲区太少还是缓冲区数量的增加掩盖了另一个问题Winapi 分配器_PROPERTIES::cBuffers中有多少缓冲区足够?,winapi,video,directshow,Winapi,Video,Directshow,我正在开发一个自定义视频转换过滤器,它是从CtrTransformFilter派生的。在DirectShow术语中,它不会做任何不寻常的事情,例如媒体样本的额外内部缓冲、输出样本的排队或动态格式更改 graphedit中包含两个端到端连接的my filters实例的图形(第一个的输出连接到第二个的输入)在按下play时挂起。该图肯定不在::Transform方法覆盖内。第二个过滤器实例未直接连接到视频渲染器 如果在两个滤光片之间插入颜色转换器,则不会出现问题。如果我将请求的缓冲区数量(分配器_P
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;
}
对于缓冲区的数量没有特定的策略,不过您应该明确地知道,固定数量的缓冲区是控制采样率的方法。当所有缓冲区都在使用时,对另一个缓冲区的请求将阻止执行,直到该缓冲区可用为止 也就是说,如果您的代码出于某种目的持有缓冲区引用,那么您应该分配相应的数量,这样您就不会锁定自己。例如,您在内部保留最后一个媒体样本引用,例如,为了能够重新发送它,而您仍然希望能够传递其他媒体样本,因此分配器上至少需要两个缓冲区 输出引脚通常负责选择和设置分配器,输入端可能需要检查和更新属性,如果/当它被通知要使用哪个分配器时。在共享分配器时,在就地转换过滤器上,您可能需要进行额外的检查,以确保满足要求
使用(至少有时)仅具有一个缓冲区的分配器,并且仍然处于良好状态DMO包装过滤器
- 对于音频,您通常会有更多的缓冲区,因为您将数据排队等待播放
- 如果代码中存在引用泄漏,并且未发布媒体示例指针,则流媒体可能会因此而锁定