зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1307022. Part 4 - move some code from OnVideoDecoded() to various state objects. r=kaku
MozReview-Commit-ID: 1Et6W4b78fG --HG-- extra : rebase_source : 83ddbcb888cf9671c812f81930477857cec94520
This commit is contained in:
Родитель
57ec42f164
Коммит
73014c126f
|
@ -214,6 +214,11 @@ public:
|
|||
|
||||
virtual bool HandleAudioDecoded(MediaData* aAudio) { return false; }
|
||||
|
||||
virtual bool HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
using Master = MediaDecoderStateMachine;
|
||||
explicit StateObject(Master* aPtr) : mMaster(aPtr) {}
|
||||
|
@ -424,6 +429,13 @@ public:
|
|||
mMaster->MaybeFinishDecodeFirstFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
|
||||
{
|
||||
mMaster->Push(aVideo, MediaData::VIDEO_DATA);
|
||||
mMaster->MaybeFinishDecodeFirstFrame();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class MediaDecoderStateMachine::DecodingState
|
||||
|
@ -497,7 +509,46 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
|
||||
{
|
||||
mMaster->Push(aVideo, MediaData::VIDEO_DATA);
|
||||
mMaster->MaybeStopPrerolling();
|
||||
CheckSlowDecoding(aDecodeStart);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void CheckSlowDecoding(TimeStamp aDecodeStart)
|
||||
{
|
||||
// For non async readers, if the requested video sample was slow to
|
||||
// arrive, increase the amount of audio we buffer to ensure that we
|
||||
// don't run out of audio. This is unnecessary for async readers,
|
||||
// since they decode audio and video on different threads so they
|
||||
// are unlikely to run out of decoded audio.
|
||||
if (Reader()->IsAsync()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimeDuration decodeTime = TimeStamp::Now() - aDecodeStart;
|
||||
int64_t adjustedTime = THRESHOLD_FACTOR * DurationToUsecs(decodeTime);
|
||||
if (adjustedTime > mMaster->mLowAudioThresholdUsecs &&
|
||||
!mMaster->HasLowBufferedData())
|
||||
{
|
||||
mMaster->mLowAudioThresholdUsecs =
|
||||
std::min(adjustedTime, mMaster->mAmpleAudioThresholdUsecs);
|
||||
|
||||
mMaster->mAmpleAudioThresholdUsecs =
|
||||
std::max(THRESHOLD_FACTOR * mMaster->mLowAudioThresholdUsecs,
|
||||
mMaster->mAmpleAudioThresholdUsecs);
|
||||
|
||||
SLOG("Slow video decode, set "
|
||||
"mLowAudioThresholdUsecs=%lld "
|
||||
"mAmpleAudioThresholdUsecs=%lld",
|
||||
mMaster->mLowAudioThresholdUsecs,
|
||||
mMaster->mAmpleAudioThresholdUsecs);
|
||||
}
|
||||
}
|
||||
|
||||
// Time at which we started decoding.
|
||||
TimeStamp mDecodeStartTime;
|
||||
};
|
||||
|
@ -538,6 +589,12 @@ public:
|
|||
MOZ_ASSERT(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
|
||||
{
|
||||
MOZ_ASSERT(false);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class MediaDecoderStateMachine::BufferingState
|
||||
|
@ -619,6 +676,15 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
|
||||
{
|
||||
// This might be the sample we need to exit buffering.
|
||||
// Schedule Step() to check it.
|
||||
mMaster->Push(aVideo, MediaData::VIDEO_DATA);
|
||||
mMaster->ScheduleStateMachine();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
TimeStamp mBufferingStart;
|
||||
};
|
||||
|
@ -1200,7 +1266,6 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideo,
|
|||
TimeStamp aDecodeStartTime)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
|
||||
MOZ_ASSERT(aVideo);
|
||||
|
||||
// Handle abnormal or negative timestamps.
|
||||
|
@ -1208,51 +1273,7 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideo,
|
|||
|
||||
SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", aVideo->mTime, aVideo->GetEndTime());
|
||||
|
||||
switch (mState) {
|
||||
case DECODER_STATE_BUFFERING: {
|
||||
// If we're buffering, this may be the sample we need to stop buffering.
|
||||
// Save it and schedule the state machine.
|
||||
Push(aVideo, MediaData::VIDEO_DATA);
|
||||
ScheduleStateMachine();
|
||||
return;
|
||||
}
|
||||
|
||||
case DECODER_STATE_DECODING_FIRSTFRAME: {
|
||||
Push(aVideo, MediaData::VIDEO_DATA);
|
||||
MaybeFinishDecodeFirstFrame();
|
||||
return;
|
||||
}
|
||||
|
||||
case DECODER_STATE_DECODING: {
|
||||
Push(aVideo, MediaData::VIDEO_DATA);
|
||||
MaybeStopPrerolling();
|
||||
|
||||
// For non async readers, if the requested video sample was slow to
|
||||
// arrive, increase the amount of audio we buffer to ensure that we
|
||||
// don't run out of audio. This is unnecessary for async readers,
|
||||
// since they decode audio and video on different threads so they
|
||||
// are unlikely to run out of decoded audio.
|
||||
if (mReader->IsAsync()) {
|
||||
return;
|
||||
}
|
||||
TimeDuration decodeTime = TimeStamp::Now() - aDecodeStartTime;
|
||||
if (THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > mLowAudioThresholdUsecs &&
|
||||
!HasLowBufferedData())
|
||||
{
|
||||
mLowAudioThresholdUsecs =
|
||||
std::min(THRESHOLD_FACTOR * DurationToUsecs(decodeTime), mAmpleAudioThresholdUsecs);
|
||||
mAmpleAudioThresholdUsecs = std::max(THRESHOLD_FACTOR * mLowAudioThresholdUsecs,
|
||||
mAmpleAudioThresholdUsecs);
|
||||
DECODER_LOG("Slow video decode, set mLowAudioThresholdUsecs=%lld mAmpleAudioThresholdUsecs=%lld",
|
||||
mLowAudioThresholdUsecs, mAmpleAudioThresholdUsecs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
// Ignore other cases.
|
||||
return;
|
||||
}
|
||||
}
|
||||
mStateObj->HandleVideoDecoded(aVideo, aDecodeStartTime);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Загрузка…
Ссылка в новой задаче