GNOME Bugzilla – Bug 744615
d3dvideosink: D3D device lost when system screen displayed
Last modified: 2015-02-26 12:21:42 UTC
I'm using C# bindings from a WPF application, but it probably doesn't matter. The D3D device is lost and the video is no longer drawn on the screen (while the pipeline is still playing) when any of the following happens: 1. The user presses Alt+Ctr+Del to display the Windows Security Screen 2. UAC prompt is displayed 3. The power mode is set to Sleep It doesn't matter whether the video sink uses its internal video window or VideoOverlay is used. This is the debug message I get from d3dvideosink: 0:00:07.162994598 3320 14B9A4E0 WARN d3dvideosink d3dhelpers.c:1213:d3d_notify_device_lost:<d3dvideosink0> D3D Device has been lost. Cleanup up resources.. In the topic below David Hoyt wrote that "in direct3d if you've lost the d3d device object (due to another app going to fullscreen, a UAC prompt, etc.), then incoming frames won't be drawn until you reset the device and redraw." http://gstreamer-devel.966125.n4.nabble.com/How-to-temporarily-disable-drawing-in-the-directdrawsink-td2311736.html#a2312303 It seems d3dvideosink is not resetting the D3D device. It is a major show stopper for me, my application must be able to display video in all situations.
Relevant documentation from MS: https://msdn.microsoft.com/en-us/library/windows/desktop/bb174714%28v=vs.85%29.aspx Basically what should happen is that the sink should try to regain the device if it was lost, and wait forever until it can do that. Once it can, it has to reallocate all resources and reconfigure the device and then can start again.
... which is exactly what d3dhelpers.c is trying to do. It's cleaning up all resources, and then sets up a timer to periodically try to reset and init the device. Can you provide the complete debug output of d3dvideosink, is anything coming after the notification that the device is lost? There should be something about "Attempt device reset" every 500ms.
Created attachment 297082 [details] d3dvideosink log (UAC prompt displayed) Actions taken while recording this log file: 1. Video file selected, pipeline state set to Paused, first frame displayed 2. UAC prompt displayed 3. Wait a few seconds 4. Pipeline state set to Playing for 2-3 seconds and then back to Paused (no video updated on the screen) 5. Wait 30 seconds
0:00:26.056518287 6556 0DA4B508 DEBUG d3dvideosink d3dhelpers.c:1354:d3d_release_swap_chain:<d3dvideosink0> D3D surface released. Ref count: 1 Apparently we leak the surface, which is then breaking the resetting probably.
Does it work better if you set enable-last-sample=false on d3dvideosink?
No, the behaviour is exactly the same.
Found it probably. Can you test? http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=d1d31dae6d9266a6723ff42ea8fd1fe2785779dc commit d1d31dae6d9266a6723ff42ea8fd1fe2785779dc Author: Sebastian Dröge <sebastian@centricular.com> Date: Wed Feb 18 12:45:22 2015 +0200 d3dvideosink: Deactivate the fallback pool and unref the fallback buffer when resetting Otherwise we will still have a reference to the surface left, which would prevent activating the sink again later. E.g. after we lost the device. Hopefully fixes https://bugzilla.gnome.org/show_bug.cgi?id=744615
Ooops... Unfortunately my colleague didn't bring his Linux laptop today. We are trying to install Linux on another machine and build d3dvideosink, it will take a while...
Any success Ralph?
Yes, it WORKS! I'm changing the status to Resolved/Fixed. Thank you very much, that was quick :)
Thanks for testing :)
Created attachment 297362 [details] d3dvideosink log 2 (bugfix applied)
I was too fast. After some more testing I can say that the fix usually works, but not always. In the attached file you can see that a few times I played the video successfully after displaying an UAC prompt, but the last time for some reason there was an error when resetting the d3d device.
An explanation why the caps are set on the sink - I'm using gnonlin to play a sequence of files and after 4 seconds of playback a different file is displayed. Having done some testing I can say that the fix never works when playing the second or any further file, changing the file breaks the ability to reset the d3d device.
So this happens only when using the same sink again and the caps are changing? If that's true that would give a hint where to look.
Hmm, the device is lost. Then caps change. And then resetting never works. Does it also fail if caps change, and then the device gets lost?
I have done around 15 tests and resetting the d3d device fails only after changing the caps (displaying another file).
Yes, it also fails when caps change and then I display the UAC prompt.
Does setting enable-last-sample=false make a difference here? Or the following two commits? commit e36c27cd46d0720ebde82fce5865d95914b4a2fc Author: Sebastian Dröge <sebastian@centricular.com> Date: Tue Feb 24 11:19:04 2015 +0200 d3dvideosink: Don't initialize the render window swap chain while the device is lost and we're waiting for reset https://bugzilla.gnome.org/show_bug.cgi?id=744615 commit f53bc227a80cd72cb2b46f8bd6e63047e1d172d9 Author: Sebastian Dröge <sebastian@centricular.com> Date: Tue Feb 24 11:18:38 2015 +0200 d3dvideosink: Deactivate the fallback buffer pool when replacing it during caps changes https://bugzilla.gnome.org/show_bug.cgi?id=744615
Thanks, Sebastian. I'm very busy releasing other software, I'll give it a good test in the afternoon.
Doesn't work. See the attached log 3. Sequence of actions: 1. Preroll at position 0 2. Seek to position 9.066666 to start displaying a new file and change the caps 3. Display an UAC prompt 4. Play
Created attachment 297867 [details] d3dvideosink log 3 (second and third bugfix applied)
The patch from bug #745159 might fix this. At least it would be another reason why this fails :)
It WORKS! Thank you very much :)