Skip to content
Permalink
Browse files
Fix failing mediasource-play.html and mediasource-config-change-mp4-v…
…-bitrate.html tests

https://bugs.webkit.org/show_bug.cgi?id=161819

Reviewed by Eric Carlson.

Source/WebCore:

Fixes tests: imported/w3c/web-platform-tests/media-source/mediasource-play.html
             imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode.html

The newest revision of the web-platform-test suite for Media Source tests new behavior
added to the MSE specification. Specifically, setting a MediaSource's duration will no
longer implicitly truncate the source's active SourceBuffer objects.

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::setDuration): Return exception if issued by setDurationInternal.
(WebCore::MediaSource::setDurationInternal): Bring "duration change" algorithm up to spec.
* Modules/mediasource/MediaSource.h:
* Modules/mediasource/SampleMap.h:
(WebCore::PresentationOrderSampleMap::begin): Add const accessor.
(WebCore::PresentationOrderSampleMap::end): Ditto.
(WebCore::PresentationOrderSampleMap::rbegin): Ditto.
(WebCore::PresentationOrderSampleMap::rend): DItto.
(WebCore::DecodeOrderSampleMap::begin): Ditto.
(WebCore::DecodeOrderSampleMap::end): Ditto.
(WebCore::DecodeOrderSampleMap::rbegin): Ditto.
(WebCore::DecodeOrderSampleMap::rend): Ditto.
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::highestPresentationTimestamp): Added convenience method.
(WebCore::SourceBuffer::removeCodedFrames): Drive-by fix; use .values() rather than
    pulling the value out of each HashMap iterator.
* Modules/mediasource/SourceBuffer.h:

LayoutTests:

* media/media-source/media-source-end-of-stream-readyState.html:
* media/media-source/media-source-end-of-stream-readyState-expected.txt:
* platform/mac/TestExpectations:


Canonical link: https://commits.webkit.org/180023@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205820 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
jernoble committed Sep 12, 2016
1 parent 7b19c6c commit f599e6fe1f8c53d2d38194c5a61da726f7917347
Showing 10 changed files with 110 additions and 32 deletions.
@@ -1,3 +1,14 @@
2016-09-12 Jer Noble <jer.noble@apple.com>

Fix failing mediasource-play.html and mediasource-config-change-mp4-v-bitrate.html tests
https://bugs.webkit.org/show_bug.cgi?id=161819

Reviewed by Eric Carlson.

* media/media-source/media-source-end-of-stream-readyState.html:
* media/media-source/media-source-end-of-stream-readyState-expected.txt:
* platform/mac/TestExpectations:

2016-09-12 Matt Baker <mattbaker@apple.com>

Web Inspector: Object.shallowEqual() should return false if object prototype chains differ
@@ -8,6 +8,6 @@ EXPECTED (source.duration.toFixed(3) == '10') OK
EXPECTED (sourceBuffer.buffered.end(0).toFixed(3) == '5') OK
RUN(source.endOfStream())
EXPECTED (source.duration.toFixed(3) == '5') OK
EVENT(updateend)
EXPECTED (sourceBuffer.updating == 'false') OK
END OF TEST

@@ -36,9 +36,10 @@
testExpected('sourceBuffer.buffered.end(0).toFixed(3)', 5);

waitForEventOn(source, 'sourceopen', function() { failTest("Should not transit to 'open' state during endOfStream().") }, false, true);
waitForEventOn(sourceBuffer, 'updateend', endTest, false, true);
run('source.endOfStream()');
testExpected('source.duration.toFixed(3)', 5);
testExpected('sourceBuffer.updating', false);
endTest();
}

