- Revision
- 260629
- Author
- [email protected]
- Date
- 2020-04-24 02:20:41 -0700 (Fri, 24 Apr 2020)
Log Message
Merge r260506 - [GStreamer][MSE] Youtube 'live stream'/H264 URLs fail to play, VP8/9 URLs play OK
https://bugs.webkit.org/show_bug.cgi?id=209119
Reviewed by Xabier Rodriguez-Calvar.
Source/WebCore:
The fix consists of removing the initial avoiding of seeking and just
issuing the proper segment instead of seeking (seeks in GStreamer can't
be done before prerolling anyway). Appsrc doesn't make easy to emit our
own custom segment, so what I did was to use a segment fixer probe to
modify the original [0, infinity] segment issued by appsrc and use
a [startTime, stopTime] with proper values depending on the seek target
and rate.
Covered by existing tests.
* platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
(WebCore::checkShouldDelaySeek): Don't hold seeks on startup, when changing from READY to PAUSED.
(WebCore::MediaPlayerPrivateGStreamerMSE::doSeek): Refactored seek delay condition. Also, don't do a regular
gst_element_seek() for initial seeks, just proceed with a special case in that situation.
* platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp:
(initialSeekSegmentFixerProbe): Probe that fixes the segment.
(webKitMediaSrcPrepareInitialSeek): Behave much like a regular seek, but also compute the right GstSegment, install
the segment fixer probe and setReadyForMoreSamples() on the SourceBufferPrivates.
* platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h:
LayoutTests:
Unskipped media/media-source/media-source-seek-redundant-append.html,
which passes now.
* platform/gtk/TestExpectations:
* platform/wpe/TestExpectations:
Modified Paths
Diff
Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/ChangeLog (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/LayoutTests/ChangeLog 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/ChangeLog 2020-04-24 09:20:41 UTC (rev 260629)
@@ -1,3 +1,16 @@
+2020-04-22 Enrique Ocaña González <[email protected]>
+
+ [GStreamer][MSE] Youtube 'live stream'/H264 URLs fail to play, VP8/9 URLs play OK
+ https://bugs.webkit.org/show_bug.cgi?id=209119
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ Unskipped media/media-source/media-source-seek-redundant-append.html,
+ which passes now.
+
+ * platform/gtk/TestExpectations:
+ * platform/wpe/TestExpectations:
+
2020-03-18 Eugene But <[email protected]>
Test for ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChildren crash fix
Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/platform/gtk/TestExpectations (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/LayoutTests/platform/gtk/TestExpectations 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/platform/gtk/TestExpectations 2020-04-24 09:20:41 UTC (rev 260629)
@@ -2760,8 +2760,6 @@
webkit.org/b/202736 storage/indexeddb/modern/handle-user-delete.html [ Timeout ]
webkit.org/b/202736 storage/indexeddb/modern/new-database-after-user-delete.html [ Timeout ]
-webkit.org/b/206873 media/media-source/media-source-seek-redundant-append.html [ Timeout ]
-
webkit.org/b/206876 http/tests/security/storage-blocking-strengthened-private-browsing-plugin.html [ Timeout ]
#////////////////////////////////////////////////////////////////////////////////////////
Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/platform/wpe/TestExpectations (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/LayoutTests/platform/wpe/TestExpectations 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/platform/wpe/TestExpectations 2020-04-24 09:20:41 UTC (rev 260629)
@@ -1338,8 +1338,6 @@
webkit.org/b/201268 accessibility/insert-newline.html [ Timeout ]
-webkit.org/b/206873 media/media-source/media-source-seek-redundant-append.html [ Timeout ]
-
#////////////////////////////////////////////////////////////////////////////////////////
# 9. TESTS FAILING
#////////////////////////////////////////////////////////////////////////////////////////
Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog 2020-04-24 09:20:41 UTC (rev 260629)
@@ -1,3 +1,30 @@
+2020-04-22 Enrique Ocaña González <[email protected]>
+
+ [GStreamer][MSE] Youtube 'live stream'/H264 URLs fail to play, VP8/9 URLs play OK
+ https://bugs.webkit.org/show_bug.cgi?id=209119
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ The fix consists of removing the initial avoiding of seeking and just
+ issuing the proper segment instead of seeking (seeks in GStreamer can't
+ be done before prerolling anyway). Appsrc doesn't make easy to emit our
+ own custom segment, so what I did was to use a segment fixer probe to
+ modify the original [0, infinity] segment issued by appsrc and use
+ a [startTime, stopTime] with proper values depending on the seek target
+ and rate.
+
+ Covered by existing tests.
+
+ * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
+ (WebCore::checkShouldDelaySeek): Don't hold seeks on startup, when changing from READY to PAUSED.
+ (WebCore::MediaPlayerPrivateGStreamerMSE::doSeek): Refactored seek delay condition. Also, don't do a regular
+ gst_element_seek() for initial seeks, just proceed with a special case in that situation.
+ * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp:
+ (initialSeekSegmentFixerProbe): Probe that fixes the segment.
+ (webKitMediaSrcPrepareInitialSeek): Behave much like a regular seek, but also compute the right GstSegment, install
+ the segment fixer probe and setReadyForMoreSamples() on the SourceBufferPrivates.
+ * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h:
+
2020-03-25 Ting-Wei Lan <[email protected]>
[GTK] Add user agent quirk for auth.mayohr.com
Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp 2020-04-24 09:20:41 UTC (rev 260629)
@@ -241,6 +241,17 @@
}
}
+static bool checkShouldDelaySeek(GstStateChangeReturn getStateResult, GstState currentState, GstState newState)
+{
+ if (getStateResult != GST_STATE_CHANGE_ASYNC)
+ return false;
+ if (GST_STATE_TRANSITION(currentState, newState) == GST_STATE_CHANGE_PLAYING_TO_PAUSED)
+ return false;
+ if (currentState == GST_STATE_READY && newState >= GST_STATE_PAUSED)
+ return false;
+ return true;
+}
+
bool MediaPlayerPrivateGStreamerMSE::doSeek(const MediaTime& position, float rate, GstSeekFlags seekType)
{
// FIXME: Make a copy here because in some cases below it is modified. This
@@ -259,13 +270,11 @@
m_isSeeking = false;
return false;
}
- if ((getStateResult == GST_STATE_CHANGE_ASYNC
- && !(state == GST_STATE_PLAYING && newState == GST_STATE_PAUSED))
- || state < GST_STATE_PAUSED
- || m_isEndReached
- || !m_gstSeekCompleted) {
+
+ bool shouldDelaySeek = checkShouldDelaySeek(getStateResult, state, newState);
+ if (shouldDelaySeek || m_isEndReached || !m_gstSeekCompleted) {
CString reason = "Unknown reason";
- if (getStateResult == GST_STATE_CHANGE_ASYNC) {
+ if (shouldDelaySeek) {
reason = makeString("In async change ",
gst_element_state_get_name(state), " --> ",
gst_element_state_get_name(newState)).utf8();
@@ -347,20 +356,26 @@
GST_DEBUG_OBJECT(pipeline(), "Actual seek to %s, end time: %s, rate: %f", toString(startTime).utf8().data(), toString(endTime).utf8().data(), rate);
- // This will call notifySeekNeedsData() after some time to tell that the pipeline is ready for sample enqueuing.
- webKitMediaSrcPrepareSeek(WEBKIT_MEDIA_SRC(m_source.get()), seekTime);
+ m_gstSeekCompleted = false;
+ if (state < GST_STATE_PAUSED) {
+ // Special case of initial seek. We set the right segment instead of a seek.
+ webKitMediaSrcPrepareInitialSeek(WEBKIT_MEDIA_SRC(m_source.get()), rate, startTime, endTime);
+ notifySeekNeedsDataForTime(seekTime);
+ GST_DEBUG("Initial seek succeeded, returning true");
+ } else {
+ // This will call notifySeekNeedsData() after some time to tell that the pipeline is ready for sample enqueuing.
+ webKitMediaSrcPrepareSeek(WEBKIT_MEDIA_SRC(m_source.get()), seekTime);
- m_gstSeekCompleted = false;
- if (!gst_element_seek(m_pipeline.get(), rate, GST_FORMAT_TIME, seekType, GST_SEEK_TYPE_SET, toGstClockTime(startTime), GST_SEEK_TYPE_SET, toGstClockTime(endTime))) {
- webKitMediaSrcSetReadyForSamples(WEBKIT_MEDIA_SRC(m_source.get()), true);
- m_isSeeking = false;
- m_gstSeekCompleted = true;
- GST_DEBUG_OBJECT(pipeline(), "doSeek(): gst_element_seek() failed, returning false");
- return false;
+ if (!gst_element_seek(m_pipeline.get(), rate, GST_FORMAT_TIME, seekType, GST_SEEK_TYPE_SET, toGstClockTime(startTime), GST_SEEK_TYPE_SET, toGstClockTime(endTime))) {
+ webKitMediaSrcSetReadyForSamples(WEBKIT_MEDIA_SRC(m_source.get()), true);
+ m_isSeeking = false;
+ m_gstSeekCompleted = true;
+ GST_DEBUG("gst_element_seek() failed, returning false");
+ return false;
+ }
+ // The samples will be enqueued in notifySeekNeedsData().
+ GST_DEBUG("gst_element_seek() succeeded, returning true");
}
-
- // The samples will be enqueued in notifySeekNeedsData().
- GST_DEBUG_OBJECT(pipeline(), "doSeek(): gst_element_seek() succeeded, returning true");
return true;
}
Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp 2020-04-24 09:20:41 UTC (rev 260629)
@@ -729,6 +729,55 @@
GST_OBJECT_UNLOCK(source);
}
+GstPadProbeReturn initialSeekSegmentFixerProbe(GstPad *pad, GstPadProbeInfo *info, gpointer userData)
+{
+ GstEvent* event = GST_PAD_PROBE_INFO_EVENT(info);
+ if (GST_EVENT_TYPE(event) == GST_EVENT_SEGMENT) {
+ const GstSegment* originalSegment = nullptr;
+ const GstSegment* fixedSegment = static_cast<GstSegment*>(userData);
+ gst_event_parse_segment(event, &originalSegment);
+ GST_DEBUG("Segment at %s: %" GST_SEGMENT_FORMAT ", replaced by %" GST_SEGMENT_FORMAT, GST_ELEMENT_NAME(GST_PAD_PARENT(pad)), originalSegment, fixedSegment);
+ gst_event_replace(reinterpret_cast<GstEvent**>(&info->data), gst_event_new_segment(fixedSegment));
+ return GST_PAD_PROBE_REMOVE;
+ }
+ return GST_PAD_PROBE_OK;
+}
+
+void webKitMediaSrcPrepareInitialSeek(WebKitMediaSrc* source, double rate, const MediaTime& startTime, const MediaTime& endTime)
+{
+ GST_OBJECT_LOCK(source);
+ MediaTime seekTime = (rate >= 0) ? startTime : endTime;
+ source->priv->seekTime = seekTime;
+ source->priv->appsrcSeekDataCount = 0;
+ source->priv->appsrcNeedDataCount = 0;
+
+ for (Stream* stream : source->priv->streams) {
+ stream->appsrcNeedDataFlag = false;
+ // Don't allow samples away from the seekTime to be enqueued.
+ stream->lastEnqueuedTime = seekTime;
+ }
+
+ // The pending action will be performed in enabledAppsrcSeekData().
+ source->priv->appsrcSeekDataNextAction = MediaSourceSeekToTime;
+
+ GUniquePtr<GstSegment> segment(gst_segment_new());
+ segment->format = GST_FORMAT_TIME;
+ gst_segment_do_seek(segment.get(), rate, GST_FORMAT_TIME,
+ static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
+ GST_SEEK_TYPE_SET, WebCore::toGstUnsigned64Time(startTime),
+ GST_SEEK_TYPE_SET, WebCore::toGstUnsigned64Time(endTime), nullptr);
+
+ for (Stream* stream : source->priv->streams) {
+ // This probe will fix the segment autogenerated by appsrc.
+ GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(stream->appsrc, "src"));
+ gst_pad_add_probe(pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+ initialSeekSegmentFixerProbe, gst_segment_copy(segment.get()), reinterpret_cast<GDestroyNotify>(gst_segment_free));
+ stream->sourceBuffer->setReadyForMoreSamples(true);
+ }
+
+ GST_OBJECT_UNLOCK(source);
+}
+
namespace WTF {
template <> GRefPtr<WebKitMediaSrc> adoptGRef(WebKitMediaSrc* ptr)
{
Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h (260628 => 260629)
--- releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h 2020-04-24 09:20:34 UTC (rev 260628)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h 2020-04-24 09:20:41 UTC (rev 260629)
@@ -73,6 +73,7 @@
void webKitMediaSrcSetMediaPlayerPrivate(WebKitMediaSrc*, WebCore::MediaPlayerPrivateGStreamerMSE*);
void webKitMediaSrcPrepareSeek(WebKitMediaSrc*, const MediaTime&);
+void webKitMediaSrcPrepareInitialSeek(WebKitMediaSrc*, double rate, const MediaTime& startTime, const MediaTime& endTime);
void webKitMediaSrcSetReadyForSamples(WebKitMediaSrc*, bool);
G_END_DECLS