mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1039128 - Fix drain of video queue
This commit is contained in:
parent
bc2513235c
commit
9b31f46826
@ -77,6 +77,7 @@ public:
|
||||
}
|
||||
|
||||
virtual nsresult Drain() MOZ_OVERRIDE {
|
||||
mCallback->DrainComplete();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -349,41 +349,45 @@ MP4Reader::Decode(TrackType aTrack)
|
||||
data.mMonitor.Unlock();
|
||||
nsAutoPtr<MP4Sample> compressed(PopSample(aTrack));
|
||||
if (!compressed) {
|
||||
// EOS, or error. Let the state machine know there are no more
|
||||
// frames coming.
|
||||
// EOS, or error. Send the decoder a signal to drain.
|
||||
LOG("Draining %s", TrackTypeToStr(aTrack));
|
||||
data.mMonitor.Lock();
|
||||
data.mDrainComplete = false;
|
||||
data.mMonitor.Unlock();
|
||||
data.mDecoder->Drain();
|
||||
return false;
|
||||
} else {
|
||||
#ifdef LOG_SAMPLE_DECODE
|
||||
LOG("PopSample %s time=%lld dur=%lld", TrackTypeToStr(aTrack),
|
||||
compressed->composition_timestamp, compressed->duration);
|
||||
#endif
|
||||
}
|
||||
data.mMonitor.Lock();
|
||||
data.mInputExhausted = false;
|
||||
data.mNumSamplesInput++;
|
||||
data.mMonitor.Unlock();
|
||||
data.mMonitor.Lock();
|
||||
data.mDrainComplete = false;
|
||||
data.mInputExhausted = false;
|
||||
data.mNumSamplesInput++;
|
||||
data.mMonitor.Unlock();
|
||||
|
||||
if (NS_FAILED(data.mDecoder->Input(compressed))) {
|
||||
return false;
|
||||
if (NS_FAILED(data.mDecoder->Input(compressed))) {
|
||||
return false;
|
||||
}
|
||||
// If Input() failed, we let the auto pointer delete |compressed|.
|
||||
// Otherwise, we assume the decoder will delete it when it's finished
|
||||
// with it.
|
||||
compressed.forget();
|
||||
}
|
||||
// If Input() failed, we let the auto pointer delete |compressed|.
|
||||
// Otherwise, we assume the decoder will delete it when it's finished
|
||||
// with it.
|
||||
compressed.forget();
|
||||
data.mMonitor.Lock();
|
||||
}
|
||||
data.mMonitor.AssertCurrentThreadOwns();
|
||||
while (!data.mError &&
|
||||
prevNumFramesOutput == data.mNumSamplesOutput &&
|
||||
!data.mInputExhausted ) {
|
||||
!data.mInputExhausted &&
|
||||
!data.mDrainComplete) {
|
||||
data.mMonitor.Wait();
|
||||
}
|
||||
}
|
||||
data.mMonitor.AssertCurrentThreadOwns();
|
||||
bool drainComplete = data.mDrainComplete;
|
||||
data.mMonitor.Unlock();
|
||||
return true;
|
||||
return !drainComplete;
|
||||
}
|
||||
|
||||
void
|
||||
@ -421,6 +425,15 @@ MP4Reader::Output(TrackType aTrack, MediaData* aSample)
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
MP4Reader::DrainComplete(TrackType aTrack)
|
||||
{
|
||||
DecoderData& data = GetDecoderData(aTrack);
|
||||
MonitorAutoLock mon(data.mMonitor);
|
||||
data.mDrainComplete = true;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
MP4Reader::InputExhausted(TrackType aTrack)
|
||||
{
|
||||
|
@ -74,6 +74,7 @@ private:
|
||||
void Error(mp4_demuxer::TrackType aTrack);
|
||||
bool Decode(mp4_demuxer::TrackType aTrack);
|
||||
void Flush(mp4_demuxer::TrackType aTrack);
|
||||
void DrainComplete(mp4_demuxer::TrackType aTrack);
|
||||
|
||||
nsAutoPtr<mp4_demuxer::MP4Demuxer> mDemuxer;
|
||||
nsAutoPtr<PlatformDecoderModule> mPlatform;
|
||||
@ -95,6 +96,9 @@ private:
|
||||
virtual void Error() MOZ_OVERRIDE {
|
||||
mReader->Error(mType);
|
||||
}
|
||||
virtual void DrainComplete() MOZ_OVERRIDE {
|
||||
mReader->DrainComplete(mType);
|
||||
}
|
||||
private:
|
||||
MP4Reader* mReader;
|
||||
mp4_demuxer::TrackType mType;
|
||||
@ -111,6 +115,7 @@ private:
|
||||
, mInputExhausted(false)
|
||||
, mError(false)
|
||||
, mIsFlushing(false)
|
||||
, mDrainComplete(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -132,6 +137,7 @@ private:
|
||||
bool mInputExhausted;
|
||||
bool mError;
|
||||
bool mIsFlushing;
|
||||
bool mDrainComplete;
|
||||
};
|
||||
DecoderData mAudio;
|
||||
DecoderData mVideo;
|
||||
|
@ -129,6 +129,8 @@ public:
|
||||
// Denotes that the last input sample has been inserted into the decoder,
|
||||
// and no more output can be produced unless more input is sent.
|
||||
virtual void InputExhausted() = 0;
|
||||
|
||||
virtual void DrainComplete() = 0;
|
||||
};
|
||||
|
||||
// MediaDataDecoder is the interface exposed by decoders created by the
|
||||
@ -173,14 +175,16 @@ public:
|
||||
// The MP4Reader will not call Input() while it's calling Flush().
|
||||
virtual nsresult Flush() = 0;
|
||||
|
||||
|
||||
// Causes all complete samples in the pipeline that can be decoded to be
|
||||
// output. If the decoder can't produce samples from the current output,
|
||||
// it drops the input samples. The decoder may be holding onto samples
|
||||
// that are required to decode samples that it expects to get in future.
|
||||
// This is called when the demuxer reaches end of stream.
|
||||
// The MP4Reader will not call Input() while it's calling Drain().
|
||||
// This function is synchronous. Once it's returned, all samples to be
|
||||
// output should have been returned via callback to the MP4Reader.
|
||||
// This function is asynchronous. The MediaDataDecoder must call
|
||||
// MediaDataDecoderCallback::DrainComplete() once all remaining
|
||||
// samples have been output.
|
||||
virtual nsresult Drain() = 0;
|
||||
|
||||
// Cancels all init/input/drain operations, and shuts down the
|
||||
|
@ -117,7 +117,7 @@ FFmpegAACDecoder<LIBAV_VER>::Input(MP4Sample* aSample)
|
||||
nsresult
|
||||
FFmpegAACDecoder<LIBAV_VER>::Drain()
|
||||
{
|
||||
// AAC is never delayed; nothing to do here.
|
||||
mCallback->DrainComplete();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -223,6 +223,12 @@ FFmpegH264Decoder<LIBAV_VER>::Input(mp4_demuxer::MP4Sample* aSample)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
FFmpegH264Decoder<LIBAV_VER>::NotifyDrain()
|
||||
{
|
||||
mCallback->DrainComplete();
|
||||
}
|
||||
|
||||
nsresult
|
||||
FFmpegH264Decoder<LIBAV_VER>::Drain()
|
||||
{
|
||||
@ -236,6 +242,8 @@ FFmpegH264Decoder<LIBAV_VER>::Drain()
|
||||
nsresult rv = Input(empty.forget());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
mTaskQueue->Dispatch(
|
||||
NS_NewRunnableMethod(this, &FFmpegH264Decoder<LIBAV_VER>::NotifyDrain));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
|
||||
private:
|
||||
void DecodeFrame(mp4_demuxer::MP4Sample* aSample);
|
||||
void NotifyDrain();
|
||||
void OutputDelayedFrames();
|
||||
|
||||
/**
|
||||
|
@ -124,6 +124,7 @@ WMFMediaDataDecoder::ProcessDrain()
|
||||
}
|
||||
// Then extract all available output.
|
||||
ProcessOutput();
|
||||
mCallback->DrainComplete();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -216,8 +216,6 @@ MP4Sample::Update()
|
||||
void
|
||||
MP4Sample::Pad(size_t aPaddingBytes)
|
||||
{
|
||||
MOZ_ASSERT(data == mMediaBuffer->data());
|
||||
|
||||
size_t newSize = size + aPaddingBytes;
|
||||
|
||||
// If the existing MediaBuffer has enough space then we just recycle it. If
|
||||
|
Loading…
Reference in New Issue
Block a user