Bug 190050

Summary: [GStreamer][MSE] Replay hits an assertion
Product: WebKit Reporter: Alicia Boya García <aboya>
Component: WebKitGTKAssignee: Enrique Ocaña <eocanha>
Status: RESOLVED FIXED    
Severity: Normal CC: bugs-noreply, eocanha
Priority: P2    
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   

Description Alicia Boya García 2018-09-27 13:15:22 PDT
How to reproduce:

1. Have a simple <video> with a MSE source.
2. Play it.
3. Wait for it to finish.
4. Click the play button in the media player controls.

ASSERT(!m_private);
#0  WTFCrash () at ../../Source/WTF/wtf/Assertions.cpp:255
#1  0x00007fd7f9da9d57 in WebCore::MediaSource::setPrivateAndOpen (this=0x7fd763c152b0, mediaSourcePrivate=...) at ../../Source/WebCore/Modules/mediasource/MediaSource.cpp:106
#2  0x00007fd7fb77060f in WebCore::MediaSourceGStreamer::open (mediaSource=..., playerPrivate=...) at ../../Source/WebCore/platform/graphics/gstreamer/mse/MediaSourceGStreamer.cpp:55
#3  0x00007fd7fb766b2a in WebCore::MediaPlayerPrivateGStreamerMSE::sourceSetup (this=0x7fd7893c2000, sourceElement=0xf744d0)
    at ../../Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:484
#4  0x00007fd7fb73241a in WebCore::MediaPlayerPrivateGStreamer::sourceSetupCallback (player=0x7fd7893c2000, sourceElement=0xf744d0)
    at ../../Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:1723
#5  0x00007fd7dd43503e in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6  0x00007fd7dd4349ff in ffi_call () at ../src/x86/ffi64.c:525
#7  0x00007fd7e438cf39 in g_cclosure_marshal_generic () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gclosure.c:1490
#8  0x00007fd7e438c76d in g_closure_invoke () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gclosure.c:804
#9  0x00007fd7e439eb43 in signal_emit_unlocked_R () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gsignal.c:3635
#10 0x00007fd7e43a7a1e in g_signal_emit_valist () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gsignal.c:3391
#11 0x00007fd7e43a80c2 in g_signal_emit () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gsignal.c:3447
#12 0x00007fd75d4abd85 in notify_source_cb (uridecodebin=0x155eef0, pspec=0x15065f0, group=0x15177c8) at ../subprojects/gst-plugins-base/gst/playback/gstplaybin2.c:5164
#13 0x00007fd7e438c76d in g_closure_invoke () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gclosure.c:804
#14 0x00007fd7e439eb43 in signal_emit_unlocked_R () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gsignal.c:3635
#15 0x00007fd7e43a7a1e in g_signal_emit_valist () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gsignal.c:3391
#16 0x00007fd7e43a80c2 in g_signal_emit () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gsignal.c:3447
#17 0x00007fd7e4390a94 in g_object_dispatch_properties_changed () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gobject.c:1080
#18 0x00007fd7e6994b29 in gst_object_dispatch_properties_changed (object=0x155eef0, n_pspecs=1, pspecs=0x7ffd007bc6c8) at ../subprojects/gstreamer/gst/gstobject.c:430
#19 0x00007fd7e4392deb in g_object_notify_by_spec_internal () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gobject.c:1173
#20 g_object_notify () at /webkit/WebKitBuild/DependenciesGTK/Source/glib-2.54.2/gobject/gobject.c:1221
#21 0x00007fd75d485a13 in setup_source (decoder=0x155eef0) at ../subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c:2200
#22 0x00007fd75d487b60 in gst_uri_decode_bin_change_state (element=0x155eef0, transition=GST_STATE_CHANGE_READY_TO_PAUSED) at ../subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c:2812
#23 0x00007fd7e69ce36d in gst_element_change_state (element=0x155eef0, transition=GST_STATE_CHANGE_READY_TO_PAUSED) at ../subprojects/gstreamer/gst/gstelement.c:2953
#24 0x00007fd7e69ce0fd in gst_element_set_state_func (element=0x155eef0, state=GST_STATE_PAUSED) at ../subprojects/gstreamer/gst/gstelement.c:2907
#25 0x00007fd7e69cdcf9 in gst_element_set_state (element=0x155eef0, state=GST_STATE_PAUSED) at ../subprojects/gstreamer/gst/gstelement.c:2808
#26 0x00007fd75d4acaec in activate_group (playbin=0x1517340, group=0x15177c8, target=GST_STATE_PAUSED) at ../subprojects/gst-plugins-base/gst/playback/gstplaybin2.c:5406
#27 0x00007fd75d4ad958 in setup_next_source (playbin=0x1517340, target=GST_STATE_PAUSED) at ../subprojects/gst-plugins-base/gst/playback/gstplaybin2.c:5629
#28 0x00007fd75d4ae0b5 in gst_play_bin_change_state (element=0x1517340, transition=GST_STATE_CHANGE_READY_TO_PAUSED) at ../subprojects/gst-plugins-base/gst/playback/gstplaybin2.c:5759
#29 0x00007fd7e69ce36d in gst_element_change_state (element=0x1517340, transition=GST_STATE_CHANGE_READY_TO_PAUSED) at ../subprojects/gstreamer/gst/gstelement.c:2953
#30 0x00007fd7e69ce0fd in gst_element_set_state_func (element=0x1517340, state=GST_STATE_PLAYING) at ../subprojects/gstreamer/gst/gstelement.c:2907
#31 0x00007fd7e69cdcf9 in gst_element_set_state (element=0x1517340, state=GST_STATE_PLAYING) at ../subprojects/gstreamer/gst/gstelement.c:2808
#32 0x00007fd7fb72b29e in WebCore::MediaPlayerPrivateGStreamer::changePipelineState (this=0x7fd7893c2000, newState=GST_STATE_PLAYING)
    at ../../Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:402
