зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1173657: Drain decoder when discontinuity encountered. r=cpearce
A discontinuity can be when waiting for data, decoding error or reaching end of stream.
This commit is contained in:
Родитель
3db4cce1f9
Коммит
8ca249040e
|
@ -720,6 +720,7 @@ MediaFormatReader::NotifyError(TrackType aTrack)
|
|||
LOGV("%s Decoding error", TrackTypeToStr(aTrack));
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
decoder.mError = true;
|
||||
decoder.mNeedDraining = true;
|
||||
ScheduleUpdate(aTrack);
|
||||
}
|
||||
|
||||
|
@ -729,6 +730,7 @@ MediaFormatReader::NotifyWaitingForData(TrackType aTrack)
|
|||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
decoder.mWaitingForData = true;
|
||||
decoder.mNeedDraining = true;
|
||||
ScheduleUpdate(aTrack);
|
||||
}
|
||||
|
||||
|
@ -738,6 +740,7 @@ MediaFormatReader::NotifyEndOfStream(TrackType aTrack)
|
|||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
decoder.mDemuxEOS = true;
|
||||
decoder.mNeedDraining = true;
|
||||
ScheduleUpdate(aTrack);
|
||||
}
|
||||
|
||||
|
@ -798,7 +801,6 @@ MediaFormatReader::UpdateReceivedNewData(TrackType aTrack)
|
|||
(!hasLastEnd || decoder.mTimeRanges.GetEnd() > lastEnd)) {
|
||||
// New data was added after our previous end, we can clear the EOS flag.
|
||||
decoder.mDemuxEOS = false;
|
||||
decoder.mDemuxEOSServiced = false;
|
||||
}
|
||||
|
||||
if (decoder.mError) {
|
||||
|
@ -945,6 +947,21 @@ MediaFormatReader::DecodeDemuxedSamples(TrackType aTrack,
|
|||
decoder.mInputExhausted = false;
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::DrainDecoder(TrackType aTrack)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
if (!decoder.mNeedDraining) {
|
||||
return;
|
||||
}
|
||||
decoder.mOutputRequested = true;
|
||||
decoder.mDecoder->Drain();
|
||||
decoder.mNeedDraining = false;
|
||||
LOG("Requesting %s decoder to drain", TrackTypeToStr(aTrack));
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::Update(TrackType aTrack)
|
||||
{
|
||||
|
@ -966,23 +983,6 @@ MediaFormatReader::Update(TrackType aTrack)
|
|||
return;
|
||||
}
|
||||
|
||||
if (decoder.HasPromise()) {
|
||||
// Handle pending requests from the MediaDecoderStateMachine.
|
||||
if (decoder.mError) {
|
||||
LOG("Decoding Error");
|
||||
decoder.RejectPromise(DECODE_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
if (decoder.mWaitingForData) {
|
||||
LOG("Waiting For Data");
|
||||
decoder.RejectPromise(WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
} else if (decoder.mWaitingForData) {
|
||||
// Nothing more we can do at present.
|
||||
LOGV("Still waiting for data.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Record number of frames decoded and parsed. Automatically update the
|
||||
// stats counters using the AutoNotifyDecoded stack-based class.
|
||||
AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder);
|
||||
|
@ -993,6 +993,7 @@ MediaFormatReader::Update(TrackType aTrack)
|
|||
a.mDecoded = static_cast<uint32_t>(delta);
|
||||
mLastReportedNumDecodedFrames = decoder.mNumSamplesOutput;
|
||||
}
|
||||
|
||||
if (decoder.HasPromise()) {
|
||||
needOutput = true;
|
||||
if (!decoder.mOutput.IsEmpty()) {
|
||||
|
@ -1011,16 +1012,22 @@ MediaFormatReader::Update(TrackType aTrack)
|
|||
output->mKeyframe);
|
||||
}
|
||||
} else if (decoder.mDrainComplete) {
|
||||
decoder.RejectPromise(END_OF_STREAM, __func__);
|
||||
decoder.mDrainComplete = false;
|
||||
if (decoder.mError) {
|
||||
LOG("Decoding Error");
|
||||
decoder.RejectPromise(DECODE_ERROR, __func__);
|
||||
return;
|
||||
} else if (decoder.mDemuxEOS) {
|
||||
decoder.RejectPromise(END_OF_STREAM, __func__);
|
||||
} else if (decoder.mWaitingForData) {
|
||||
LOG("Waiting For Data");
|
||||
decoder.RejectPromise(WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder.mDemuxEOS && !decoder.mDemuxEOSServiced) {
|
||||
decoder.mOutputRequested = true;
|
||||
decoder.mDecoder->Drain();
|
||||
decoder.mDemuxEOSServiced = true;
|
||||
LOGV("Requesting decoder to drain");
|
||||
if (decoder.mError || decoder.mDemuxEOS || decoder.mWaitingForData) {
|
||||
DrainDecoder(aTrack);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,8 @@ private:
|
|||
// Decode any pending already demuxed samples.
|
||||
void DecodeDemuxedSamples(TrackType aTrack,
|
||||
AbstractMediaDecoder::AutoNotifyDecoded& aA);
|
||||
// Drain the current decoder.
|
||||
void DrainDecoder(TrackType aTrack);
|
||||
void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
|
||||
void NotifyInputExhausted(TrackType aTrack);
|
||||
void NotifyDrainComplete(TrackType aTrack);
|
||||
|
@ -188,13 +190,13 @@ private:
|
|||
, mForceDecodeAhead(false)
|
||||
, mUpdateScheduled(false)
|
||||
, mDemuxEOS(false)
|
||||
, mDemuxEOSServiced(false)
|
||||
, mWaitingForData(false)
|
||||
, mReceivedNewData(false)
|
||||
, mDiscontinuity(true)
|
||||
, mOutputRequested(false)
|
||||
, mInputExhausted(false)
|
||||
, mError(false)
|
||||
, mNeedDraining(false)
|
||||
, mDrainComplete(false)
|
||||
, mNumSamplesInput(0)
|
||||
, mNumSamplesOutput(0)
|
||||
|
@ -219,7 +221,6 @@ private:
|
|||
bool mForceDecodeAhead;
|
||||
bool mUpdateScheduled;
|
||||
bool mDemuxEOS;
|
||||
bool mDemuxEOSServiced;
|
||||
bool mWaitingForData;
|
||||
bool mReceivedNewData;
|
||||
bool mDiscontinuity;
|
||||
|
@ -241,6 +242,7 @@ private:
|
|||
bool mOutputRequested;
|
||||
bool mInputExhausted;
|
||||
bool mError;
|
||||
bool mNeedDraining;
|
||||
bool mDrainComplete;
|
||||
// If set, all decoded samples prior mTimeThreshold will be dropped.
|
||||
// Used for internal seeking when a change of stream is detected.
|
||||
|
@ -270,13 +272,13 @@ private:
|
|||
MOZ_ASSERT(mOwner->OnTaskQueue());
|
||||
mForceDecodeAhead = false;
|
||||
mDemuxEOS = false;
|
||||
mDemuxEOSServiced = false;
|
||||
mWaitingForData = false;
|
||||
mReceivedNewData = false;
|
||||
mDiscontinuity = true;
|
||||
mQueuedSamples.Clear();
|
||||
mOutputRequested = false;
|
||||
mInputExhausted = false;
|
||||
mNeedDraining = false;
|
||||
mDrainComplete = false;
|
||||
mTimeThreshold.reset();
|
||||
mOutput.Clear();
|
||||
|
|
Загрузка…
Ссылка в новой задаче