[vlc-devel] Push Model Issue

Steve Lhomme robux4 at ycbcr.xyz
Thu Jun 13 09:01:56 CEST 2019

On 2019-06-12 16:58, Steve Lhomme wrote:
> 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.

"La nuit porte conseil"

It seems that we can create a IDirect3DDevice9 with either a NULL or 
GetDesktopWindow() HWND in all cases. The IDirect3DDevice9::Present() 
can override the HWND it's supposed to render to. So we can use the 
display HWND only there and always use NULL or GetDesktopWindow() for 
all IDirect3DDevice9. It should be created before the display module is 
created, that would be the "decoder device" as it's currently done.

More information about the vlc-devel mailing list