Title: [172032] trunk/Source/WebCore
Revision
172032
Author
jer.no...@apple.com
Date
2014-08-05 09:42:09 -0700 (Tue, 05 Aug 2014)

Log Message

[MSE] Seeking occasionally causes many frames to be displayed in "fast forward" mode
https://bugs.webkit.org/show_bug.cgi?id=135422

Reviewed by Eric Carlson.

Three related fixes:

In reenqueueMediaForTime(), update TrackBuffer.lastEnqueuedPresentationTime when we flush
samples, so that the next time samples are re-enqueued, the starting point for re-enqueueing
is correct.

In sourceBufferPrivateDidReceiveSample(), do not add samples to the decode queue
if they are before the current media time.

When a seek is pending, but samples for the new time is not yet present in the SourceBuffer,
the SourceBufferPrivate may signal that it's ready for new samples through the
sourceBufferPrivateDidBecomeReadyForMoreSamples() method. In this situation, we should not
continue to provideMediaData(), as that will append samples from the prior-to-seeking media
timeline. Since the timeline may have moved forward due to the seek, a decoder may decide to
display those frames as quickly as possible (the "fast forward" behavior) in order to catch
up to the new current time.

If a re-enqueue is pending, don't provide media data in response to being notified that the
SourceBufferPrivate is ready for more samples. Wait until samples for the new current time
are appended.

Also, don't provide media data if we are waiting for a seek to complete.

* Modules/mediasource/MediaSource.h:
(WebCore::MediaSource::isSeeking): Convenience method.
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
(WebCore::SourceBuffer::sourceBufferPrivateDidBecomeReadyForMoreSamples):
(WebCore::SourceBuffer::reenqueueMediaForTime):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (172031 => 172032)


--- trunk/Source/WebCore/ChangeLog	2014-08-05 16:41:46 UTC (rev 172031)
+++ trunk/Source/WebCore/ChangeLog	2014-08-05 16:42:09 UTC (rev 172032)
@@ -1,3 +1,40 @@
+2014-08-05  Jer Noble  <jer.no...@apple.com>
+
+        [MSE] Seeking occasionally causes many frames to be displayed in "fast forward" mode
+        https://bugs.webkit.org/show_bug.cgi?id=135422
+
+        Reviewed by Eric Carlson.
+
+        Three related fixes:
+
+        In reenqueueMediaForTime(), update TrackBuffer.lastEnqueuedPresentationTime when we flush
+        samples, so that the next time samples are re-enqueued, the starting point for re-enqueueing
+        is correct.
+
+        In sourceBufferPrivateDidReceiveSample(), do not add samples to the decode queue
+        if they are before the current media time.
+
+        When a seek is pending, but samples for the new time is not yet present in the SourceBuffer,
+        the SourceBufferPrivate may signal that it's ready for new samples through the
+        sourceBufferPrivateDidBecomeReadyForMoreSamples() method. In this situation, we should not
+        continue to provideMediaData(), as that will append samples from the prior-to-seeking media
+        timeline. Since the timeline may have moved forward due to the seek, a decoder may decide to
+        display those frames as quickly as possible (the "fast forward" behavior) in order to catch
+        up to the new current time.
+
+        If a re-enqueue is pending, don't provide media data in response to being notified that the
+        SourceBufferPrivate is ready for more samples. Wait until samples for the new current time
+        are appended.
+
+        Also, don't provide media data if we are waiting for a seek to complete.
+
+        * Modules/mediasource/MediaSource.h:
+        (WebCore::MediaSource::isSeeking): Convenience method.
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+        (WebCore::SourceBuffer::sourceBufferPrivateDidBecomeReadyForMoreSamples):
+        (WebCore::SourceBuffer::reenqueueMediaForTime):
+
 2014-08-05  Chris Fleizach  <cfleiz...@apple.com>
 
         AX: Select text activity should return replaced text instead of previously selected text

Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.h (172031 => 172032)


--- trunk/Source/WebCore/Modules/mediasource/MediaSource.h	2014-08-05 16:41:46 UTC (rev 172031)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.h	2014-08-05 16:42:09 UTC (rev 172032)
@@ -79,6 +79,7 @@
     bool attachToElement(HTMLMediaElement*);
     void close();
     void monitorSourceBuffers();
+    bool isSeeking() const { return m_pendingSeekTime.isValid(); }
     void completeSeek();
 
     void setDuration(double, ExceptionCode&);

Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (172031 => 172032)


--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-08-05 16:41:46 UTC (rev 172031)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-08-05 16:42:09 UTC (rev 172032)
@@ -1208,8 +1208,10 @@
         // Add the coded frame with the presentation timestamp, decode timestamp, and frame duration to the track buffer.
         trackBuffer.samples.addSample(sample);
 
-        DecodeOrderSampleMap::KeyType decodeKey(decodeTimestamp, presentationTimestamp);
-        trackBuffer.decodeQueue.insert(DecodeOrderSampleMap::MapType::value_type(decodeKey, sample));
+        if (trackBuffer.lastEnqueuedPresentationTime.isInvalid() || presentationTimestamp > trackBuffer.lastEnqueuedPresentationTime) {
+            DecodeOrderSampleMap::KeyType decodeKey(decodeTimestamp, presentationTimestamp);
+            trackBuffer.decodeQueue.insert(DecodeOrderSampleMap::MapType::value_type(decodeKey, sample));
+        }
 
         // 1.18 Set last decode timestamp for track buffer to decode timestamp.
         trackBuffer.lastDecodeTimestamp = decodeTimestamp;
@@ -1362,7 +1364,9 @@
     if (it == m_trackBufferMap.end())
         return;
 
-    provideMediaData(it->value, trackID);
+    TrackBuffer& trackBuffer = it->value;
+    if (!trackBuffer.needsReenqueueing && !m_source->isSeeking())
+        provideMediaData(trackBuffer, trackID);
 }
 
 void SourceBuffer::provideMediaData(TrackBuffer& trackBuffer, AtomicString trackID)
@@ -1421,6 +1425,9 @@
 
     m_private->flushAndEnqueueNonDisplayingSamples(nonDisplayingSamples, trackID);
 
+    if (!nonDisplayingSamples.isEmpty())
+        trackBuffer.lastEnqueuedPresentationTime = nonDisplayingSamples.last()->presentationTime();
+
     // Fill the decode queue with the remaining samples.
     trackBuffer.decodeQueue.clear();
     for (auto iter = currentSampleDTSIterator; iter != trackBuffer.samples.decodeOrder().end(); ++iter)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to