Вядзенне перамоваў паміж размеркавальнікам Directshow фільтрамі не атрымоўваецца

Я займаюся распрацоўкай карыстацкага фільтра крыніцы Directshow забяспечыць распакаваныя відэададзеныя да візуалізацыі фільтра. Я выкарыстаў ўзор PushSource прадастаўленага Directshow SDK у якасці асновы для майго фільтра. Я спрабую падключыць да фільтра VideoMixingRenderer9.

Пры стварэнні графіка я тэлефаную ConnectDirect ():

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

але падчас гэтага выкліку, выклік SetProperties на выхадзе фільтраў размеркавальніка (у DecideBufferSize ()), трывае няўдачу з 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);

Любая дапамога будзе высока цэніцца! Дзякуючы.

EDIT: Гэта тып носьбіта забяспечваецца 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 фільтруе вам патрэбна іншая стратэгія. Размеркавальнік заўсёды іх. Вы павінны падтрымліваць пашыраныя крокі. См Handling змены фармату з відэа Renderer .

1
дададзена
Вы звычайна забяспечваеце тып носьбіта з па змаўчанні хады і VMR абновіць хаду і паведамляе вам праз дынамічная змена фармату. Што менавіта памылка пры выкарыстанні allcoator VMR ў?
дададзена аўтар Roman R., крыніца
Ці будзеце вы абнаўляць свой пост з поўнай інфармацыяй аб бягучым злучэнні тыпу носьбіта, а таксама аргументы SetProperties патэлефанаваць?
дададзена аўтар Roman R., крыніца
Добра, ну што цяпер ваш 128 ўсё аб? Стандартны крок з'яўляецца неабходнай колькасцю байт + водступаў ў 32-бітнай мяжу. Там няма 128 ёсць. Як у вас ёсць 24-бітны RGB, cbBuffer павінен быць ((3 * шырыня) + 3)/4 * 4 .
дададзена аўтар Roman R., крыніца
Ён прымае гэтую першапачатковую канфігурацыю і будзе працаваць з ёй, ці яна будзе прапаноўваць пашыраную хаду. Апошняе адбываецца ўжо падчас выканання, як толькі вы пачынаеце струменевага відэа.
дададзена аўтар Roman R., крыніца
Дзякуючы. Я рады выкарыстоўваць аллокатор VMR, калі гэта дазволіць мне. Фільтр VMR тэлефануе QueryAccept падчас выкліку SetProperties і QueryAccept вяртаецца S_OK. Я лічу, што я ўсталёўваю хаду правільна (у GetMediaType - ((шырыня/128) + 1) * 128). Ці ёсць што-небудзь яшчэ, што я не хапае?
дададзена аўтар james, крыніца
Я ўсталёўваю хаду першапачаткова ў GetMediaType (pMediaType-> pbFormat-> bmiHeader.biWidth). Калі VMR называе CheckMediaType (праз QueryAccept) яна забяспечвае тое ж значэнне. Я не ўпэўнены, што адбываецца паміж гэтым вяртаюцца S_OK і SetProperties вяртаннем D3DERR_INVALIDCALL.
дададзена аўтар james, крыніца
Гатова. VMR шчасліва прымаць тып носьбіта на пачатковым этапе, але трывае няўдачу на SetProperties.
дададзена аўтар james, крыніца
Дзякуючы Раман. Я таксама павінен быў змяніцца на 32-бітным RGB (здаецца VMR9 прымае толькі RGB у той жа бітавай глыбіні, што і дысплей ў зыходным абмене!). VMR цяпер па меншай меры, прымаючы размеркавальнік seetings.
дададзена аўтар james, крыніца