[vlc-devel] Push Model Issue
robux4 at ycbcr.xyz
Wed Jun 12 16:58:06 CEST 2019
Following the vout workshop we took some decisions regarding how the
hardware information will be pushed by the decoder with help from the
display module (decoder hint, decoder device, decoder context in reverse
I started implemented the decoder device for D3D11 and D3D9 and realized
there is a problem with D3D9/DXVA2.
For D3D9 the "decoder device" could contain either a IDirect3D9* or a
IDirect3DDevice9*. The "decoder context" definitely needs a
IDirect3DDevice9* (it uses IDirect3DDeviceManager9::ResetDevice to link
the API to get a decoder and the actual device). But to create a
IDirect3DDevice9* this cannot be done by the decoder because it needs
the HWND that will be used to render with this device (or NULL or no
display will occur). It cannot be the parent HWND (the one provided by
our vout_window_t) it has to be the one that the display module creates
internally (see the win32/window.c code).
It works as it is now because the display module creates its HWND, then
the IDirect3DDevice9* for it and it's shared with the decoder.
In push it would seem logical to pass the HWND to whoever will create
the IDirect3DDevice9*, likely the "decoder device" or the decoder (in
the "decoder context"). But the display module may be reset completely
for the same decoder, losing this HWND that the decoder is now tied to.
Closing the display module will make the decoder unusable because it
relies on the HWND that is now gone.
1/ It's possible to get around this by having the display module create
a new IDirect3DDevice9* for its HWND each time it's opened. The
IDirect3DDeviceManager9::ResetDevice() will then be reset in the
decoder, provided this new device is propagated to the decoder when it
changes. This is not very push model-like. And even then the
ResetDevice, as the name suggests, means the previous decoder handle
cannot be used anymore, including the pictures it holds. So even if it
is a push-model it would still very much depends on the display module
2/ Another option is to let the decoder handle a IDirect3DDevice9*
created with a NULL HWND and the display module have its own
IDirect3DDevice9* and share surfaces between the two. I tried this
solution but the surface coming from the decoder are copied to the
surface owned by the display. It is done transparently in the driver and
it seems to affect the performance a lot even though it's the same GPU.
So IMO this is not a viable solution even though it would be the cleanest.
I will keep investigate on option #2 but I'm running out of ideas on how
to solve the performance issue. So I wonder if it makes sense to have
the decoder depend on the display module in push to be created an
usable. This is a limitation of D3D9 where everything is tied to a HWND.
In D3D11 the resources can be shared and are only tied to a GPU.
More information about the vlc-devel