#33 0x00007fd7fb76507e in WebCore::MediaPlayerPrivateGStreamerMSE::changePipelineState (this=0x7fd7893c2000, newState=GST_STATE_PLAYING)
    at ../../Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:216
#34 0x00007fd7fb72b42c in WebCore::MediaPlayerPrivateGStreamer::play (this=0x7fd7893c2000) at ../../Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:439
#35 0x00007fd7fad6178f in WebCore::MediaPlayer::play (this=0x7fd763c239c0) at ../../Source/WebCore/platform/graphics/MediaPlayer.cpp:548
#36 0x00007fd7fa698e94 in WebCore::HTMLMediaElement::updatePlayState (this=0x7fd763400778, updateState=WebCore::HTMLMediaElement::UpdateState::Synchronously)
    at ../../Source/WebCore/html/HTMLMediaElement.cpp:5413
#37 0x00007fd7fa6928a8 in WebCore::HTMLMediaElement::playInternal (this=0x7fd763400778) at ../../Source/WebCore/html/HTMLMediaElement.cpp:3619
#38 0x00007fd7fa6925a0 in WebCore::HTMLMediaElement::play (this=0x7fd763400778, promise=...) at ../../Source/WebCore/html/HTMLMediaElement.cpp:3526
#39 0x00007fd7f94f349d in WebCore::jsHTMLMediaElementPrototypeFunctionPlayBody (state=0x7ffd007bce80, castedThis=0x7fd788160040, promise=..., throwScope=...)
    at DerivedSources/WebCore/JSHTMLMediaElement.cpp:1532
#40 0x00007fd7f94fc276 in WebCore::IDLOperationReturningPromise<WebCore::JSHTMLMediaElement>::<lambda(JSC::ExecState&, WTF::Ref<WebCore::DeferredPromise, WTF::DumbPtrTraits<WebCore::DeferredPromise> >&&)>::operator()(JSC::ExecState &, WTF::Ref<WebCore::DeferredPromise, WTF::DumbPtrTraits<WebCore::DeferredPromise> > &&) const (this=0x7ffd007bcda0, state=..., promise=...)
    at ../../Source/WebCore/bindings/js/JSDOMOperationReturningPromise.h:52
Comment 1 Enrique Ocaña 2018-10-02 03:53:21 PDT
The assert happens when you manually click "play" after the test has finished. It happens because the finish (EOS) of the video after the test sets the playback pipeline to READY, destroying almost all the elements. On the second playback (manual one), the pipeline is recreated and the "source-setup" signal ends up triggering MediaSource::setPrivateAndOpen() a second time, and the assert checks that it can only happen a single time. A second empty WebKitMediaSource is created when the second playback begins, and it's misconfigured (no player private pointer, no appsrcs linked to SourceBuffers). I need to find a way to re-create the Streams when WebKitMediaSource is re-created.
Comment 2 Enrique Ocaña 2018-10-05 02:21:13 PDT
I've coded a way to recreate the Streams and re-attach them on second playback but things still aren't working as they should, because nobody tries to put the pipeline on PAUSED or PLAYING the second time and the elements aren't in the same state as they were during the first playback. Debugged where does the change to PAUSED/PLAYING comes from the first time and why it doesn't happen on the second time.

Added code to put the playback pipeline automatically in PAUSED the second time, but SourceBuffer isn't aware that it has to enqueue samples. Added code to reenqueue samples, but the state change doesn't complete.
Comment 3 Alicia Boya García 2019-08-29 09:27:00 PDT
Fixed by https://bugs.webkit.org/show_bug.cgi?id=199719