void DecoderCallbackFuzzingWrapper::Shutdown() { CFW_LOGV("Clear delayed output (if any) before shutting down mTaskQueue"); ClearDelayedOutput(); // Await idle here, so that 'ClearDelayedOutput' runs to completion before // the task queue is shutdown (and tasks can't be queued anymore). mTaskQueue->AwaitIdle(); CFW_LOGV("Shutting down mTaskQueue"); mTaskQueue->BeginShutdown(); mTaskQueue->AwaitIdle(); CFW_LOGV("mTaskQueue shut down"); }
bool DecoderCallbackFuzzingWrapper::OnReaderTaskQueue() { CFW_LOGV(""); MOZ_ASSERT(mCallback); return mCallback->OnReaderTaskQueue(); }
DecoderCallbackFuzzingWrapper::DecoderCallbackFuzzingWrapper(MediaDataDecoderCallback* aCallback) : mCallback(aCallback) , mDontDelayInputExhausted(false) , mDraining(false) , mTaskQueue(new TaskQueue(SharedThreadPool::Get(NS_LITERAL_CSTRING("MediaFuzzingWrapper"), 1))) { CFW_LOGV("aCallback=%p", aCallback); }
void DecoderCallbackFuzzingWrapper::ReleaseMediaResources() { if (!mTaskQueue->IsCurrentThreadIn()) { mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::ReleaseMediaResources)); return; } CFW_LOGV(""); MOZ_ASSERT(mCallback); mCallback->ReleaseMediaResources(); }
void DecoderCallbackFuzzingWrapper::Error() { if (!mTaskQueue->IsCurrentThreadIn()) { mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::Error)); return; } CFW_LOGV(""); MOZ_ASSERT(mCallback); ClearDelayedOutput(); mCallback->Error(); }
void DecoderCallbackFuzzingWrapper::DrainComplete() { if (!mTaskQueue->IsCurrentThreadIn()) { mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::DrainComplete)); return; } MOZ_ASSERT(mCallback); if (mDelayedOutput.empty()) { // No queued output -> Draining is complete now. CFW_LOGV("No delayed output -> DrainComplete now"); mCallback->DrainComplete(); } else { // Queued output waiting -> Make sure we call DrainComplete when it's empty. CFW_LOGD("Delayed output -> DrainComplete later"); mDraining = true; } }
void DecoderCallbackFuzzingWrapper::InputExhausted() { if (!mTaskQueue->IsCurrentThreadIn()) { mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::InputExhausted)); return; } if (!mDontDelayInputExhausted && !mDelayedOutput.empty()) { MediaDataAndInputExhausted& last = mDelayedOutput.back(); CFW_LOGD("InputExhausted delayed until after output of sample@%lld", last.first()->mTime); last.second() = true; return; } CFW_LOGV(""); MOZ_ASSERT(mCallback); mCallback->InputExhausted(); }
void DecoderCallbackFuzzingWrapper::Output(MediaData* aData) { if (!mTaskQueue->IsCurrentThreadIn()) { nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethodWithArg<StorensRefPtrPassByPtr<MediaData>>( this, &DecoderCallbackFuzzingWrapper::Output, aData); mTaskQueue->Dispatch(task.forget()); return; } CFW_LOGV("aData.mTime=%lld", aData->mTime); MOZ_ASSERT(mCallback); if (mFrameOutputMinimumInterval) { if (!mPreviousOutput.IsNull()) { if (!mDelayedOutput.empty()) { // We already have some delayed frames, just add this one to the queue. mDelayedOutput.push_back(MakePair<nsRefPtr<MediaData>, bool>(aData, false)); CFW_LOGD("delaying output of sample@%lld, total queued:%d", aData->mTime, int(mDelayedOutput.size())); return; } if (TimeStamp::Now() < mPreviousOutput + mFrameOutputMinimumInterval) { // Frame arriving too soon after the previous one, start queuing. mDelayedOutput.push_back(MakePair<nsRefPtr<MediaData>, bool>(aData, false)); CFW_LOGD("delaying output of sample@%lld, first queued", aData->mTime); if (!mDelayedOutputTimer) { mDelayedOutputTimer = new MediaTimer(); } ScheduleOutputDelayedFrame(); return; } } // If we're here, we're going to actually output a frame -> Record time. mPreviousOutput = TimeStamp::Now(); } // Passing the data straight through, no need to dispatch to another queue, // callback should deal with that. mCallback->Output(aData); }
DecoderCallbackFuzzingWrapper::~DecoderCallbackFuzzingWrapper() { CFW_LOGV(""); }