1

CTransformFilter から派生したカスタム ビデオ変換フィルターに取り組んでいます。メディア サンプルの余分な内部バッファリング、出力サンプルのキューイング、または動的なフォーマット変更など、DirectShow 用語で異常なことは何もしません。

再生を押すと、エンド ツー エンドで接続されたフィルターの 2 つのインスタンス (最初の出力が 2 番目の入力に接続されている) を含むグラフ編集のグラフがハングします。グラフは、::Transform メソッドのオーバーライド内でぶら下がっていません。2 番目のフィルター インスタンスは、ビデオ レンダラーに直接接続されていません。

2 つのフィルターの間にカラー コンバーターが挿入されている場合、この問題は発生しません。要求されたバッファ (ALLOCATOR_PROPERTIES::cBuffers) の数を 1 から 3 に増やすと、問題はなくなります。元の DecideBufferSize オーバーライドは以下にあり、他の多くのサンプル DirectShow フィルター コードに似ています。

DirectShow フィルター (変換またはその他) で要求されたバッファーの数を設定するための堅牢なポリシーは何ですか? 最新の要件に対して 1 つのバッファーを要求するコードは時代遅れですか? 私の問題はバッファーが少なすぎるのでしょうか、それともバッファーの数を増やして別の問題を隠しているのでしょうか?

    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;
}
4

1 に答える 1

2

バッファーの量に関する特定のポリシーはありませんが、バッファーの固定数がサンプルレートを制御する方法であることを確実に認識しておく必要があります。すべてのバッファーが使用中の場合、別のバッファーを要求すると、そのようなバッファーが使用可能になるまで実行がブロックされます。

つまり、コードが特定の目的でバッファー参照を保持している場合は、自分自身をロックしないように、それぞれの量を割り当てる必要があります。たとえば、最後のメディアサンプル参照を内部に保持し、たとえば再送信できるようにし、他のメディアサンプルを配信できるようにしたい場合は、アロケータに少なくとも2つのバッファが必要です。

出力ピンは通常、アロケータの選択と設定を担当します。使用するアロケータが通知された場合、入力でプロパティを確認および更新する必要がある場合があります。アロケータを共有する場合のインプレース変換フィルターでは、要件が満たされていることを確認するために追加のチェックが必要になる場合があります。

  • DMO Wrapper Filter(少なくとも時々)1つのバッファのみでアロケータを使用し、まだ良好な状態にあります
  • オーディオの場合、再生用にデータをキューに入れるため、通常はより多くのバッファがあります
  • コードに参照リークがあり、メディアサンプルポインタを解放しない場合、これが原因でストリーミングがロックされなくなる可能性があります
于 2012-06-22T19:07:14.253 に答える