Bug 1297265: P3. Rework Apple VT use of InputExhausted. r=me

The only time we need to use InputExhausted is for the initial video decoding or when a frame is dropped.

MozReview-Commit-ID: IrHqZXJwQe1

--HG--
extra : rebase_source : eb7ff378adafe05458b79a6c3b6c7593c84d40a2
This commit is contained in:
Jean-Yves Avenard 2016-09-01 19:29:19 +10:00
Родитель eeb0e7dd1d
Коммит 92fc37ef91
2 изменённых файлов: 5 добавлений и 35 удалений

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

@ -34,11 +34,9 @@ AppleVTDecoder::AppleVTDecoder(const VideoInfo& aConfig,
, mPictureHeight(aConfig.mImage.height) , mPictureHeight(aConfig.mImage.height)
, mDisplayWidth(aConfig.mDisplay.width) , mDisplayWidth(aConfig.mDisplay.width)
, mDisplayHeight(aConfig.mDisplay.height) , mDisplayHeight(aConfig.mDisplay.height)
, mQueuedSamples(0)
, mTaskQueue(aTaskQueue) , mTaskQueue(aTaskQueue)
, mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData)) , mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData))
, mImageContainer(aImageContainer) , mImageContainer(aImageContainer)
, mInputIncoming(0)
, mIsShutDown(false) , mIsShutDown(false)
#ifdef MOZ_WIDGET_UIKIT #ifdef MOZ_WIDGET_UIKIT
, mUseSoftwareImages(true) , mUseSoftwareImages(true)
@ -88,8 +86,6 @@ AppleVTDecoder::Input(MediaRawData* aSample)
aSample->mKeyframe ? " keyframe" : "", aSample->mKeyframe ? " keyframe" : "",
aSample->Size()); aSample->Size());
mInputIncoming++;
mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>( mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
this, &AppleVTDecoder::ProcessDecode, aSample)); this, &AppleVTDecoder::ProcessDecode, aSample));
return NS_OK; return NS_OK;
@ -104,8 +100,6 @@ AppleVTDecoder::Flush()
NewRunnableMethod(this, &AppleVTDecoder::ProcessFlush); NewRunnableMethod(this, &AppleVTDecoder::ProcessFlush);
SyncRunnable::DispatchToThread(mTaskQueue, runnable); SyncRunnable::DispatchToThread(mTaskQueue, runnable);
mIsFlushing = false; mIsFlushing = false;
// All ProcessDecode() tasks should be done.
MOZ_ASSERT(mInputIncoming == 0);
mSeekTargetThreshold.reset(); mSeekTargetThreshold.reset();
@ -142,18 +136,11 @@ AppleVTDecoder::ProcessDecode(MediaRawData* aSample)
{ {
AssertOnTaskQueueThread(); AssertOnTaskQueueThread();
mInputIncoming--;
if (mIsFlushing) { if (mIsFlushing) {
return NS_OK; return NS_OK;
} }
auto rv = DoDecode(aSample); auto rv = DoDecode(aSample);
// Ask for more data.
if (NS_SUCCEEDED(rv) && !mInputIncoming && mQueuedSamples <= mMaxRefFrames) {
LOG("%s task queue empty; requesting more data", GetDescriptionName());
mCallback->InputExhausted();
}
return rv; return rv;
} }
@ -213,7 +200,6 @@ AppleVTDecoder::DrainReorderedFrames()
while (!mReorderQueue.IsEmpty()) { while (!mReorderQueue.IsEmpty()) {
mCallback->Output(mReorderQueue.Pop().get()); mCallback->Output(mReorderQueue.Pop().get());
} }
mQueuedSamples = 0;
} }
void void
@ -223,7 +209,6 @@ AppleVTDecoder::ClearReorderedFrames()
while (!mReorderQueue.IsEmpty()) { while (!mReorderQueue.IsEmpty()) {
mReorderQueue.Pop(); mReorderQueue.Pop();
} }
mQueuedSamples = 0;
} }
void void
@ -288,16 +273,10 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
aFrameRef.is_sync_point ? " keyframe" : "" aFrameRef.is_sync_point ? " keyframe" : ""
); );
if (mQueuedSamples > mMaxRefFrames) {
// We had stopped requesting more input because we had received too much at
// the time. We can ask for more once again.
mCallback->InputExhausted();
}
MOZ_ASSERT(mQueuedSamples);
mQueuedSamples--;
if (!aImage) { if (!aImage) {
// Image was dropped by decoder. // Image was dropped by decoder or none return yet.
// We need more input to continue.
mCallback->InputExhausted();
return NS_OK; return NS_OK;
} }
@ -410,9 +389,10 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
// in composition order. // in composition order.
MonitorAutoLock mon(mMonitor); MonitorAutoLock mon(mMonitor);
mReorderQueue.Push(data); mReorderQueue.Push(data);
while (mReorderQueue.Length() > mMaxRefFrames) { if (mReorderQueue.Length() > mMaxRefFrames) {
mCallback->Output(mReorderQueue.Pop().get()); mCallback->Output(mReorderQueue.Pop().get());
} }
mCallback->InputExhausted();
LOG("%llu decoded frames queued", LOG("%llu decoded frames queued",
static_cast<unsigned long long>(mReorderQueue.Length())); static_cast<unsigned long long>(mReorderQueue.Length()));
@ -480,8 +460,6 @@ AppleVTDecoder::DoDecode(MediaRawData* aSample)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
mQueuedSamples++;
VTDecodeFrameFlags decodeFlags = VTDecodeFrameFlags decodeFlags =
kVTDecodeFrame_EnableAsynchronousDecompression; kVTDecodeFrame_EnableAsynchronousDecompression;
rv = VTDecompressionSessionDecodeFrame(mSession, rv = VTDecompressionSessionDecodeFrame(mSession,

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

@ -90,11 +90,6 @@ private:
const uint32_t mDisplayWidth; const uint32_t mDisplayWidth;
const uint32_t mDisplayHeight; const uint32_t mDisplayHeight;
// Number of times a sample was queued via Input(). Will be decreased upon
// the decoder's callback being invoked.
// This is used to calculate how many frames has been buffered by the decoder.
Atomic<uint32_t> mQueuedSamples;
// Method to set up the decompression session. // Method to set up the decompression session.
nsresult InitializeSession(); nsresult InitializeSession();
nsresult WaitForAsynchronousFrames(); nsresult WaitForAsynchronousFrames();
@ -106,9 +101,6 @@ private:
const RefPtr<TaskQueue> mTaskQueue; const RefPtr<TaskQueue> mTaskQueue;
const uint32_t mMaxRefFrames; const uint32_t mMaxRefFrames;
const RefPtr<layers::ImageContainer> mImageContainer; const RefPtr<layers::ImageContainer> mImageContainer;
// Increased when Input is called, and decreased when ProcessFrame runs.
// Reaching 0 indicates that there's no pending Input.
Atomic<uint32_t> mInputIncoming;
Atomic<bool> mIsShutDown; Atomic<bool> mIsShutDown;
const bool mUseSoftwareImages; const bool mUseSoftwareImages;