[vlc-devel] Push Model Issue

Steve Lhomme robux4 at ycbcr.xyz
Wed Jun 12 16:58:06 CEST 2019


Hi,

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 
order).

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 
lifecycle.

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 mailing list