DirectShowフィルタ間のアロケータのネゴシエーションが失敗する

私は、DirectShowソースフィルタを開発して、圧縮解除されたビデオデータをレンダリングフィルタに提供しています。 DirectShow SDKが提供するPushSourceサンプルをフィルタの基礎として使用しました。これをVideoMixingRenderer9フィルタに接続しようとしています。

私はConnectDirect()を呼び出すグラフを作成するとき:

HRESULT hr = mp_graph_builder->ConnectDirect(OutPin, InPin, &mediaType);

このコール中に、DecideBufferSize()のダウンストリームフィルタアロケータのSetPropertiesを呼び出すと、D3DERR_INVALIDCALL(0x8876086c)で失敗します。

ALLOCATOR_PROPERTIES actual;
memset(&actual,0,sizeof(actual));
hr = pAlloc->SetProperties(pRequest, &actual);

ダウンストリームフィルタでアロケータを設定するときに私のアロケータ(CBaseOutputPinによって提供されるアロケータ)を使用しようとすると、これはE_FAIL(CBaseOutputPin :: DecideAllocator)で失敗します。

hr = pPin->NotifyAllocator(*ppAlloc, FALSE);

どんな助けでも大歓迎です! ありがとう。

編集: これは、GetMediaTypeによって提供されるメディアタイプです。

VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
if (pvi == 0) 
    return(E_OUTOFMEMORY);

ZeroMemory(pvi, pMediaType->cbFormat);   
pvi->AvgTimePerFrame = m_rtFrameLength;

pMediaType->formattype = FORMAT_VideoInfo; 
pMediaType->majortype = MEDIATYPE_Video;
pMediaType->subtype = MEDIASUBTYPE_RGB24; 
pMediaType->bTemporalCompression = FALSE;
pMediaType->bFixedSizeSamples = TRUE;
pMediaType->formattype = FORMAT_VideoInfo;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = (640/128 + 1) * 128;
pvi->bmiHeader.biHeight = -480;//negative so top down..
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biBitCount = 24;
pvi->bmiHeader.biCompression = NULL;//ok if rgb else use MAKEFOURCC(...)
pvi->bmiHeader.biSizeImage  = GetBitmapSize(&pvi->bmiHeader);
pvi->bmiHeader.biClrImportant = 0;
pvi->bmiHeader.biClrUsed    = 0;        //Use max colour depth
pvi->bmiHeader.biXPelsPerMeter = 0; 
pvi->bmiHeader.biYPelsPerMeter = 0;
SetRectEmpty(&(pvi->rcSource));
SetRectEmpty(&(pvi->rcTarget));
pvi->rcSource.bottom = 480;
pvi->rcSource.right = 640;
pvi->rcTarget.bottom = 480;
pvi->rcTarget.right = 640;

pMediaType->SetType(&MEDIATYPE_Video);
pMediaType->SetFormatType(&FORMAT_VideoInfo);
pMediaType->SetTemporalCompression(FALSE);
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pMediaType->SetSubtype(&SubTypeGUID);
pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage);

and DecideBufferSize where pAlloc->SetProperties is called

HRESULT CPushPinBitmap::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest) {
    HRESULT hr;
    CAutoLock cAutoLock(CBasePin::m_pLock);

    CheckPointer(pAlloc, E_POINTER);
    CheckPointer(pRequest, E_POINTER);

    if (pRequest->cBuffers == 0) {
        pRequest->cBuffers = 2;
    }
    pRequest->cbBuffer =  480 * ( (640/128 + 1) * 128 ) * 3;

    ALLOCATOR_PROPERTIES actual;
    memset(&actual,0,sizeof(actual));
    hr = pAlloc->SetProperties(pRequest, &actual);
    if (FAILED(hr)) {
        return hr;
    }
    if (actual.cbBuffer < pRequest->cbBuffer) {
        return E_FAIL;
    }

    return S_OK;
}

定数は一時的なものです!

1

1 答え

VMR/EVRフィルタで独自のアロケータを使用する方法はありません。 DirectDraw/Direct3Dサーフェス上でサポートされています。

VMR/EVRフィルタに直接接続するには、別の戦略が必要です。アロケータは常にそれらのアロケータです。拡張ストライドをサポートする必要があります。 ビデオからのフォーマット変更の処理を参照してください。レンダラーを参照してください。

1
追加された
通常は、メディアタイプにデフォルトのストライドを提供し、VMRはストライドを更新し、動的フォーマットの変更を通知します。 VMRのAllcoatorを使用しているときのエラーはどうなりますか?
追加された 著者 Roman R.,
現在の接続メディアの種類と SetProperties コールの引数について詳しく説明しますか?
追加された 著者 Roman R.,
さて、あなたの128は何のことなのですか?標準ストライドは、必要なバイト数+ 32ビット境界までのパディングです。そこに128はありません。 24ビットRGBの場合、 cbBuffer ((3 * width)+ 3)/ 4 * 4 でなければなりません。
追加された 著者 Roman R.,
この初期設定を受け入れ、それを使って実行するか、拡張ストライドを提案します。後者は、ストリーミングを開始するとすぐに実行時に実行されます。
追加された 著者 Roman R.,
ありがとう。 VMRアロケータを使用していただければ幸いです。 VMRフィルタは、SetPropertiesの呼び出し中にQueryAcceptを呼び出しており、QueryAcceptはS_OKを返しています。私はストライドを正しく設定していると思います(GetMediaType - ((width/128)+ 1)* 128)。私は行方不明のものが他にありますか?
追加された 著者 james,
もともとGetMediaType(pMediaType-> pbFormat-> bmiHeader.biWidth)にストライドを設定しています。 VMRが(QueryAcceptを介して)CheckMediaTypeを呼び出すとき、VMRは同じ値を提供します。私は、S_OKを返すこととD3DERR_INVALIDCALLを返すSetPropertiesとの間に何が起こるのかよく分かりません。
追加された 著者 james,
完了しました。 VMRは最初は喜んでメディアタイプを受け入れますが、SetPropertiesでは失敗します。
追加された 著者 james,
ローマに感謝します。私も32ビットRGBに変更しなければなりませんでした(VMR9は最初の交換のディスプレイと同じビット深度でRGBを受け入れるだけです)。 VMRは、少なくともアロケータセッティングを受け入れます。
追加された 著者 james,