2012-06-22 43 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使用(至少有時)僅具有一個緩衝分配器並且仍然在良好信譽
  • 與音頻你通常有多種緩衝液,因爲你排隊播放
  • 數據如果在有一個參考泄漏您的代碼,並且您不釋放媒體樣本指針,那麼您的流式傳輸可能會因此而死鎖