Title: [170932] trunk
Revision
170932
Author
jer.no...@apple.com
Date
2014-07-09 14:37:17 -0700 (Wed, 09 Jul 2014)

Log Message

Source/WebCore: [MSE] http/tests/media/media-source/mediasource-remove.html is failing
https://bugs.webkit.org/show_bug.cgi?id=134768

Reviewed by Eric Carlson.

Fix multiple bugs causing mediasource-remove.html to fail:

Separate out setDuration() into setDurationInternal() so that steps which require
us to run the "duration change algorithm" don't bail out if the SoureBuffer is
inside updating().

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::setDuration):
(WebCore::MediaSource::setDurationInternal):
* Modules/mediasource/MediaSource.h:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):

When removing coded frames, do so starting from the first sample in the range in
decode order, so that frames dependant on removed frames are themselves removed. Add
a convenience method in SampleMap findSampleWithPresentationTime(), and rename
findSampleAfterPresentationTime() to findSampleOnOrAfterPresentationTime() to correctly
reflect what the method does, and simplify its implementation by searching the map's keys
directly.

* Modules/mediasource/SampleMap.cpp:
(WebCore::PresentationOrderSampleMap::findSampleWithPresentationTime):
(WebCore::PresentationOrderSampleMap::findSampleOnOrAfterPresentationTime):
(WebCore::DecodeOrderSampleMap::findSyncSampleAfterPresentationTime):
(WebCore::PresentationOrderSampleMap::findSampleAfterPresentationTime): Deleted.
* Modules/mediasource/SampleMap.h:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::decodeTimeComparator):
(WebCore::SourceBuffer::removeCodedFrames):

Throw the correct exception (INVALID_STATE_ERR) from SourceBuffer::remove().

* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::remove):

LayoutTests: [MSE] http/tests/media/media-source/mediasource-remove.html is failing.
https://bugs.webkit.org/show_bug.cgi?id=134768

Reviewed by Eric Carlson.

Update mediasource-remove.html with the correct locations of sync-samples.

* http/tests/media/media-source/mediasource-remove.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (170931 => 170932)


--- trunk/LayoutTests/ChangeLog	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/LayoutTests/ChangeLog	2014-07-09 21:37:17 UTC (rev 170932)
@@ -1,3 +1,14 @@
+2014-06-28  Jer Noble  <jer.no...@apple.com>
+
+        [MSE] http/tests/media/media-source/mediasource-remove.html is failing.
+        https://bugs.webkit.org/show_bug.cgi?id=134768
+
+        Reviewed by Eric Carlson.
+
+        Update mediasource-remove.html with the correct locations of sync-samples.
+
+        * http/tests/media/media-source/mediasource-remove.html:
+
 2014-07-09  Antti Koivisto  <an...@apple.com>
 
         fast/dom/HTMLImageElement/sizes/image-sizes-js-change.html is failing in some bots

Modified: trunk/LayoutTests/http/tests/media/media-source/mediasource-remove.html (170931 => 170932)


--- trunk/LayoutTests/http/tests/media/media-source/mediasource-remove.html	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/LayoutTests/http/tests/media/media-source/mediasource-remove.html	2014-07-09 21:37:17 UTC (rev 170932)
@@ -187,7 +187,7 @@
           {
               var expectations = {
                 webm: ("{ [3.187, " + duration + ") }"),
-                mp4: ("{ [3.021, " + duration + ") }"),
+                mp4: ("{ [3.228, " + duration + ") }"),
               };
 
               // Note: Range doesn't start exactly at the end of the remove range because there isn't
@@ -199,7 +199,7 @@
           {
               var expectations = {
                 webm: ("{ [0.000, 1.012) [3.187, " + duration + ") }"),
-                mp4: ("{ [0.000, 1.022) [3.021, " + duration + ") }"),
+                mp4: ("{ [0.000, 1.029) [3.228, " + duration + ") }"),
               };
 
               // Note: The first resulting range ends slightly after start because the removal algorithm only removes
@@ -212,7 +212,7 @@
           {
               var expectations = {
                 webm: "{ [0.000, 1.012) }",
-                mp4: "{ [0.000, 1.022) }",
+                mp4: "{ [0.000, 1.029) }",
               };
 
               removeAndCheckBufferedRanges(test, sourceBuffer, 1, Number.POSITIVE_INFINITY, expectations[subType]);

Modified: trunk/Source/WebCore/ChangeLog (170931 => 170932)


--- trunk/Source/WebCore/ChangeLog	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/Source/WebCore/ChangeLog	2014-07-09 21:37:17 UTC (rev 170932)
@@ -1,3 +1,46 @@
+2014-06-28  Jer Noble  <jer.no...@apple.com>
+
+        [MSE] http/tests/media/media-source/mediasource-remove.html is failing
+        https://bugs.webkit.org/show_bug.cgi?id=134768
+
+        Reviewed by Eric Carlson.
+
+        Fix multiple bugs causing mediasource-remove.html to fail:
+
+        Separate out setDuration() into setDurationInternal() so that steps which require
+        us to run the "duration change algorithm" don't bail out if the SoureBuffer is
+        inside updating().
+
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::setDuration):
+        (WebCore::MediaSource::setDurationInternal):
+        * Modules/mediasource/MediaSource.h:
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+
+        When removing coded frames, do so starting from the first sample in the range in
+        decode order, so that frames dependant on removed frames are themselves removed. Add
+        a convenience method in SampleMap findSampleWithPresentationTime(), and rename
+        findSampleAfterPresentationTime() to findSampleOnOrAfterPresentationTime() to correctly
+        reflect what the method does, and simplify its implementation by searching the map's keys
+        directly.
+
+        * Modules/mediasource/SampleMap.cpp:
+        (WebCore::PresentationOrderSampleMap::findSampleWithPresentationTime):
+        (WebCore::PresentationOrderSampleMap::findSampleOnOrAfterPresentationTime):
+        (WebCore::DecodeOrderSampleMap::findSyncSampleAfterPresentationTime):
+        (WebCore::PresentationOrderSampleMap::findSampleAfterPresentationTime): Deleted.
+        * Modules/mediasource/SampleMap.h:
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::decodeTimeComparator):
+        (WebCore::SourceBuffer::removeCodedFrames):
+
+        Throw the correct exception (INVALID_STATE_ERR) from SourceBuffer::remove().
+
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::remove):
+
 2014-07-09  Pratik Solanki  <psola...@apple.com>
 
         Add SharedBuffer::wrapCFDataArray() and use it

Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp (170931 => 170932)


--- trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp	2014-07-09 21:37:17 UTC (rev 170932)
@@ -278,6 +278,11 @@
     }
 
     // 4. Run the duration change algorithm with new duration set to the value being assigned to this attribute.
+    setDurationInternal(duration);
+}
+
+void MediaSource::setDurationInternal(double duration)
+{
     m_private->setDuration(MediaTime::createWithDouble(duration));
 }
 

Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.h (170931 => 170932)


--- trunk/Source/WebCore/Modules/mediasource/MediaSource.h	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.h	2014-07-09 21:37:17 UTC (rev 170932)
@@ -79,6 +79,7 @@
     void monitorSourceBuffers();
 
     void setDuration(double, ExceptionCode&);
+    void setDurationInternal(double);
     double currentTime() const;
     const AtomicString& readyState() const { return m_readyState; }
     void setReadyState(const AtomicString&);

Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp (170931 => 170932)


--- trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp	2014-07-09 21:37:17 UTC (rev 170932)
@@ -122,6 +122,14 @@
     m_totalSize -= sample->sizeInBytes();
 }
 
+PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleWithPresentationTime(const MediaTime& time)
+{
+    auto range = m_samples.equal_range(time);
+    if (range.first == range.second)
+        return end();
+    return range.first;
+}
+
 PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleContainingPresentationTime(const MediaTime& time)
 {
     auto range = std::equal_range(begin(), end(), time, SampleIsLessThanMediaTimeComparator<MapType>());
@@ -130,9 +138,9 @@
     return range.first;
 }
 
-PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleAfterPresentationTime(const MediaTime& time)
+PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleOnOrAfterPresentationTime(const MediaTime& time)
 {
-    return std::lower_bound(begin(), end(), time, SampleIsLessThanMediaTimeComparator<MapType>());
+    return m_samples.lower_bound(time);
 }
 
 DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSampleWithDecodeTime(const MediaTime& time)
@@ -184,7 +192,7 @@
 
 DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSyncSampleAfterPresentationTime(const MediaTime& time, const MediaTime& threshold)
 {
-    PresentationOrderSampleMap::iterator currentSamplePTS = m_presentationOrder.findSampleAfterPresentationTime(time);
+    PresentationOrderSampleMap::iterator currentSamplePTS = m_presentationOrder.findSampleOnOrAfterPresentationTime(time);
     if (currentSamplePTS == m_presentationOrder.end())
         return end();
 

Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.h (170931 => 170932)


--- trunk/Source/WebCore/Modules/mediasource/SampleMap.h	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.h	2014-07-09 21:37:17 UTC (rev 170932)
@@ -50,8 +50,9 @@
     reverse_iterator rbegin() { return m_samples.rbegin(); }
     reverse_iterator rend() { return m_samples.rend(); }
 
+    iterator findSampleWithPresentationTime(const MediaTime&);
     iterator findSampleContainingPresentationTime(const MediaTime&);
-    iterator findSampleAfterPresentationTime(const MediaTime&);
+    iterator findSampleOnOrAfterPresentationTime(const MediaTime&);
     reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&);
     reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&);
     iterator_range findSamplesBetweenPresentationTimes(const MediaTime&, const MediaTime&);

Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (170931 => 170932)


