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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user