Changeset 284711 in webkit
- Timestamp:
- Oct 22, 2021, 1:22:52 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/glib/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/mediasource/MediaSource.cpp (modified) (1 diff)
-
Source/WebCore/platform/graphics/SourceBufferPrivate.h (modified) (1 diff)
-
Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h (modified) (1 diff)
-
Source/WebCore/platform/graphics/gstreamer/MediaSampleGStreamer.cpp (modified) (1 diff)
-
Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r284709 r284711 1 2021-10-22 Alicia Boya García <aboya@igalia.com> 2 3 [MSE][GStreamer] Honor MP4 edit lists, bis 4 https://bugs.webkit.org/show_bug.cgi?id=231019 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 Update expectations for mediasource-remove.html in the GStreamer 9 ports, as a couple subtests get fixed. 10 11 * platform/glib/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt: 12 1 13 2021-10-22 Chris Dumez <cdumez@apple.com> 2 14 -
trunk/LayoutTests/platform/glib/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt
r284087 r284711 12 12 PASS Test remove with a start at the duration. 13 13 PASS Test remove transitioning readyState from 'ended' to 'open'. 14 FAIL Test removing all appended data. assert_equals: Initial buffered range. expected "{ [0.095, 6.548) }" but got "{ [0.000, 6.548) }" 15 FAIL Test removing beginning of appended data. assert_equals: Initial buffered range. expected "{ [0.095, 6.548) }" but got "{ [0.000, 6.548) }" 16 FAIL Test removing the middle of appended data. assert_equals: Initial buffered range. expected "{ [0.095, 6.548) }" but got "{ [0.000, 6.548) }"17 FAIL Test removing the end of appended data. assert_equals: Initial buffered range. expected "{ [0.095, 6.548) }" but got "{ [0.000, 6.548) }"14 PASS Test removing all appended data. 15 PASS Test removing beginning of appended data. 16 FAIL Test removing the middle of appended data. assert_equals: Buffered ranges after remove(). expected "{ [0.095, 0.997) [3.298, 6.548) }" but got "{ [0.095, 0.975) [3.298, 6.548) }" 17 FAIL Test removing the end of appended data. assert_equals: Buffered ranges after remove(). expected "{ [0.095, 1.022) }" but got "{ [0.095, 0.995) }" 18 18 -
trunk/Source/WebCore/ChangeLog
r284694 r284711 1 2021-10-22 Alicia Boya García <aboya@igalia.com> 2 3 [MSE][GStreamer] Honor MP4 edit lists, bis 4 https://bugs.webkit.org/show_bug.cgi?id=231019 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 This patch takes into consideration the GstSegment attached to a 9 sample to offset the PTS and DTS. This ensures accurate timestamps are 10 obtained for MP4 files containing edit lists (commonly necessary for 11 files containing video with B frames to have PTS starting at zero). 12 13 Before this was implemented, a workaround was in place based on a 14 heuristic (DTS = 0 && PTS > 0 && PTS < 0.1). The workaround is 15 preserved for the sake of content without proper edit lists, but 16 any edit list takes preference. 17 18 The time fudge factor has been modified from 0.083 seconds up to 19 0.100 seconds to accomodate the size of the empty edit in test.mp4 20 used by Web Platform Tests. 21 22 This test fixes improves expectation results and fixes two subtests in 23 imported/w3c/web-platform-tests/media-source/mediasource-remove.html. 24 25 This is a reworked version that avoids using gst_sample_set_buffer() 26 which is not available on GStreamer 1.14, and fixes an issue where 27 frames that would get a negative DTS were not being enqueued properly. 28 29 * Modules/mediasource/MediaSource.cpp: 30 (WebCore::MediaSource::currentTimeFudgeFactor): 31 * platform/graphics/SourceBufferPrivate.h: 32 (WebCore::SourceBufferPrivate::timeFudgeFactor const): 33 * platform/graphics/gstreamer/GStreamerCommon.h: 34 (WebCore::toGstClockTime): 35 * platform/graphics/gstreamer/MediaSampleGStreamer.cpp: 36 (WebCore::MediaSampleGStreamer::MediaSampleGStreamer): 37 * platform/graphics/gstreamer/mse/AppendPipeline.cpp: 38 (WebCore::bufferTimeToStreamTime): 39 (WebCore::AppendPipeline::appsinkNewSample): 40 1 41 2021-10-22 Alex Christensen <achristensen@webkit.org> 2 42 -
trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp
r284087 r284711 324 324 const MediaTime& MediaSource::currentTimeFudgeFactor() 325 325 { 326 // Allow hasCurrentTime() to be off by as much as the length of two 24fps video frames327 static NeverDestroyed<MediaTime> fudgeFactor( 2002, 24000);326 // Allow hasCurrentTime() to be off by as much as 100ms. 327 static NeverDestroyed<MediaTime> fudgeFactor(1, 10); 328 328 return fudgeFactor; 329 329 } -
trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.h
r284087 r284711 151 151 // The following method should never be called directly and be overridden instead. 152 152 WEBCORE_EXPORT virtual void append(Vector<unsigned char>&&); 153 virtual MediaTime timeFudgeFactor() const { return { 2002, 24000}; }153 virtual MediaTime timeFudgeFactor() const { return { 1, 10 }; } 154 154 virtual bool isActive() const { return false; } 155 155 virtual bool isSeeking() const { return false; } -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h
r281440 r284711 81 81 inline GstClockTime toGstClockTime(const MediaTime &mediaTime) 82 82 { 83 if (mediaTime.isInvalid()) 84 return GST_CLOCK_TIME_NONE; 85 if (mediaTime < MediaTime::zeroTime()) 86 return 0; 83 87 return static_cast<GstClockTime>(toGstUnsigned64Time(mediaTime)); 84 88 } -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaSampleGStreamer.cpp
r284368 r284711 73 73 74 74 m_size = gst_buffer_get_size(buffer); 75 m_sample = sample; 75 m_sample = adoptGRef(gst_sample_new(buffer, gst_sample_get_caps(sample.get()), nullptr, 76 gst_sample_get_info(sample.get()) ? gst_structure_copy(gst_sample_get_info(sample.get())) : nullptr)); 76 77 77 78 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp
r284156 r284711 375 375 } 376 376 377 static MediaTime bufferTimeToStreamTime(const GstSegment* segment, GstClockTime bufferTime) 378 { 379 if (bufferTime == GST_CLOCK_TIME_NONE) 380 return MediaTime::invalidTime(); 381 382 guint64 streamTime; 383 int sign = gst_segment_to_stream_time_full(segment, GST_FORMAT_TIME, bufferTime, &streamTime); 384 if (!sign) { 385 GST_ERROR("Couldn't map buffer time %" GST_TIME_FORMAT " to segment %" GST_PTR_FORMAT, GST_TIME_ARGS(bufferTime), segment); 386 return MediaTime::invalidTime(); 387 } 388 return MediaTime(sign * streamTime, GST_SECOND); 389 } 390 377 391 void AppendPipeline::appsinkNewSample(const Track& track, GRefPtr<GstSample>&& sample) 378 392 { 379 393 ASSERT(isMainThread()); 380 394 381 if (UNLIKELY(!gst_sample_get_buffer(sample.get()))) { 395 GstBuffer* buffer = gst_sample_get_buffer(sample.get()); 396 if (UNLIKELY(!buffer)) { 382 397 GST_WARNING("Received sample without buffer from appsink."); 383 398 return; 384 399 } 385 400 386 if (!GST_BUFFER_PTS_IS_VALID( gst_sample_get_buffer(sample.get()))) {401 if (!GST_BUFFER_PTS_IS_VALID(buffer)) { 387 402 // When demuxing Vorbis, matroskademux creates several PTS-less frames with header information. We don't need those. 388 403 GST_DEBUG("Ignoring sample without PTS: %" GST_PTR_FORMAT, gst_sample_get_buffer(sample.get())); … … 390 405 } 391 406 407 GstSegment* segment = gst_sample_get_segment(sample.get()); 392 408 auto mediaSample = MediaSampleGStreamer::create(WTFMove(sample), track.presentationSize, track.trackId); 409 410 if (segment && (segment->time || segment->start)) { 411 // MP4 has the concept of edit lists, where some buffer time needs to be offsetted, often very slightly, 412 // to get exact timestamps. 413 MediaTime pts = bufferTimeToStreamTime(segment, GST_BUFFER_PTS(buffer)); 414 MediaTime dts = bufferTimeToStreamTime(segment, GST_BUFFER_DTS(buffer)); 415 GST_TRACE_OBJECT(track.appsinkPad.get(), "Mapped buffer to segment, PTS %" GST_TIME_FORMAT " -> %s DTS %" GST_TIME_FORMAT " -> %s", 416 GST_TIME_ARGS(GST_BUFFER_PTS(buffer)), pts.toString().utf8().data(), GST_TIME_ARGS(GST_BUFFER_DTS(buffer)), dts.toString().utf8().data()); 417 mediaSample->setTimestamps(pts, dts); 418 } else if (!GST_BUFFER_DTS(buffer) && GST_BUFFER_PTS(buffer) > 0 && GST_BUFFER_PTS(buffer) <= 100'000'000) { 419 // Because a track presentation time starting at some close to zero, but not exactly zero time can cause unexpected 420 // results for applications, we extend the duration of this first sample to the left so that it starts at zero. 421 // This is relevant for files that should have an edit list but don't, or when using GStreamer < 1.16, where 422 // edit lists are not parsed in push-mode. 423 424 GST_DEBUG("Extending first sample of track '%s' to make it start at PTS=0 %" GST_PTR_FORMAT, track.trackId.string().utf8().data(), buffer); 425 mediaSample->extendToTheBeginning(); 426 } 393 427 394 428 GST_TRACE("append: trackId=%s PTS=%s DTS=%s DUR=%s presentationSize=%.0fx%.0f", … … 398 432 mediaSample->duration().toString().utf8().data(), 399 433 mediaSample->presentationSize().width(), mediaSample->presentationSize().height()); 400 401 // Hack, rework when GStreamer >= 1.16 becomes a requirement:402 // We're not applying edit lists. GStreamer < 1.16 doesn't emit the correct segments to do so.403 // GStreamer fix in https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/commit/c2a0da8096009f0f99943f78dc18066965be60f9404 // Also, in order to apply them we would need to convert the timestamps to stream time, which we're not currently405 // doing for consistency between GStreamer versions.406 //407 // In consequence, the timestamps we're handling here are unedited track time. In track time, the first sample is408 // guaranteed to have DTS == 0, but in the case of streams with B-frames, often PTS > 0. Edit lists fix this by409 // offsetting all timestamps by that amount in movie time, but we can't do that if we don't have access to them.410 // (We could assume the track PTS of the sample with track DTS = 0 is the offset, but we don't have any guarantee411 // we will get appended that sample first, or ever).412 //413 // Because a track presentation time starting at some close to zero, but not exactly zero time can cause unexpected414 // results for applications, we extend the duration of this first sample to the left so that it starts at zero.415 if (mediaSample->decodeTime() == MediaTime::zeroTime() && mediaSample->presentationTime() > MediaTime::zeroTime() && mediaSample->presentationTime() <= MediaTime(1, 10)) {416 GST_DEBUG("Extending first sample to make it start at PTS=0");417 mediaSample->extendToTheBeginning();418 }419 434 420 435 m_sourceBufferPrivate.didReceiveSample(mediaSample.get());
Note:
See TracChangeset
for help on using the changeset viewer.