0

我正在尝试构建一个就地转换过滤器,该过滤器插入到解码器和渲染器之间的 DirectShow 过滤器图中,目的是显示一些随每一帧而变化的覆盖文本。

我有转换过滤器工作,但我正在努力将文本写入传递给渲染器的图像。

我有以下用于 VMR9 的测试代码。

#define HR(x) if(FAILED(x)) { return x; }

HRESULT COverlay::Transform(IMediaSample* pSample)
{
    HR(pSample->GetMediaType(&pMt));
    if (pMt)
    {
        // Media type has changed grab the bitmap header so we have frame size etc.
        if (IsEqualGUID(pMt->formattype,FORMAT_VideoInfo))
        {
            VIDEOINFOHEADER* pVInfo = (VIDEOINFOHEADER*)pMt->pbFormat;
            ::memcpy(&bmi,&(pVInfo->bmiHeader),sizeof(BITMAPINFOHEADER));
        }
        else if (IsEqualGUID(pMt->formattype,FORMAT_VideoInfo2))
        {
            VIDEOINFOHEADER2* pVInfo = (VIDEOINFOHEADER2*)pMt->pbFormat;
            ::memcpy(&bmi,&(pVInfo->bmiHeader),sizeof(BITMAPINFOHEADER));
        }
        else
        {
            return S_FALSE;
        }
        DeleteMediaType(pMt);
    }

    IVMRSurface9* pvs = NULL;
    HR(pSample->QueryInterface(IID_IVMRSurface9, (void**)&pvs));

    IDirect3DSurface9* psfc;
    HR(pvs->GetSurface(&psfc));
    IDirect3DDevice9* pdev;
    HR(psfc->GetDevice(&pdev));

    if (_font == NULL)
    {
        // Create a font we can use to draw overlay text
        D3DXFONT_DESC fontDesc = {bmi.biHeight / 18,
                0,
                400,
                0,
                false,
                DEFAULT_CHARSET,
                OUT_TT_PRECIS,
                CLIP_DEFAULT_PRECIS,
            DEFAULT_PITCH,
                L"Arial"
        };

        _fontPosition.top = 0;
        _fontPosition.left = 0;
        _fontPosition.right = abs(bmi.biWidth);
        _fontPosition.bottom = abs(bmi.biHeight);

        HR(D3DXCreateFontIndirect(pdev,&fontDesc,&_font));
    }

    HR(pdev->BeginScene());

    //RECT qtr;
    //qtr.top = 0;
    //qtr.left = 0;
    //qtr.bottom = abs(bmi.biHeight)/4;
    //qtr.right = abs(bmi.biWidth)/4;
    //HR(pdev->ColorFill(psfc,&qtr,D3DCOLOR_ARGB(0xFF,0,0,0)));

    int x = _font->DrawText(NULL,L"Hello", -1, &_fontPosition, DT_CENTER|DT_VCENTER, 0xffffffff);

    HR(pdev->EndScene());

    //HR(pdev->Present(NULL,NULL,NULL,NULL));

    pdev->Release();
    psfc->Release();
    pvs->Release();
}

使用此代码,在播放视频时,如果我移动或调整视频窗口的大小,我只会看到框架上的文本。在正常播放期间,文本不可见,当我移动或调整窗口大小时,文本仅在移动或调整大小正在进行时才可见。

我正在使用 graphedit 在 W7 64 上以 32 位模式运行图形。

我已经尝试过,无论是否调用 Present,我都遇到了同样的问题。

为小矩形着色的注释代码在所有情况下都能正常工作。

我有一个定制的源过滤器将 H264 NAL 流馈送到连接到我的覆盖过滤器(包含上面的代码)的 ffdshow 解码器,该过滤器又连接到 VMR9。

如果我使用不同的解码后帧格式,问题不会改变,我看到 NV12 和 RGB32 的症状相同。

我猜这个问题在于我缺乏与 D3D 渲染管道相关的知识。谁能告诉我如何正确显示我的文本叠加层?

谢谢

4

0 回答 0