Bug 1047188 - Ensure we only call MediaDataDecoder::Drain() once, and break out of MP4Reader::Decode() when DrainComplete() is called. r=kentuckyfriedtakahe

This commit is contained in:
Chris Pearce 2014-08-01 16:04:37 +12:00
Родитель 0511225e67
Коммит 3ae2cca96e
2 изменённых файлов: 26 добавлений и 7 удалений

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

@ -463,7 +463,8 @@ MP4Reader::Decode(TrackType aTrack)
// if we need output.
while (prevNumFramesOutput == data.mNumSamplesOutput &&
(data.mInputExhausted ||
(data.mNumSamplesInput - data.mNumSamplesOutput) < data.mDecodeAhead)) {
(data.mNumSamplesInput - data.mNumSamplesOutput) < data.mDecodeAhead) &&
!data.mEOS) {
data.mMonitor.AssertCurrentThreadOwns();
data.mMonitor.Unlock();
nsAutoPtr<MP4Sample> compressed(PopSample(aTrack));
@ -471,6 +472,9 @@ MP4Reader::Decode(TrackType aTrack)
// EOS, or error. Send the decoder a signal to drain.
LOG("Draining %s", TrackTypeToStr(aTrack));
data.mMonitor.Lock();
MOZ_ASSERT(!data.mEOS);
data.mEOS = true;
MOZ_ASSERT(!data.mDrainComplete);
data.mDrainComplete = false;
data.mMonitor.Unlock();
data.mDecoder->Drain();
@ -498,15 +502,27 @@ MP4Reader::Decode(TrackType aTrack)
data.mMonitor.AssertCurrentThreadOwns();
while (!data.mError &&
prevNumFramesOutput == data.mNumSamplesOutput &&
!data.mInputExhausted &&
(!data.mInputExhausted || data.mEOS) &&
!data.mDrainComplete) {
data.mMonitor.Wait();
}
if (data.mError ||
(data.mEOS && data.mDrainComplete)) {
break;
}
}
data.mMonitor.AssertCurrentThreadOwns();
bool drainComplete = data.mDrainComplete;
bool rv = !(data.mEOS || data.mError);
data.mMonitor.Unlock();
return !drainComplete;
return rv;
}
nsresult
MP4Reader::ResetDecode()
{
Flush(kAudio);
Flush(kVideo);
return MediaDecoderReader::ResetDecode();
}
void
@ -591,6 +607,8 @@ MP4Reader::Flush(TrackType aTrack)
{
MonitorAutoLock mon(data.mMonitor);
data.mIsFlushing = true;
data.mDrainComplete = false;
data.mEOS = false;
}
data.mDecoder->Flush();
{
@ -668,9 +686,6 @@ MP4Reader::Seek(int64_t aTime,
if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
return NS_ERROR_FAILURE;
}
Flush(kVideo);
Flush(kAudio);
ResetDecode();
mQueuedVideoSample = nullptr;
if (mDemuxer->HasValidVideo()) {

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

@ -58,6 +58,8 @@ public:
virtual bool IsWaitingMediaResources() MOZ_OVERRIDE;
virtual nsresult ResetDecode() MOZ_OVERRIDE;
private:
void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
@ -121,6 +123,7 @@ private:
, mError(false)
, mIsFlushing(false)
, mDrainComplete(false)
, mEOS(false)
{
}
@ -143,6 +146,7 @@ private:
bool mError;
bool mIsFlushing;
bool mDrainComplete;
bool mEOS;
};
DecoderData mAudio;
DecoderData mVideo;