Directshow filtreleri arasındaki bir ayırıcıyı görüşme başarısız oluyor

Bir işleme filtresine sıkıştırılmış video verisi sağlamak için özel bir Directshow kaynak filtresi geliştiriyorum. Filtrelerim için Directshow SDK tarafından sağlanan PushSource örneğini kullandım. Bunu bir VideoMixingRenderer9 filtresine bağlamaya çalışıyorum.

Grafiği oluştururken ConnectDirect() öğesini arıyorum:

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

ancak bu çağrı sırasında, SetProperties alt akış süzgeç ayırıcısı (DecideBufferSize ()), çağrısı D3DERR_INVALIDCALL (0x8876086c) ile başarısız:

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

Alt akış filtresindeki ayırıcıyı ayarlarken (CBaseOutputPin tarafından sağlanan) allocator'umu kullanmaya çalışırsam, bu E_FAIL ile başarısız olur (CBaseOutputPin :: DecideAllocator'da)

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

Herhangi bir yardım çok takdir edilecektir! Teşekkürler.

DÜZENLE: Bu GetMediaType tarafından sağlanan ortam türü

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

Sabitler sadece geçicidir!

1

1 cevap

VMR/EVR filtreleriyle kendi ayırıcınızı kullanmanın bir yolu yoktur. Sadece kendi başlarına ısrar ediyorlar, bu da DirectDraw/Direct3D yüzeylere destekleniyor.

VMR/EVR filtrelere doğrudan bağlanmak için farklı bir stratejiye ihtiyacınız vardır. Allocator her zaman onlarındır. Genişletilmiş adımları desteklemeniz gerekiyor. Videodan Biçim Değişikliklerini İşleme bakın renderer .

1
katma
Normalde varsayılan adımda bir medya türü sağlıyorsunuz ve VMR adımı güncelleyecek ve dinamik biçim değişikliği ile sizi bilgilendirecek. VMR allcoator kullanırken hata tam olarak nedir?
katma yazar Roman R., kaynak
Yayınınızı geçerli bağlantı medya türü ve SetProperties çağrısına ilişkin argümanlar hakkında tüm ayrıntılarla günceller misiniz?
katma yazar Roman R., kaynak
Tamam, peki şimdi 128’in ne hakkında? Standart adım, istenen bit sayısı + 32 bitlik sınırlamadır. Orada 128 tane yok. 24 bit RGB'ye sahip olduğunuzdan, cbBuffer ((3 * width) + 3)/4 * 4 olmalıdır.
katma yazar Roman R., kaynak
Bu ilk yapılandırmayı kabul eder ve onunla çalışır veya uzatılmış adım önerecektir. İkincisi, akışa başladığınız anda çalışma zamanı üzerinde zaten gerçekleşir.
katma yazar Roman R., kaynak
Teşekkürler. İzin verirseniz VMR ayırıcısını kullanmaktan mutluluk duyarım. VMR filtresi, SetProperties çağrısı sırasında QueryAccept'i çağırıyor ve QueryAccept, S_OK'u döndürüyor. Adımı doğru olarak ayarlıyorum (GetMediaType - ((width/128) + 1) * 128). Kaybettiğim başka bir şey var mı?
katma yazar james, kaynak
Adımı başlangıçta GetMediaType (pMediaType-> pbFormat-> bmiHeader.biWidth) olarak ayarlıyorum. VMR, CheckMediaType (QueryAccept aracılığıyla) çağırdığında, aynı değeri sağlar. D3DERR_INVALIDCALL dönen dönen S_OK ve SetProperties arasında ne olduğundan emin değilim.
katma yazar james, kaynak
Bitti. VMR, başlangıçta medya türünü kabul ediyor ancak SetProperties'te başarısız oluyor.
katma yazar james, kaynak
Teşekkürler Roman. Ayrıca 32 bit RGB'ye geçmek zorunda kaldım (VMR9 sadece RGB'yi başlangıçtaki ekran ile aynı bit derinliğinde kabul ediyor gibi görünüyor). VMR şimdi en azından allocator seetings kabul ediyor.
katma yazar james, kaynak