--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-07-09 21:36:16 UTC (rev 170931)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-07-09 21:37:17 UTC (rev 170932)
@@ -243,7 +243,7 @@
     //    InvalidStateError exception and abort these steps.
     // 4. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
     if (isRemoved() || m_updating) {
-        ec = INVALID_ACCESS_ERR;
+        ec = INVALID_STATE_ERR;
         return;
     }
 
@@ -541,6 +541,11 @@
         m_source->streamEndedWithError(decodeError(), IgnorableExceptionCode());
 }
 
+static bool decodeTimeComparator(const PresentationOrderSampleMap::MapType::value_type& a, const PresentationOrderSampleMap::MapType::value_type& b)
+{
+    return a.second->decodeTime() < b.second->decodeTime();
+}
+
 void SourceBuffer::removeCodedFrames(const MediaTime& start, const MediaTime& end)
 {
     // 3.5.9 Coded Frame Removal Algorithm
@@ -561,20 +566,33 @@
         // NOTE: findSyncSampleAfterPresentationTime will return the next sync sample on or after the presentation time
         // or decodeOrder().end() if no sync sample exists after that presentation time.
         DecodeOrderSampleMap::iterator removeDecodeEnd = trackBuffer.samples.decodeOrder().findSyncSampleAfterPresentationTime(end);
+        PresentationOrderSampleMap::iterator removePresentationEnd;
+        if (removeDecodeEnd == trackBuffer.samples.decodeOrder().end())
+            removePresentationEnd = trackBuffer.samples.presentationOrder().end();
+        else
+            removePresentationEnd = trackBuffer.samples.presentationOrder().findSampleWithPresentationTime(removeDecodeEnd->second->presentationTime());
 
+        PresentationOrderSampleMap::iterator removePresentationStart = trackBuffer.samples.presentationOrder().findSampleOnOrAfterPresentationTime(start);
+        if (removePresentationStart == removePresentationEnd)
+            continue;
+
         // 3.3 Remove all media data, from this track buffer, that contain starting timestamps greater than or equal to
         // start and less than the remove end timestamp.
         // NOTE: frames must be removed in decode order, so that all dependant frames between the frame to be removed
-        // and the next sync sample frame are removed.
-        PresentationOrderSampleMap::iterator removePresentaionStart = trackBuffer.samples.presentationOrder().findSampleAfterPresentationTime(start);
-        DecodeOrderSampleMap::iterator removeDecodeStart = trackBuffer.samples.decodeOrder().findSampleWithDecodeTime(removePresentaionStart->second->decodeTime());
+        // and the next sync sample frame are removed. But we must start from the first sample in decode order, not
+        // presentation order.
+        PresentationOrderSampleMap::iterator minDecodeTimeIter = std::min_element(removePresentationStart, removePresentationEnd, decodeTimeComparator);
+        DecodeOrderSampleMap::iterator removeDecodeStart = trackBuffer.samples.decodeOrder().findSampleWithDecodeTime(minDecodeTimeIter->second->decodeTime());
+
         DecodeOrderSampleMap::MapType erasedSamples(removeDecodeStart, removeDecodeEnd);
+
         RefPtr<TimeRanges> erasedRanges = TimeRanges::create();
         MediaTime microsecond(1, 1000000);
         for (auto erasedIt : erasedSamples) {
-            trackBuffer.samples.removeSample(erasedIt.second.get());
-            double startTime = erasedIt.first.toDouble();
-            double endTime = ((erasedIt.first + erasedIt.second->duration()) + microsecond).toDouble();
+            RefPtr<MediaSample>& sample = erasedIt.second;
+            trackBuffer.samples.removeSample(sample.get());
+            double startTime = sample->presentationTime().toDouble();
+            double endTime = startTime + (sample->duration() + microsecond).toDouble();
             erasedRanges->add(startTime, endTime);
         }
 
@@ -692,7 +710,7 @@
         // ↳ Otherwise:
         //   Run the duration change algorithm with new duration set to positive Infinity.
         MediaTime newDuration = segment.duration.isValid() ? segment.duration : MediaTime::positiveInfiniteTime();
-        m_source->setDuration(newDuration.toDouble(), IGNORE_EXCEPTION);
+        m_source->setDurationInternal(newDuration.toDouble());
     }
 
     // 2. If the initialization segment has no audio, video, or text tracks, then run the end of stream
@@ -1217,7 +1235,7 @@
     // 5. If the media segment contains data beyond the current duration, then run the duration change algorithm with new
     // duration set to the maximum of the current duration and the highest end timestamp reported by HTMLMediaElement.buffered.
     if (highestPresentationEndTimestamp().toDouble() > m_source->duration())
-        m_source->setDuration(highestPresentationEndTimestamp().toDouble(), IgnorableExceptionCode());
+        m_source->setDurationInternal(highestPresentationEndTimestamp().toDouble());
 }
 
 bool SourceBuffer::sourceBufferPrivateHasAudio(const SourceBufferPrivate*) const
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to