[GStreamer] flush video sample upon DRAIN query
authorphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jun 2018 09:43:04 +0000 (09:43 +0000)
committerphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jun 2018 09:43:04 +0000 (09:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186481

Patch by Philippe Normand <philn@igalia.com> on 2018-06-11
Reviewed by Xabier Rodriguez-Calvar.

Use the appsink sink pad pad probe for both event and drain query
management. This patch is partially based on
https://github.com/WebPlatformForEmbedded/WPEWebKit/commit/d3a336523d123119fe1dd53da5d9006c92cf078c
by Enrique Ocaña González <eocanha@igalia.com>.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
(WebCore::MediaPlayerPrivateGStreamerBase::createGLAppSink):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232747 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp

index 71e9d1b..9f8c091 100644 (file)
@@ -1,3 +1,19 @@
+2018-06-11  Philippe Normand  <philn@igalia.com>
+
+        [GStreamer] flush video sample upon DRAIN query
+        https://bugs.webkit.org/show_bug.cgi?id=186481
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Use the appsink sink pad pad probe for both event and drain query
+        management. This patch is partially based on
+        https://github.com/WebPlatformForEmbedded/WPEWebKit/commit/d3a336523d123119fe1dd53da5d9006c92cf078c
+        by Enrique Ocaña González <eocanha@igalia.com>.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
+        (WebCore::MediaPlayerPrivateGStreamerBase::createGLAppSink):
+
 2018-06-11  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Replace HorizontalGeometry::width and margin with WidthAndMargin (Vertical too)
index cfeb3e0..0411058 100644 (file)
@@ -890,7 +890,12 @@ void MediaPlayerPrivateGStreamerBase::flushCurrentBuffer()
 {
     GST_DEBUG_OBJECT(pipeline(), "Flushing video sample");
     auto sampleLocker = holdLock(m_sampleMutex);
-    m_sample.clear();
+
+    // Replace by a new sample having only the caps, so this dummy sample is still useful to get the dimensions.
+    // This prevents resizing problems when the video changes its quality and a DRAIN is performed.
+    const GstStructure* info = gst_sample_get_info(m_sample.get());
+    m_sample = adoptGRef(gst_sample_new(nullptr, gst_sample_get_caps(m_sample.get()),
+        gst_sample_get_segment(m_sample.get()), info ? gst_structure_copy(info) : nullptr));
 
     {
         LockHolder locker(m_platformLayerProxy->lock());
@@ -1047,9 +1052,17 @@ GstElement* MediaPlayerPrivateGStreamerBase::createGLAppSink()
     g_signal_connect(appsink, "new-preroll", G_CALLBACK(newPrerollCallback), this);
 
     GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(appsink, "sink"));
-    gst_pad_add_probe (pad.get(), GST_PAD_PROBE_TYPE_EVENT_FLUSH, [] (GstPad*, GstPadProbeInfo* info,  gpointer userData) -> GstPadProbeReturn {
-        if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_EVENT (info)) != GST_EVENT_FLUSH_START)
-            return GST_PAD_PROBE_OK;
+    gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), [] (GstPad*, GstPadProbeInfo* info,  gpointer userData) -> GstPadProbeReturn {
+        if (info->type & GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM) {
+            if (GST_QUERY_TYPE(GST_PAD_PROBE_INFO_QUERY(info)) != GST_QUERY_DRAIN)
+                return GST_PAD_PROBE_OK;
+            GST_DEBUG("Acting upon DRAIN query");
+        }
+        if (info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH) {
+            if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_EVENT(info)) != GST_EVENT_FLUSH_START)
+                return GST_PAD_PROBE_OK;
+            GST_DEBUG("Acting upon flush-start event");
+        }
 
         auto* player = static_cast<MediaPlayerPrivateGStreamerBase*>(userData);
         player->flushCurrentBuffer();