在Directshow过滤器之间协商分配器失败

时间:2011-10-28 11:51:21

标签: 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);

和DecideBufferSize,其中调用了pAlloc-> SetProperties

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 个答案:

答案 0 :(得分:1)

您无法使用自己的分配器和VMR / EVR过滤器。他们只是坚持自己,而后者又支持DirectDraw / Direct3D表面。

要直接连接到VMR / EVR过滤器,您需要采用不同的策略。分配器总是他们的。您需要支持扩展步幅。请参阅Handling Format Changes from the Video Renderer