2012-06-22 41 views
0

我正在从CTransformFilter派生的自定义视频转换过滤器。它在DirectShow术语中不会出现任何异常情况,如媒体样本的额外内部缓冲,输出样本的排队或动态格式更改。ALLOCATOR_PROPERTIES :: cBuffers中有多少缓冲区?

包含我的过滤器的两个端对端连接(第一个连接到第二个输入的输出)的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; 
} 

回答

2

缓冲区的数量没有特定的策略,但您应该清楚固定数量的缓冲区是控制采样率的方法。当所有缓冲区都在使用中时,对另一个缓冲区的请求将阻止执行,直到此缓冲区可用。

也就是说,如果您的代码为了某种目的而保存缓冲区引用,则应该分配相应的数量,以便不锁定自己。例如。您在内部保存最后的媒体样本参考,例如能够重新发送它,并且您仍然希望能够提供其他媒体样本,因此您至少需要分配器上的两个缓冲区。

输出引脚通常负责选择和设置分配器,输入可能需要检查和更新属性,如果/当它被通知哪个分配器将被使用。在共享分配器时就地转换过滤器时,您可能需要额外检查以确保符合要求。

  • DMO Wrapper Filter使用(至少有时)仅具有一个缓冲分配器并且仍然在良好信誉
  • 与音频你通常有多种缓冲液,因为你排队播放
  • 数据如果在有一个参考泄漏您的代码,并且您不释放媒体样本指针,那么您的流式传输可能会因此而死锁