Bug 938022. Part 6: Have MediaDecoder/MediaDecoderStateMachine that's producing a MediaStream use that stream's current time as the media clock. r=padenot

We monitor the stream's output current time via a new MediaStreamListener
owned by DecodedStreamData. We also track its main-thread Finished status.
While we're writing to a DecodedStreamData stream that hasn't finished its
output, we stay in the DECODER_STATE_COMPLETED state so we can keep updating
video and firing timeupdates.

GetClock() uses the DecodedStreamData stream's current time as the source for
the clock if there is one.
This commit is contained in:
Robert O'Callahan
2013-12-02 10:09:06 +13:00
parent 73556e9413
commit 293c76a40a
4 changed files with 116 additions and 9 deletions

View File

@@ -371,6 +371,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
bool aRealTime) :
mDecoder(aDecoder),
mState(DECODER_STATE_DECODING_METADATA),
mSyncPointInMediaStream(-1),
mSyncPointInDecodedStream(-1),
mResetPlayStartTime(false),
mPlayDuration(0),
mStartTime(-1),
@@ -1319,6 +1321,19 @@ void MediaDecoderStateMachine::StopPlayback()
mDecoder->UpdateStreamBlockingForStateMachinePlaying();
}
void MediaDecoderStateMachine::SetSyncPointForMediaStream()
{
AssertCurrentThreadInMonitor();
DecodedStreamData* stream = mDecoder->GetDecodedStream();
if (!stream) {
return;
}
mSyncPointInMediaStream = stream->GetLastOutputTime();
mSyncPointInDecodedStream = mStartTime + mPlayDuration;
}
void MediaDecoderStateMachine::StartPlayback()
{
DECODER_LOG(PR_LOG_DEBUG, ("%p StartPlayback()", mDecoder.get()));
@@ -2329,7 +2344,8 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
// end of the media, and so that we update the readyState.
if (mState == DECODER_STATE_COMPLETED &&
(mReader->VideoQueue().GetSize() > 0 ||
(HasAudio() && !mAudioCompleted)))
(HasAudio() && !mAudioCompleted) ||
(mDecoder->GetDecodedStream() && !mDecoder->GetDecodedStream()->IsFinished())))
{
AdvanceFrame();
NS_ASSERTION(mDecoder->GetState() != MediaDecoder::PLAY_STATE_PLAYING ||
@@ -2432,10 +2448,16 @@ int64_t MediaDecoderStateMachine::GetClock() {
// Determine the clock time. If we've got audio, and we've not reached
// the end of the audio, use the audio clock. However if we've finished
// audio, or don't have audio, use the system clock.
// audio, or don't have audio, use the system clock. If our output is being
// fed to a MediaStream, use that stream as the source of the clock.
int64_t clock_time = -1;
DecodedStreamData* stream = mDecoder->GetDecodedStream();
if (!IsPlaying()) {
clock_time = mPlayDuration + mStartTime;
} else if (stream) {
NS_ASSERTION(mSyncPointInDecodedStream >= 0, "Should have set up sync point");
StreamTime streamDelta = stream->GetLastOutputTime() - mSyncPointInMediaStream;
clock_time = mSyncPointInDecodedStream + MediaTimeToMicroseconds(streamDelta);
} else {
int64_t audio_time = GetAudioClock();
if (HasAudio() && !mAudioCompleted && audio_time != -1) {