Painting frames while media session is paused

2019-09-19 07:34发布

问题:

I'm working on a custom video player using the Media Foundation framework. Currently, I can play, pause, stop or change the rate of the playback using an IMFMediaSession. I can also retrieve a single frame using an IMFSourceReader.

I am currently able to render a frame (IMFSample) to a window area (a HWND) but only when the media session is stopped. My goal is to be able to render a frame while the media session is paused. (= doing frame-stepping using a source reader and not the media session)

I'm using GetDC, CreateBitmap, SelectObject and BitBlt to render my frame. I tried using directd3d interfaces to fill it with a solid color (I'm really new to direct3d so followed a basic tutorial) but it didn't work. Here is what I did : retrieving an IDirect3DDeviceManager9 with MR_VIDEO_ACCELERATION_SERVICE, doing OpenDeviceHandle, LockDevice, Clear, Begin/EndScene and Present.

None of these calls fail but I suspect the EVR is still painting the last frame. So basically, I want the EVR to stop repainting its frame when I want and of course, I need to re-enable its painting process.

Any idea how to do that ? Thanks

回答1:

I finally got it working. If you're interested, do the following:

  • retrieve IMFVideoDisplayControl and IMFVideoMixerBitmap from the media session using MFGetService
  • set up MFVideoAlphaBitmap structure and feed it to IMFVideoMixerBitmap::SetAlphaBitmap (there is a working example at the dedicated MSDN page)
  • call IMFVideoDisplayControl::RepaintVideo to update the output

To hide the previous content, don't set the alpha so that it's opaque. Call IMFVideoMixerBitmap::ClearAlphaBitmap to get the previous content back.

And voilà !