Commit 2c7a68b0 authored by wolenetz@chromium.org's avatar wolenetz@chromium.org

Enable round-tripping and updating of SourceBuffer timestamp offset

This is the second part of a three-sided MediaSource 
Chromium/Blink+roll Blink/Chromium set of changes to enable 
JavaScript web apps to continue to round-trip 
SourceBuffer.timestampOffset set/get if SourceBuffer append 
operations do not update the timestamp offset, and to 
retrieve any updated timestamp offset as can occur during 
upcoming "sequence" append mode compliant coded frame 
processing. 

R=acolwell@chromium.org,jamesr@chromium.org
BUG=249422
TEST=No local linux regressions of http/tests/media/media-source/ layout tests

Review URL: https://codereview.chromium.org/178763006

git-svn-id: svn://svn.chromium.org/blink/trunk@168163 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 9d60d2fb
...@@ -102,7 +102,8 @@ ...@@ -102,7 +102,8 @@
assert_equals(sourceBuffer.mode, 'segments'); assert_equals(sourceBuffer.mode, 'segments');
sourceBuffer.mode = 'segments'; // No exception should occur. sourceBuffer.mode = 'segments'; // No exception should occur.
assert_equals(sourceBuffer.timestampOffset, 0.0); assert_equals(sourceBuffer.timestampOffset, 0.0);
sourceBuffer.timestampOffset = 10.0; // No exception should occur. sourceBuffer.timestampOffset = 10.123456789; // No exception should occur.
assert_equals(sourceBuffer.timestampOffset, 10.123456789); // Super-precise offsets should round-trip.
// Append first part of media segment. // Append first part of media segment.
test.expectEvent(sourceBuffer, 'updateend', 'Partial media segment append ended.'); test.expectEvent(sourceBuffer, 'updateend', 'Partial media segment append ended.');
...@@ -116,7 +117,7 @@ ...@@ -116,7 +117,7 @@
assert_throws('InvalidStateError', assert_throws('InvalidStateError',
function() { sourceBuffer.mode = 'segments'; }, function() { sourceBuffer.mode = 'segments'; },
'Setting valid sourceBuffer.mode while still parsing media segment threw InvalidStateError.'); 'Setting valid sourceBuffer.mode while still parsing media segment threw InvalidStateError.');
assert_equals(sourceBuffer.timestampOffset, 10.0); assert_equals(sourceBuffer.timestampOffset, 10.123456789);
assert_throws('InvalidStateError', assert_throws('InvalidStateError',
function() { sourceBuffer.timestampOffset = 20.0; }, function() { sourceBuffer.timestampOffset = 20.0; },
'Setting valid sourceBuffer.timestampOffset while still parsing media segment threw InvalidStateError.'); 'Setting valid sourceBuffer.timestampOffset while still parsing media segment threw InvalidStateError.');
...@@ -131,7 +132,7 @@ ...@@ -131,7 +132,7 @@
assert_false(sourceBuffer.updating, 'updating attribute is false'); assert_false(sourceBuffer.updating, 'updating attribute is false');
assert_equals(sourceBuffer.mode, 'segments'); assert_equals(sourceBuffer.mode, 'segments');
sourceBuffer.mode = 'segments'; // No exception should occur. sourceBuffer.mode = 'segments'; // No exception should occur.
assert_equals(sourceBuffer.timestampOffset, 10.0); assert_equals(sourceBuffer.timestampOffset, 10.123456789);
sourceBuffer.timestampOffset = 20.0; // No exception should occur. sourceBuffer.timestampOffset = 20.0; // No exception should occur.
test.done(); test.done();
}); });
......
...@@ -37,6 +37,11 @@ EXPECTED (mediaSource.sourceBuffers[0].buffered.length == '2') OK ...@@ -37,6 +37,11 @@ EXPECTED (mediaSource.sourceBuffers[0].buffered.length == '2') OK
EXPECTED (mediaSource.sourceBuffers[0].buffered.start(1) == '5') OK EXPECTED (mediaSource.sourceBuffers[0].buffered.start(1) == '5') OK
EXPECTED (mediaSource.sourceBuffers[0].buffered.end(1) > '5') OK EXPECTED (mediaSource.sourceBuffers[0].buffered.end(1) > '5') OK
Round-trip a precise timestampOffset
EXPECTED (segmentHelper.sourceBuffer.timestampOffset == '5') OK
RUN(segmentHelper.sourceBuffer.timestampOffset = 5.123456789)
EXPECTED (segmentHelper.sourceBuffer.timestampOffset == '5.123456789') OK
Remove SourceBuffer Remove SourceBuffer
RUN(mediaSource.removeSourceBuffer(segmentHelper.sourceBuffer)) RUN(mediaSource.removeSourceBuffer(segmentHelper.sourceBuffer))
EXPECTED (mediaSource.sourceBuffers.length == '0') OK EXPECTED (mediaSource.sourceBuffers.length == '0') OK
......
...@@ -61,6 +61,13 @@ ...@@ -61,6 +61,13 @@
testExpected("mediaSource.sourceBuffers[0].buffered.start(1)", 5); testExpected("mediaSource.sourceBuffers[0].buffered.start(1)", 5);
testExpected("mediaSource.sourceBuffers[0].buffered.end(1)", 5, '>'); testExpected("mediaSource.sourceBuffers[0].buffered.end(1)", 5, '>');
// Confirm that sub-microsecond granularity timestamps round-trip set/get.
consoleWrite("");
consoleWrite("Round-trip a precise timestampOffset");
testExpected("segmentHelper.sourceBuffer.timestampOffset", 5);
run("segmentHelper.sourceBuffer.timestampOffset = 5.123456789");
testExpected("segmentHelper.sourceBuffer.timestampOffset", 5.123456789);
consoleWrite(""); consoleWrite("");
consoleWrite("Remove SourceBuffer"); consoleWrite("Remove SourceBuffer");
......
...@@ -534,7 +534,7 @@ void SourceBuffer::appendBufferAsyncPart() ...@@ -534,7 +534,7 @@ void SourceBuffer::appendBufferAsyncPart()
// so that it can clear its end of stream state if necessary. // so that it can clear its end of stream state if necessary.
m_pendingAppendData.resize(1); m_pendingAppendData.resize(1);
} }
m_webSourceBuffer->append(m_pendingAppendData.data(), appendSize); m_webSourceBuffer->append(m_pendingAppendData.data(), appendSize, &m_timestampOffset);
// 3. Set the updating attribute to false. // 3. Set the updating attribute to false.
m_updating = false; m_updating = false;
...@@ -688,8 +688,7 @@ void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength ...@@ -688,8 +688,7 @@ void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength
WTF_LOG(Media, "SourceBuffer::didReceiveDataForClient(%d) %p", dataLength, this); WTF_LOG(Media, "SourceBuffer::didReceiveDataForClient(%d) %p", dataLength, this);
ASSERT(m_updating); ASSERT(m_updating);
ASSERT(m_loader); ASSERT(m_loader);
m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), dataLength, &m_timestampOffset);
m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), dataLength);
} }
void SourceBuffer::didFinishLoading() void SourceBuffer::didFinishLoading()
......
...@@ -136,7 +136,10 @@ void WebKitSourceBuffer::append(PassRefPtr<Uint8Array> data, ExceptionState& exc ...@@ -136,7 +136,10 @@ void WebKitSourceBuffer::append(PassRefPtr<Uint8Array> data, ExceptionState& exc
m_source->openIfInEndedState(); m_source->openIfInEndedState();
// Steps 6 & beyond are handled by m_webSourceBuffer. // Steps 6 & beyond are handled by m_webSourceBuffer.
m_webSourceBuffer->append(data->data(), data->length());
// Use null for |timestampOffset| parameter because the prefixed API does not allow appends
// to update timestampOffset.
m_webSourceBuffer->append(data->data(), data->length(), 0);
} }
void WebKitSourceBuffer::abort(ExceptionState& exceptionState) void WebKitSourceBuffer::abort(ExceptionState& exceptionState)
......
...@@ -45,7 +45,11 @@ public: ...@@ -45,7 +45,11 @@ public:
virtual ~WebSourceBuffer() { } virtual ~WebSourceBuffer() { }
virtual bool setMode(AppendMode) = 0; virtual bool setMode(AppendMode) = 0;
virtual WebTimeRanges buffered() = 0; virtual WebTimeRanges buffered() = 0;
virtual void append(const unsigned char* data, unsigned length) = 0;
// Appends data and runs the segment parser loop algorithm.
// The algorithm may update |*timestampOffset| if |timestampOffset| is not null.
virtual void append(const unsigned char* data, unsigned length, double* timestampOffset) = 0;
virtual void abort() = 0; virtual void abort() = 0;
virtual void remove(double start, double end) = 0; virtual void remove(double start, double end) = 0;
virtual bool setTimestampOffset(double) = 0; virtual bool setTimestampOffset(double) = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment