0

I'm trying to build an in place transform filter that is inserted into a DirectShow filter graph between the decoder and the renderer for the purpose of displaying some overlay text that changes with every frame.

I have the transform filter working but I am struggling to write text onto the image that is passed through to the renderer.

I have the following test code for use with 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();
}

Using this code, while the video is playing I only see the text on the frame if I move or re-size the video window. During normal playback the text is not visible, when I move or re-size the window the text becomes visible only while the move or re-size is in progress.

I am using graphedit to run the graph in 32 bit mode on W7 64.

I have tried this with and without the call to Present and I get the same problem.

The commented code that colours a small rectangle works correctly in all cases.

I have a bespoke source filter feeding an H264 NAL Stream to an ffdshow decoder that is connected to my Overlay filter (contains the code above) which is in turn connected to the VMR9.

The problem does not change if I use different post decode frame formats, I see the same symptoms for both NV12 and RGB32.

I'm guessing this problem lies in my lack of knowledge relating to the D3D rendering pipeline. Can any one tell me how to get my text overlay displayed correctly?

Thanks

Roman R.
  • 68,205
  • 6
  • 94
  • 158
C Hall
  • 175
  • 2
  • 15
  • Does `ColorFill` (commented) work? You are to prepare surface here, without actual visualization. You should rather implement custom allocator/presenter if you wan to work with surfaces directly, rather than media sample buffers. – Roman R. Mar 19 '13 at 18:59
  • ColoFill does work in all cases. I have read about custom allocator/presenter and looked at the SDK vmr9allocator sample. This seemed like a smaller amount of work. Do you think this can be made to work? If not I will continue with the vmr9allocator sample. Thanks for your help. – C Hall Mar 19 '13 at 23:04
  • OK, the reason I asked about `ColorFill` is that it changes surface `psfc`. This looks good for me. `DrawText` however is not working with surface at all and this is not OK for me because it is surface which is important. – Roman R. Mar 19 '13 at 23:15
  • Is there a way of drawing text to a surface? I just need to write a string onto the surface to provide overlay data. – C Hall Mar 20 '13 at 18:17

0 Answers0