mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
Bug 1062134 - Freeze decoding when back from Dormant state. r=jwwang
This commit is contained in:
parent
460ea00cb5
commit
ca40a01d83
@ -213,7 +213,9 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
mDropVideoUntilNextDiscontinuity(false),
|
||||
mDecodeToSeekTarget(false),
|
||||
mCurrentTimeBeforeSeek(0),
|
||||
mLastFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED)
|
||||
mLastFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED),
|
||||
mDecodingFrozenAtStateMetadata(false),
|
||||
mDecodingFrozenAtStateDecoding(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
@ -1356,8 +1358,9 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant)
|
||||
SetState(DECODER_STATE_DORMANT);
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
} else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) {
|
||||
mDecodingFrozenAtStateMetadata = true;
|
||||
mDecodingFrozenAtStateDecoding = true;
|
||||
ScheduleStateMachine();
|
||||
mStartTime = 0;
|
||||
mCurrentFrameTime = 0;
|
||||
SetState(DECODER_STATE_DECODING_NONE);
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
@ -1454,6 +1457,10 @@ void MediaDecoderStateMachine::Play()
|
||||
SetState(DECODER_STATE_DECODING);
|
||||
mDecodeStartTime = TimeStamp::Now();
|
||||
}
|
||||
if (mDecodingFrozenAtStateDecoding) {
|
||||
mDecodingFrozenAtStateDecoding = false;
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
// Once we start playing, we don't want to minimize our prerolling, as we
|
||||
// assume the user is likely to want to keep playing in future.
|
||||
mMinimizePreroll = false;
|
||||
@ -1515,6 +1522,8 @@ void MediaDecoderStateMachine::Seek(const SeekTarget& aTarget)
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
|
||||
mDecodingFrozenAtStateDecoding = false;
|
||||
|
||||
if (mState == DECODER_STATE_SHUTDOWN) {
|
||||
return;
|
||||
}
|
||||
@ -1622,6 +1631,11 @@ MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == DECODER_STATE_DECODING && mDecodingFrozenAtStateDecoding) {
|
||||
DECODER_LOG("DispatchDecodeTasksIfNeeded return due to "
|
||||
"mFreezeDecodingAtStateDecoding");
|
||||
return;
|
||||
}
|
||||
// NeedToDecodeAudio() can go from false to true while we hold the
|
||||
// monitor, but it can't go from true to false. This can happen because
|
||||
// NeedToDecodeAudio() takes into account the amount of decoded audio
|
||||
@ -1972,6 +1986,10 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
|
||||
SetStartTime(0);
|
||||
res = FinishDecodeMetadata();
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
} else if (mDecodingFrozenAtStateMetadata) {
|
||||
SetStartTime(mStartTime);
|
||||
res = FinishDecodeMetadata();
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
} else {
|
||||
if (HasAudio()) {
|
||||
ReentrantMonitorAutoExit unlock(mDecoder->GetReentrantMonitor());
|
||||
@ -1997,7 +2015,7 @@ MediaDecoderStateMachine::FinishDecodeMetadata()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!mScheduler->IsRealTime()) {
|
||||
if (!mScheduler->IsRealTime() && !mDecodingFrozenAtStateMetadata) {
|
||||
|
||||
const VideoData* v = VideoQueue().PeekFront();
|
||||
const AudioData* a = AudioQueue().PeekFront();
|
||||
@ -2029,6 +2047,8 @@ MediaDecoderStateMachine::FinishDecodeMetadata()
|
||||
mStartTime, mEndTime, GetDuration(),
|
||||
mDecoder->IsTransportSeekable(), mDecoder->IsMediaSeekable());
|
||||
|
||||
mDecodingFrozenAtStateMetadata = false;
|
||||
|
||||
if (HasAudio() && !HasVideo()) {
|
||||
// We're playing audio only. We don't need to worry about slow video
|
||||
// decodes causing audio underruns, so don't buffer so much audio in
|
||||
|
@ -921,6 +921,17 @@ protected:
|
||||
mozilla::MediaMetadataManager mMetadataManager;
|
||||
|
||||
MediaDecoderOwner::NextFrameStatus mLastFrameStatus;
|
||||
|
||||
// True if we are back from DECODER_STATE_DORMANT state, and we can skip
|
||||
// SetStartTime because the mStartTime already set before. Also we don't need
|
||||
// to decode any audio/video since the MediaDecoder will trigger a seek
|
||||
// operation soon.
|
||||
// mDecodingFrozenAtStateMetadata: turn on/off at
|
||||
// SetDormant/FinishDecodeMetadata.
|
||||
// mDecodingFrozenAtStateDecoding: turn on/off at
|
||||
// SetDormant/Seek,Play.
|
||||
bool mDecodingFrozenAtStateMetadata;
|
||||
bool mDecodingFrozenAtStateDecoding;
|
||||
};
|
||||
|
||||
} // namespace mozilla;
|
||||
|
@ -101,16 +101,4 @@ RtspMediaCodecReader::ReadMetadata(MediaInfo* aInfo,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Called on Binder thread.
|
||||
void
|
||||
RtspMediaCodecReader::codecReserved(Track& aTrack)
|
||||
{
|
||||
// TODO: fix me, we need a SeekTime(0) here because the
|
||||
// MediaDecoderStateMachine will update the mStartTime after ReadMetadata.
|
||||
MediaCodecReader::codecReserved(aTrack);
|
||||
if (aTrack.mCodec != nullptr) {
|
||||
mRtspResource->SeekTime(0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -65,8 +65,6 @@ public:
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
virtual void codecReserved(Track& aTrack) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// A pointer to RtspMediaResource for calling the Rtsp specific function.
|
||||
// The lifetime of mRtspResource is controlled by MediaDecoder. MediaDecoder
|
||||
|
Loading…
Reference in New Issue
Block a user