Bug 1025768 - Restore eager SourceBuffer switching. r=cajbir

This commit is contained in:
Matthew Gregan 2014-07-17 21:31:00 +12:00
Родитель df3c03ce18
Коммит 5104db1529
1 изменённых файлов: 21 добавлений и 18 удалений

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

@ -68,7 +68,7 @@ public:
void RequestAudioData() MOZ_OVERRIDE void RequestAudioData() MOZ_OVERRIDE
{ {
if (!GetAudioReader()) { if (!GetAudioReader()) {
MSE_DEBUG("%p DecodeAudioFrame called with no audio reader", this); MSE_DEBUG("%p MSR::RequestAudioData called with no audio reader", this);
MOZ_ASSERT(mPendingDecoders.IsEmpty()); MOZ_ASSERT(mPendingDecoders.IsEmpty());
GetCallback()->OnDecodeError(); GetCallback()->OnDecodeError();
return; return;
@ -83,18 +83,21 @@ public:
void OnAudioEOS() void OnAudioEOS()
{ {
MSE_DEBUG("%p OnAudioEOS %d (%p) EOS (readers=%u)",
this, mActiveAudioDecoder, mDecoders[mActiveAudioDecoder].get(), mDecoders.Length());
GetCallback()->OnAudioEOS(); GetCallback()->OnAudioEOS();
} }
void RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) MOZ_OVERRIDE void RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) MOZ_OVERRIDE
{ {
if (!GetVideoReader()) { if (!GetVideoReader()) {
MSE_DEBUG("%p DecodeVideoFrame called with no video reader", this); MSE_DEBUG("%p MSR::RequestVideoData called with no video reader", this);
MOZ_ASSERT(mPendingDecoders.IsEmpty()); MOZ_ASSERT(mPendingDecoders.IsEmpty());
GetCallback()->OnDecodeError(); GetCallback()->OnDecodeError();
return; return;
} }
mTimeThreshold = aTimeThreshold; mTimeThreshold = aTimeThreshold;
SwitchVideoReaders(SWITCH_OPTIONAL);
GetVideoReader()->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold); GetVideoReader()->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold);
} }
@ -102,28 +105,28 @@ public:
{ {
if (mDropVideoBeforeThreshold) { if (mDropVideoBeforeThreshold) {
if (aSample->mTime < mTimeThreshold) { if (aSample->mTime < mTimeThreshold) {
MSE_DEBUG("%p MSR::OnVideoDecoded VideoData mTime %lld below mTimeThreshold %lld",
this, aSample->mTime, mTimeThreshold);
delete aSample; delete aSample;
GetVideoReader()->RequestVideoData(false, mTimeThreshold); GetVideoReader()->RequestVideoData(false, mTimeThreshold);
} else { return;
mDropVideoBeforeThreshold = false;
GetCallback()->OnVideoDecoded(aSample);
} }
} else { mDropVideoBeforeThreshold = false;
GetCallback()->OnVideoDecoded(aSample);
} }
GetCallback()->OnVideoDecoded(aSample);
} }
void OnVideoEOS() void OnVideoEOS()
{ {
// End of stream. See if we can switch to another video decoder. // End of stream. See if we can switch to another video decoder.
MSE_DEBUG("%p MSR::DecodeVF %d (%p) returned false (readers=%u)", MSE_DEBUG("%p MSR::OnVideoEOS %d (%p) (readers=%u)",
this, mActiveVideoDecoder, mDecoders[mActiveVideoDecoder].get(), mDecoders.Length()); this, mActiveVideoDecoder, mDecoders[mActiveVideoDecoder].get(), mDecoders.Length());
if (MaybeSwitchVideoReaders()) { if (SwitchVideoReaders(SWITCH_FORCED)) {
// Success! Resume decoding with next video decoder. // Success! Resume decoding with next video decoder.
RequestVideoData(false, mTimeThreshold); RequestVideoData(false, mTimeThreshold);
} else { } else {
// End of stream. // End of stream.
MSE_DEBUG("%p MSR::DecodeVF %d (%p) EOS (readers=%u)", MSE_DEBUG("%p MSR::OnVideoEOS %d (%p) EOS (readers=%u)",
this, mActiveVideoDecoder, mDecoders[mActiveVideoDecoder].get(), mDecoders.Length()); this, mActiveVideoDecoder, mDecoders[mActiveVideoDecoder].get(), mDecoders.Length());
GetCallback()->OnVideoEOS(); GetCallback()->OnVideoEOS();
} }
@ -175,17 +178,16 @@ public:
} }
private: private:
// These are read and written on the decode task queue threads. // These are read and written on the decode task queue threads.
int64_t mTimeThreshold; int64_t mTimeThreshold;
bool mDropVideoBeforeThreshold; bool mDropVideoBeforeThreshold;
enum SwitchState { enum SwitchType {
SWITCHSTATE_SEEKING, SWITCH_OPTIONAL,
SWITCHSTATE_PLAYING SWITCH_FORCED
}; };
bool MaybeSwitchVideoReaders(SwitchState aState = SWITCHSTATE_PLAYING) { bool SwitchVideoReaders(SwitchType aType) {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
MOZ_ASSERT(mActiveVideoDecoder != -1); MOZ_ASSERT(mActiveVideoDecoder != -1);
@ -197,11 +199,12 @@ private:
continue; continue;
} }
if (aState == SWITCHSTATE_SEEKING || mTimeThreshold >= mDecoders[i]->GetMediaStartTime()) { if (aType == SWITCH_FORCED || mTimeThreshold >= mDecoders[i]->GetMediaStartTime()) {
GetVideoReader()->SetIdle(); GetVideoReader()->SetIdle();
mActiveVideoDecoder = i; mActiveVideoDecoder = i;
MSE_DEBUG("%p MSR::DecodeVF switching to %d", this, mActiveVideoDecoder); mDropVideoBeforeThreshold = true;
MSE_DEBUG("%p MSR::SwitchVideoReaders(%d) switching to %d", this, aType, mActiveVideoDecoder);
return true; return true;
} }
} }
@ -484,7 +487,7 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
while (!mMediaSource->ActiveSourceBuffers()->AllContainsTime(target) while (!mMediaSource->ActiveSourceBuffers()->AllContainsTime(target)
&& !IsShutdown()) { && !IsShutdown()) {
mMediaSource->WaitForData(); mMediaSource->WaitForData();
MaybeSwitchVideoReaders(SWITCHSTATE_SEEKING); SwitchVideoReaders(SWITCH_FORCED);
} }
if (IsShutdown()) { if (IsShutdown()) {