Aleksoid1978 / VideoRenderer

Внешний видео-рендерер
GNU General Public License v3.0
997 stars 110 forks source link

Discussions on support passing the OSD as D3D surface to MPC VR. #86

Closed ternam closed 1 year ago

ternam commented 1 year ago

During a very popular DVB watching software adaptation of MPC VR, it was found there's issue on full OSD support with transparency. It seems currently MPC VR does not support passing the OSD as D3D surface, then it needs cumbersome conversion and calculation to pass OSD as GDI bitmap and the result is not perfect so far. Detailed discussion's here: https://www.dvbviewer.tv/forum/topic/64639-mpc-video-renderer-support/

I'm not the software author, just to query if MPC VR can support D3D surface OSD, if not, will it be added in a later release. Thanks!

Aleksoid1978 commented 1 year ago

The plans do not support this kind of OSD, at least because the renderer supports DX9 / DX11, which means that if a D3D surface is used for OSD, either refuse processing if it does not match DX9 / DX11, or do a DX9 <-> DX11 conversion .

The current OSD support algorithm is quite normal.

ternam commented 1 year ago

or do a DX9 <-> DX11 conversion .

Why not? The Microsoft specifications allow passing a IDirect3DSurface9 interface pointer as IMFVideoMixerBitmap::SetAlphaBitmap parameter, so if MPC VR implements this interface, it should work as specified. If MPC VR prefers a proprietary solution, it should rather offer a proprietary interface for it, plus documentation how to use it, like MadVR does

Anyway, there is another major drawback of IMFVideoMixerBitmap::SetAlphaBitmap (also concerning the standard EVR). It only updates the OSD while video is playing. In pause mode it doesn't. From the user's point of view the OSD freezes when video stops. Changes like a moving selection bar in a menu are not displayed anymore. That was one of the main reasons for developing a custom EVR based video renderer and using it in DVBViewer. It still displays OSD changes if video stops for some reason (= no new pictures are received by the video renderer).

For other video renderers, particularly the Microsoft standard renderers, a dirty work-around had to be implemented, and unfortunately it must also be applied to MPC VR: If the user switches to pause mode, DVBViewer quickly retrieves a screenshot from the video renderer, switches over to its own OSD output, that normally is only used if no video is playing, and uses the screenshot as background picture for it. This hides (covers) the original video renderer output with the frozen OSD completely, until playback starts again.

However, this work-around is difficult to organize. And it doesn't work if video suddenly stops for reasons outside DVBViewer, e.g. TV signal loss. If you switch to a channel that doesn't work, the OSD doesn't work either. So it has to be stated that IMFVideoMixerBitmap::SetAlphaBitmap is not really suitable for TV applications, particularly when they are completely controlled via OSD in a HTPC environment. It is acceptable if the normal DVBViewer UI (menu bar etc.) is used, though.

BTW: This problem doesn't exist with MadVR. When it came to implementing MadVR support in DVBViewer, Madshi was willing to handle the issue and modified the (proprietary) IMadVROsdServices interface in a way that allowed for keeping the OSD alive even if video stops.

Aleksoid1978 commented 1 year ago

Personally, I'm not at all interested in this. But if someone decides to implement this - please, I will not mind. Well, and another very important thing is that no players support IDirect3DSurface9 interface pointer as IMFVideoMixerBitmap::SetAlphaBitmap parameter, so there is nothing to even check / debug the development.

As for changing the OSD on pause - all this is possible in MPC VR, you just need to send it a command to draw, for this there is an IExFilterConfig interface. Let the DVBViewer developer figure it out.