Bug 1054831 - Improve state transition about decoding metadata by removing |mDispatchedDecodeMetadataTask|. r=cpearce

--HG--
extra : rebase_source : 23e040a5d35954e10f65029f5550e4440aeb4117
This commit is contained in:
JW Wang 2014-08-20 23:37:00 -04:00
Родитель 650a0fbdc5
Коммит df65a5a044
2 изменённых файлов: 26 добавлений и 32 удалений

Просмотреть файл

@ -180,7 +180,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
aDecoder->GetReentrantMonitor(),
&MediaDecoderStateMachine::TimeoutExpired,
MOZ_THIS_IN_INITIALIZER_LIST(), aRealTime)),
mState(DECODER_STATE_DECODING_METADATA),
mState(DECODER_STATE_DECODING_NONE),
mSyncPointInMediaStream(-1),
mSyncPointInDecodedStream(-1),
mPlayDuration(0),
@ -209,7 +209,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mQuickBuffering(false),
mMinimizePreroll(false),
mDecodeThreadWaiting(false),
mDispatchedDecodeMetadataTask(false),
mDropAudioUntilNextDiscontinuity(false),
mDropVideoUntilNextDiscontinuity(false),
mDecodeToSeekTarget(false),
@ -358,22 +357,26 @@ static const TrackRate RATE_VIDEO = USECS_PER_S;
void MediaDecoderStateMachine::SendStreamData()
{
NS_ASSERTION(OnDecodeThread() ||
OnStateMachineThread(), "Should be on decode thread or state machine thread");
NS_ASSERTION(OnDecodeThread() || OnStateMachineThread(),
"Should be on decode thread or state machine thread");
AssertCurrentThreadInMonitor();
MOZ_ASSERT(mState != DECODER_STATE_DECODING_NONE);
DecodedStreamData* stream = mDecoder->GetDecodedStream();
if (!stream)
if (!stream) {
return;
}
if (mState == DECODER_STATE_DECODING_METADATA)
if (mState == DECODER_STATE_DECODING_METADATA) {
return;
}
// If there's still an audio sink alive, then we can't send any stream
// data yet since both SendStreamData and the audio sink want to be in
// charge of popping the audio queue. We're waiting for the audio sink
if (mAudioSink)
if (mAudioSink) {
return;
}
int64_t minLastAudioPacketTime = INT64_MAX;
bool finished =
@ -1330,7 +1333,7 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant)
ScheduleStateMachine();
mStartTime = 0;
mCurrentFrameTime = 0;
mState = DECODER_STATE_DECODING_METADATA;
mState = DECODER_STATE_DECODING_NONE;
mDecoder->GetReentrantMonitor().NotifyAll();
}
}
@ -1399,8 +1402,8 @@ void MediaDecoderStateMachine::NotifyWaitingForResourcesStatusChanged()
DECODER_LOG("NotifyWaitingForResourcesStatusChanged");
// The reader is no longer waiting for resources (say a hardware decoder),
// we can now proceed to decode metadata.
mState = DECODER_STATE_DECODING_METADATA;
EnqueueDecodeMetadataTask();
mState = DECODER_STATE_DECODING_NONE;
ScheduleStateMachine();
}
void MediaDecoderStateMachine::Play()
@ -1531,21 +1534,13 @@ nsresult
MediaDecoderStateMachine::EnqueueDecodeMetadataTask()
{
AssertCurrentThreadInMonitor();
MOZ_ASSERT(mState == DECODER_STATE_DECODING_METADATA);
if (mState != DECODER_STATE_DECODING_METADATA ||
mDispatchedDecodeMetadataTask) {
return NS_OK;
}
mDispatchedDecodeMetadataTask = true;
RefPtr<nsIRunnable> task(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::CallDecodeMetadata));
nsresult rv = mDecodeTaskQueue->Dispatch(task);
if (NS_FAILED(rv)) {
DECODER_WARN("Dispatch ReadMetadata task failed.");
mDispatchedDecodeMetadataTask = false;
}
return rv;
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
void
@ -1872,10 +1867,8 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
{
AssertCurrentThreadInMonitor();
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
MOZ_ASSERT(mState == DECODER_STATE_DECODING_METADATA);
DECODER_LOG("Decoding Media Headers");
if (mState != DECODER_STATE_DECODING_METADATA) {
return NS_ERROR_FAILURE;
}
nsresult res;
MediaInfo info;
@ -1890,7 +1883,6 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
// change state to DECODER_STATE_WAIT_FOR_RESOURCES
StartWaitForResources();
// affect values only if ReadMetadata succeeds
mDispatchedDecodeMetadataTask = false;
return NS_OK;
}
}
@ -2012,7 +2004,6 @@ MediaDecoderStateMachine::FinishDecodeMetadata()
StartPlayback();
}
mDispatchedDecodeMetadataTask = false;
return NS_OK;
}
@ -2143,6 +2134,8 @@ MediaDecoderStateMachine::SeekCompleted()
}
}
MOZ_ASSERT(mState != DECODER_STATE_DECODING_NONE);
mDecoder->StartProgressUpdates();
if (mState == DECODER_STATE_DECODING_METADATA ||
mState == DECODER_STATE_DORMANT ||
@ -2329,11 +2322,16 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
return NS_OK;
}
case DECODER_STATE_DECODING_METADATA: {
case DECODER_STATE_DECODING_NONE: {
mState = DECODER_STATE_DECODING_METADATA;
// Ensure we have a decode thread to decode metadata.
return EnqueueDecodeMetadataTask();
}
case DECODER_STATE_DECODING_METADATA: {
return NS_OK;
}
case DECODER_STATE_DECODING: {
if (mDecoder->GetState() != MediaDecoder::PLAY_STATE_PLAYING &&
IsPlaying())

Просмотреть файл

@ -135,6 +135,7 @@ public:
// Enumeration for the valid decoding states
enum State {
DECODER_STATE_DECODING_NONE,
DECODER_STATE_DECODING_METADATA,
DECODER_STATE_WAIT_FOR_RESOURCES,
DECODER_STATE_DORMANT,
@ -893,11 +894,6 @@ protected:
// by the decoder monitor.
bool mDecodeThreadWaiting;
// True if we've dispatched a task to the decode task queue to call
// ReadMetadata on the reader. We maintain a flag to ensure that we don't
// dispatch multiple tasks to re-do the metadata loading.
bool mDispatchedDecodeMetadataTask;
// These two flags are true when we need to drop decoded samples that
// we receive up to the next discontinuity. We do this when we seek;
// the first sample in each stream after the seek is marked as being