</script>
@@ -1047,8 +1047,10 @@ webkit.org/b/137505 media/track/track-forced-subtitles-in-band.html [ Failure Pa
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/SourceBuffer-abort-removed.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/SourceBuffer-abort.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-closed.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-config-change-mp4-v-bitrate.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-endofstream-invaliderror.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-multiple-attach.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-play.html [ Pass ]
[ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-sourcebufferlist.html [ Pass ]

# Flaky Media Source tests
@@ -1060,7 +1062,6 @@ webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/m
webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-append-buffer.html [ Failure ]
webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-config-change-mp4-v-bitrate.html [ Failure ]
webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-is-type-supported.html [ Failure ]
webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-play.html [ Failure ]
webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-remove.html [ Failure ]
webkit.org/b/161725 [ Yosemite+ ] imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode.html [ Failure ]

@@ -1,3 +1,36 @@
2016-09-12 Jer Noble <jer.noble@apple.com>

Fix failing mediasource-play.html and mediasource-config-change-mp4-v-bitrate.html tests
https://bugs.webkit.org/show_bug.cgi?id=161819

Reviewed by Eric Carlson.

Fixes tests: imported/w3c/web-platform-tests/media-source/mediasource-play.html
imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode.html

The newest revision of the web-platform-test suite for Media Source tests new behavior
added to the MSE specification. Specifically, setting a MediaSource's duration will no
longer implicitly truncate the source's active SourceBuffer objects.

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::setDuration): Return exception if issued by setDurationInternal.
(WebCore::MediaSource::setDurationInternal): Bring "duration change" algorithm up to spec.
* Modules/mediasource/MediaSource.h:
* Modules/mediasource/SampleMap.h:
(WebCore::PresentationOrderSampleMap::begin): Add const accessor.
(WebCore::PresentationOrderSampleMap::end): Ditto.
(WebCore::PresentationOrderSampleMap::rbegin): Ditto.
(WebCore::PresentationOrderSampleMap::rend): DItto.
(WebCore::DecodeOrderSampleMap::begin): Ditto.
(WebCore::DecodeOrderSampleMap::end): Ditto.
(WebCore::DecodeOrderSampleMap::rbegin): Ditto.
(WebCore::DecodeOrderSampleMap::rend): Ditto.
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::highestPresentationTimestamp): Added convenience method.
(WebCore::SourceBuffer::removeCodedFrames): Drive-by fix; use .values() rather than
pulling the value out of each HashMap iterator.
* Modules/mediasource/SourceBuffer.h:

2016-09-12 Chris Dumez <cdumez@apple.com>

Switch remaining users of Document::inPageCache() to pageCacheState()
@@ -357,41 +357,49 @@ void MediaSource::setDuration(double duration, ExceptionCode& ec)
}

// 4. Run the duration change algorithm with new duration set to the value being assigned to this attribute.
setDurationInternal(MediaTime::createWithDouble(duration));
auto result = setDurationInternal(MediaTime::createWithDouble(duration));
if (result)
ec = result.value();
}

