Changeset 260506 in webkit
- Timestamp:
- Apr 22, 2020 4:36:27 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r260505 r260506 1 2020-04-22 Enrique Ocaña González <eocanha@igalia.com> 2 3 [GStreamer][MSE] Youtube 'live stream'/H264 URLs fail to play, VP8/9 URLs play OK 4 https://bugs.webkit.org/show_bug.cgi?id=209119 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 Unskipped media/media-source/media-source-seek-redundant-append.html, 9 which passes now. 10 11 * platform/gtk/TestExpectations: 12 * platform/wpe/TestExpectations: 13 1 14 2020-04-21 Sergio Villar Senin <svillar@igalia.com> 2 15 -
trunk/LayoutTests/platform/gtk/TestExpectations
r260503 r260506 3326 3326 webkit.org/b/202736 [ Release ] http/wpt/cache-storage/quota-third-party.https.html [ Failure Timeout Pass ] 3327 3327 3328 webkit.org/b/206873 media/media-source/media-source-seek-redundant-append.html [ Timeout ]3329 3330 3328 webkit.org/b/206876 http/tests/security/storage-blocking-strengthened-private-browsing-plugin.html [ Timeout ] 3331 3329 -
trunk/LayoutTests/platform/wpe/TestExpectations
r260505 r260506 1500 1500 webkit.org/b/201268 accessibility/insert-newline.html [ Timeout ] 1501 1501 1502 webkit.org/b/206873 media/media-source/media-source-seek-redundant-append.html [ Timeout ]1503 1504 1502 webkit.org/b/207711 [ Debug ] fast/selectors/slow-style-sharing-with-long-cousin-list.html [ Timeout ] 1505 1503 webkit.org/b/207711 http/tests/cookies/double-quoted-value-with-semi-colon.html [ Failure Timeout ] -
trunk/Source/WebCore/ChangeLog
r260505 r260506 1 2020-04-22 Enrique Ocaña González <eocanha@igalia.com> 2 3 [GStreamer][MSE] Youtube 'live stream'/H264 URLs fail to play, VP8/9 URLs play OK 4 https://bugs.webkit.org/show_bug.cgi?id=209119 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 The fix consists of removing the initial avoiding of seeking and just 9 issuing the proper segment instead of seeking (seeks in GStreamer can't 10 be done before prerolling anyway). Appsrc doesn't make easy to emit our 11 own custom segment, so what I did was to use a segment fixer probe to 12 modify the original [0, infinity] segment issued by appsrc and use 13 a [startTime, stopTime] with proper values depending on the seek target 14 and rate. 15 16 Covered by existing tests. 17 18 * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: 19 (WebCore::checkShouldDelaySeek): Don't hold seeks on startup, when changing from READY to PAUSED. 20 (WebCore::MediaPlayerPrivateGStreamerMSE::doSeek): Refactored seek delay condition. Also, don't do a regular 21 gst_element_seek() for initial seeks, just proceed with a special case in that situation. 22 * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp: 23 (initialSeekSegmentFixerProbe): Probe that fixes the segment. 24 (webKitMediaSrcPrepareInitialSeek): Behave much like a regular seek, but also compute the right GstSegment, install 25 the segment fixer probe and setReadyForMoreSamples() on the SourceBufferPrivates. 26 * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h: 27 1 28 2020-04-21 Sergio Villar Senin <svillar@igalia.com> 2 29 -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp
r258542 r260506 242 242 } 243 243 244 static bool checkShouldDelaySeek(GstStateChangeReturn getStateResult, GstState currentState, GstState newState) 245 { 246 if (getStateResult != GST_STATE_CHANGE_ASYNC) 247 return false; 248 if (GST_STATE_TRANSITION(currentState, newState) == GST_STATE_CHANGE_PLAYING_TO_PAUSED) 249 return false; 250 if (currentState == GST_STATE_READY && newState >= GST_STATE_PAUSED) 251 return false; 252 return true; 253 } 254 244 255 bool MediaPlayerPrivateGStreamerMSE::doSeek(const MediaTime& position, float rate, GstSeekFlags seekType) 245 256 { … … 260 271 return false; 261 272 } 262 if ((getStateResult == GST_STATE_CHANGE_ASYNC 263 && !(state == GST_STATE_PLAYING && newState == GST_STATE_PAUSED)) 264 || state < GST_STATE_PAUSED 265 || m_isEndReached 266 || !m_gstSeekCompleted) { 273 274 bool shouldDelaySeek = checkShouldDelaySeek(getStateResult, state, newState); 275 if (shouldDelaySeek || m_isEndReached || !m_gstSeekCompleted) { 267 276 CString reason = "Unknown reason"; 268 if ( getStateResult == GST_STATE_CHANGE_ASYNC) {277 if (shouldDelaySeek) { 269 278 reason = makeString("In async change ", 270 279 gst_element_state_get_name(state), " --> ", … … 348 357 GST_DEBUG_OBJECT(pipeline(), "Actual seek to %s, end time: %s, rate: %f", toString(startTime).utf8().data(), toString(endTime).utf8().data(), rate); 349 358 350 // This will call notifySeekNeedsData() after some time to tell that the pipeline is ready for sample enqueuing.351 webKitMediaSrcPrepareSeek(WEBKIT_MEDIA_SRC(m_source.get()), seekTime);352 353 359 m_gstSeekCompleted = false; 354 if (!gst_element_seek(m_pipeline.get(), rate, GST_FORMAT_TIME, seekType, GST_SEEK_TYPE_SET, toGstClockTime(startTime), GST_SEEK_TYPE_SET, toGstClockTime(endTime))) { 355 webKitMediaSrcSetReadyForSamples(WEBKIT_MEDIA_SRC(m_source.get()), true); 356 m_isSeeking = false; 357 m_gstSeekCompleted = true; 358 GST_DEBUG_OBJECT(pipeline(), "doSeek(): gst_element_seek() failed, returning false"); 359 return false; 360 } 361 362 // The samples will be enqueued in notifySeekNeedsData(). 363 GST_DEBUG_OBJECT(pipeline(), "doSeek(): gst_element_seek() succeeded, returning true"); 360 if (state < GST_STATE_PAUSED) { 361 // Special case of initial seek. We set the right segment instead of a seek. 362 webKitMediaSrcPrepareInitialSeek(WEBKIT_MEDIA_SRC(m_source.get()), rate, startTime, endTime); 363 notifySeekNeedsDataForTime(seekTime); 364 GST_DEBUG("Initial seek succeeded, returning true"); 365 } else { 366 // This will call notifySeekNeedsData() after some time to tell that the pipeline is ready for sample enqueuing. 367 webKitMediaSrcPrepareSeek(WEBKIT_MEDIA_SRC(m_source.get()), seekTime); 368 369 if (!gst_element_seek(m_pipeline.get(), rate, GST_FORMAT_TIME, seekType, GST_SEEK_TYPE_SET, toGstClockTime(startTime), GST_SEEK_TYPE_SET, toGstClockTime(endTime))) { 370 webKitMediaSrcSetReadyForSamples(WEBKIT_MEDIA_SRC(m_source.get()), true); 371 m_isSeeking = false; 372 m_gstSeekCompleted = true; 373 GST_DEBUG("gst_element_seek() failed, returning false"); 374 return false; 375 } 376 // The samples will be enqueued in notifySeekNeedsData(). 377 GST_DEBUG("gst_element_seek() succeeded, returning true"); 378 } 364 379 return true; 365 380 } -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp
r251365 r260506 730 730 } 731 731 732 GstPadProbeReturn initialSeekSegmentFixerProbe(GstPad *pad, GstPadProbeInfo *info, gpointer userData) 733 { 734 GstEvent* event = GST_PAD_PROBE_INFO_EVENT(info); 735 if (GST_EVENT_TYPE(event) == GST_EVENT_SEGMENT) { 736 const GstSegment* originalSegment = nullptr; 737 const GstSegment* fixedSegment = static_cast<GstSegment*>(userData); 738 gst_event_parse_segment(event, &originalSegment); 739 GST_DEBUG("Segment at %s: %" GST_SEGMENT_FORMAT ", replaced by %" GST_SEGMENT_FORMAT, GST_ELEMENT_NAME(GST_PAD_PARENT(pad)), originalSegment, fixedSegment); 740 gst_event_replace(reinterpret_cast<GstEvent**>(&info->data), gst_event_new_segment(fixedSegment)); 741 return GST_PAD_PROBE_REMOVE; 742 } 743 return GST_PAD_PROBE_OK; 744 } 745 746 void webKitMediaSrcPrepareInitialSeek(WebKitMediaSrc* source, double rate, const MediaTime& startTime, const MediaTime& endTime) 747 { 748 GST_OBJECT_LOCK(source); 749 MediaTime seekTime = (rate >= 0) ? startTime : endTime; 750 source->priv->seekTime = seekTime; 751 source->priv->appsrcSeekDataCount = 0; 752 source->priv->appsrcNeedDataCount = 0; 753 754 for (Stream* stream : source->priv->streams) { 755 stream->appsrcNeedDataFlag = false; 756 // Don't allow samples away from the seekTime to be enqueued. 757 stream->lastEnqueuedTime = seekTime; 758 } 759 760 // The pending action will be performed in enabledAppsrcSeekData(). 761 source->priv->appsrcSeekDataNextAction = MediaSourceSeekToTime; 762 763 GUniquePtr<GstSegment> segment(gst_segment_new()); 764 segment->format = GST_FORMAT_TIME; 765 gst_segment_do_seek(segment.get(), rate, GST_FORMAT_TIME, 766 static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), 767 GST_SEEK_TYPE_SET, WebCore::toGstUnsigned64Time(startTime), 768 GST_SEEK_TYPE_SET, WebCore::toGstUnsigned64Time(endTime), nullptr); 769 770 for (Stream* stream : source->priv->streams) { 771 // This probe will fix the segment autogenerated by appsrc. 772 GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(stream->appsrc, "src")); 773 gst_pad_add_probe(pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, 774 initialSeekSegmentFixerProbe, gst_segment_copy(segment.get()), reinterpret_cast<GDestroyNotify>(gst_segment_free)); 775 stream->sourceBuffer->setReadyForMoreSamples(true); 776 } 777 778 GST_OBJECT_UNLOCK(source); 779 } 780 732 781 namespace WTF { 733 782 template <> GRefPtr<WebKitMediaSrc> adoptGRef(WebKitMediaSrc* ptr) -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h
r251365 r260506 74 74 75 75 void webKitMediaSrcPrepareSeek(WebKitMediaSrc*, const MediaTime&); 76 void webKitMediaSrcPrepareInitialSeek(WebKitMediaSrc*, double rate, const MediaTime& startTime, const MediaTime& endTime); 76 77 void webKitMediaSrcSetReadyForSamples(WebKitMediaSrc*, bool); 77 78
Note: See TracChangeset
for help on using the changeset viewer.