如何使用IVMRSurface9在VMR9 IDirect3DSurface9上绘制文本

时间:2013-03-19 17:15:53

标签: windows visual-c++ video directshow directx-9

我正在尝试构建一个就地变换过滤器,它插入到解码器和渲染器之间的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解码器,该解码器连接到我的Overlay滤波器(包含上面的代码),然后连接到VMR9。

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

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

由于

0 个答案:

没有答案