void MediaSource::setDurationInternal(const MediaTime& duration)
Optional<ExceptionCode> MediaSource::setDurationInternal(const MediaTime& duration)
{
// Duration Change Algorithm
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#duration-change-algorithm
// 2.4.6 Duration Change
// https://rawgit.com/w3c/media-source/45627646344eea0170dd1cbc5a3d508ca751abb8/media-source-respec.html#duration-change-algorithm

// 1. If the current value of duration is equal to new duration, then return.
if (duration == m_duration)
return;

// 2. Set old duration to the current value of duration.
MediaTime oldDuration = m_duration;

// 3. Update duration to new duration.
m_duration = duration;
MediaTime newDuration = duration;

// 4. If the new duration is less than old duration, then call remove(new duration, old duration)
// on all objects in sourceBuffers.
if (oldDuration.isValid() && duration < oldDuration) {
for (auto& sourceBuffer : *m_sourceBuffers)
sourceBuffer->rangeRemoval(duration, oldDuration);
// 1. If the current value of duration is equal to new duration, then return.
if (newDuration == m_duration)
return { };

// 2. If new duration is less than the highest presentation timestamp of any buffered coded frames
// for all SourceBuffer objects in sourceBuffers, then throw an InvalidStateError exception and
// abort these steps.
// 3. Let highest end time be the largest track buffer ranges end time across all the track buffers
// across all SourceBuffer objects in sourceBuffers.
MediaTime highestPresentationTimestamp;
MediaTime highestEndTime;
for (auto& sourceBuffer : *m_sourceBuffers) {
highestPresentationTimestamp = std::max(highestPresentationTimestamp, sourceBuffer->highestPresentationTimestamp());
highestEndTime = std::max(highestEndTime, sourceBuffer->buffered()->ranges().maximumBufferedTime());
}
if (highestPresentationTimestamp.isValid() && newDuration < highestPresentationTimestamp)
return INVALID_STATE_ERR;

// 5. If a user agent is unable to partially render audio frames or text cues that start before and end after the
// duration, then run the following steps:
// 5.1 Update new duration to the highest end time reported by the buffered attribute across all SourceBuffer objects
// in sourceBuffers.
// 5.2 Update duration to new duration.
// NOTE: Assume UA is able to partially render audio frames.
// 4. If new duration is less than highest end time, then
// 4.1. Update new duration to equal highest end time.
if (highestEndTime.isValid() && newDuration < highestEndTime)
newDuration = highestEndTime;

// 6. Update the media controller duration to new duration and run the HTMLMediaElement duration change algorithm.
// 5. Update duration to new duration.
m_duration = newDuration;

// 6. Update the media duration to new duration and run the HTMLMediaElement duration change algorithm.
LOG(MediaSource, "MediaSource::setDurationInternal(%p) - duration(%g)", this, duration.toDouble());
m_private->durationChanged();

return { };
}

void MediaSource::setReadyState(const AtomicString& state)
@@ -84,7 +84,7 @@ class MediaSource : public MediaSourcePrivateClient, public ActiveDOMObject, pub
void completeSeek();

void setDuration(double, ExceptionCode&);
void setDurationInternal(const MediaTime&);
Optional<ExceptionCode> setDurationInternal(const MediaTime&);
MediaTime currentTime() const;
const AtomicString& readyState() const { return m_readyState; }
void setReadyState(const AtomicString&);
@@ -42,13 +42,19 @@ class PresentationOrderSampleMap {
public:
typedef std::map<MediaTime, RefPtr<MediaSample>> MapType;
typedef MapType::iterator iterator;
typedef MapType::const_iterator const_iterator;
typedef MapType::reverse_iterator reverse_iterator;
typedef MapType::const_reverse_iterator const_reverse_iterator;
typedef std::pair<iterator, iterator> iterator_range;

iterator begin() { return m_samples.begin(); }
const_iterator begin() const { return m_samples.begin(); }
iterator end() { return m_samples.end(); }
const_iterator end() const { return m_samples.end(); }
reverse_iterator rbegin() { return m_samples.rbegin(); }
const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
reverse_iterator rend() { return m_samples.rend(); }
const_reverse_iterator rend() const { return m_samples.rend(); }

iterator findSampleWithPresentationTime(const MediaTime&);
iterator findSampleContainingPresentationTime(const MediaTime&);
@@ -69,13 +75,19 @@ class DecodeOrderSampleMap {
typedef std::pair<MediaTime, MediaTime> KeyType;
typedef std::map<KeyType, RefPtr<MediaSample>> MapType;
typedef MapType::iterator iterator;
typedef MapType::const_iterator const_iterator;
typedef MapType::reverse_iterator reverse_iterator;
typedef MapType::const_reverse_iterator const_reverse_iterator;
typedef std::pair<reverse_iterator, reverse_iterator> reverse_iterator_range;

iterator begin() { return m_samples.begin(); }
const_iterator begin() const { return m_samples.begin(); }
iterator end() { return m_samples.end(); }
const_iterator end() const { return m_samples.end(); }
reverse_iterator rbegin() { return m_samples.rbegin(); }
const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
reverse_iterator rend() { return m_samples.rend(); }
const_reverse_iterator rend() const { return m_samples.rend(); }

iterator findSampleWithDecodeKey(const KeyType&);
reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&);
@@ -395,6 +395,18 @@ void SourceBuffer::abortIfUpdating()
scheduleEvent(eventNames().updateendEvent);
}

MediaTime SourceBuffer::highestPresentationTimestamp() const
{
MediaTime highestTime;
for (auto& trackBuffer : m_trackBufferMap.values()) {
auto lastSampleIter = trackBuffer.samples.presentationOrder().rbegin();
if (lastSampleIter == trackBuffer.samples.presentationOrder().rend())
continue;
highestTime = std::max(highestTime, lastSampleIter->first);
}
return highestTime;
}

void SourceBuffer::removedFromMediaSource()
{
if (isRemoved())
@@ -741,9 +753,7 @@ void SourceBuffer::removeCodedFrames(const MediaTime& start, const MediaTime& en

// 2. Let end be the end presentation timestamp for the removal range.
// 3. For each track buffer in this source buffer, run the following steps:
for (auto& iter : m_trackBufferMap) {
TrackBuffer& trackBuffer = iter.value;

for (auto& trackBuffer : m_trackBufferMap.values()) {
// 3.1. Let remove end timestamp be the current value of duration
// 3.2 If this track buffer has a random access point timestamp that is greater than or equal to end, then update
// remove end timestamp to that random access point timestamp.
@@ -124,6 +124,8 @@ class SourceBuffer final : public RefCounted<SourceBuffer>, public ActiveDOMObje
bool isBufferedDirty() const { return m_bufferedDirty; }
void setBufferedDirty(bool flag) { m_bufferedDirty = flag; }

MediaTime highestPresentationTimestamp() const;

// ActiveDOMObject API.
bool hasPendingActivity() const override;

0 comments on commit f599e6f

Please sign in to comment.