Bug 1319987: P2. Remove FuzzingWrapper. r?gerald draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 21 Dec 2016 10:52:01 +1100
changeset 479119 a72ed1b6f93049216581900e501b593d75b69e97
parent 479118 990ce9b365e5a1037628bc1deaa2825bb8cece40
child 479120 e34e0e55075fb4db0a81458b615f2d95f19f72e4
push id44146
push userbmo:jyavenard@mozilla.com
push dateSun, 05 Feb 2017 21:13:07 +0000
reviewersgerald
bugs1319987
milestone54.0a1
Bug 1319987: P2. Remove FuzzingWrapper. r?gerald It is no longer used and in its current state incompatible with promise based decoders. We'll re-add it later. MozReview-Commit-ID: DHsyTsFvTZB
dom/media/platforms/PDMFactory.cpp
dom/media/platforms/moz.build
dom/media/platforms/wrappers/FuzzingWrapper.cpp
dom/media/platforms/wrappers/FuzzingWrapper.h
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -30,17 +30,16 @@
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/TaskQueue.h"
 
 #include "MediaInfo.h"
 #include "MediaPrefs.h"
-#include "FuzzingWrapper.h"
 #include "H264Converter.h"
 
 #include "AgnosticDecoderModule.h"
 #include "EMEDecoderModule.h"
 
 #include "DecoderDoctorDiagnostics.h"
 
 #include "MP4Decoder.h"
@@ -282,44 +281,27 @@ PDMFactory::CreateDecoderWithPDM(Platfor
   }
 
   if (!config.IsVideo()) {
     *result = MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                           RESULT_DETAIL("Decoder configuration error, expected audio or video."));
     return nullptr;
   }
 
-  MediaDataDecoderCallback* callback = aParams.mCallback;
-  RefPtr<DecoderCallbackFuzzingWrapper> callbackWrapper;
-  if (MediaPrefs::PDMFuzzingEnabled()) {
-    callbackWrapper = new DecoderCallbackFuzzingWrapper(callback);
-    callbackWrapper->SetVideoOutputMinimumInterval(
-      TimeDuration::FromMilliseconds(MediaPrefs::PDMFuzzingInterval()));
-    callbackWrapper->SetDontDelayInputExhausted(!MediaPrefs::PDMFuzzingDelayInputExhausted());
-    callback = callbackWrapper.get();
-  }
-
-  CreateDecoderParams params = aParams;
-  params.mCallback = callback;
-
   if (MP4Decoder::IsH264(config.mMimeType) && !aParams.mUseBlankDecoder) {
-    RefPtr<H264Converter> h = new H264Converter(aPDM, params);
+    RefPtr<H264Converter> h = new H264Converter(aPDM, aParams);
     const nsresult rv = h->GetLastError();
     if (NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_INITIALIZED) {
       // The H264Converter either successfully created the wrapped decoder,
       // or there wasn't enough AVCC data to do so. Otherwise, there was some
       // problem, for example WMF DLLs were missing.
       m = h.forget();
     }
   } else {
-    m = aPDM->CreateVideoDecoder(params);
-  }
-
-  if (callbackWrapper && m) {
-    m = new DecoderFuzzingWrapper(m.forget(), callbackWrapper.forget());
+    m = aPDM->CreateVideoDecoder(aParams);
   }
 
   return m.forget();
 }
 
 bool
 PDMFactory::SupportsMimeType(const nsACString& aMimeType,
                              DecoderDoctorDiagnostics* aDiagnostics) const
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -8,30 +8,28 @@ EXPORTS += [
     'agnostic/AgnosticDecoderModule.h',
     'agnostic/OpusDecoder.h',
     'agnostic/TheoraDecoder.h',
     'agnostic/VorbisDecoder.h',
     'agnostic/VPXDecoder.h',
     'MediaTelemetryConstants.h',
     'PDMFactory.h',
     'PlatformDecoderModule.h',
-    'wrappers/FuzzingWrapper.h',
     'wrappers/H264Converter.h'
 ]
 
 UNIFIED_SOURCES += [
     'agnostic/AgnosticDecoderModule.cpp',
     'agnostic/BlankDecoderModule.cpp',
     'agnostic/OpusDecoder.cpp',
     'agnostic/TheoraDecoder.cpp',
     'agnostic/VorbisDecoder.cpp',
     'agnostic/VPXDecoder.cpp',
     'agnostic/WAVDecoder.cpp',
     'PDMFactory.cpp',
-    'wrappers/FuzzingWrapper.cpp',
     'wrappers/H264Converter.cpp'
 ]
 
 DIRS += [
     'agnostic/eme',
     'agnostic/gmp',
     'omx'
 ]
deleted file mode 100644
--- a/dom/media/platforms/wrappers/FuzzingWrapper.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "FuzzingWrapper.h"
-
-mozilla::LogModule* GetFuzzingWrapperLog() {
-  static mozilla::LazyLogModule log("MediaFuzzingWrapper");
-  return log;
-}
-#define DFW_LOGD(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Debug, ("DecoderFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define DFW_LOGV(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Verbose, ("DecoderFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define CFW_LOGD(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Debug, ("DecoderCallbackFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define CFW_LOGV(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Verbose, ("DecoderCallbackFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-
-namespace mozilla {
-
-DecoderFuzzingWrapper::DecoderFuzzingWrapper(
-    already_AddRefed<MediaDataDecoder> aDecoder,
-    already_AddRefed<DecoderCallbackFuzzingWrapper> aCallbackWrapper)
-  : mDecoder(aDecoder)
-  , mCallbackWrapper(aCallbackWrapper)
-{
-  DFW_LOGV("aDecoder=%p aCallbackWrapper=%p", mDecoder.get(), mCallbackWrapper.get());
-}
-
-DecoderFuzzingWrapper::~DecoderFuzzingWrapper()
-{
-  DFW_LOGV("");
-}
-
-RefPtr<MediaDataDecoder::InitPromise>
-DecoderFuzzingWrapper::Init()
-{
-  DFW_LOGV("");
-  MOZ_ASSERT(mDecoder);
-  return mDecoder->Init();
-}
-
-void
-DecoderFuzzingWrapper::Input(MediaRawData* aData)
-{
-  DFW_LOGV("aData.mTime=%lld", aData->mTime);
-  MOZ_ASSERT(mDecoder);
-  mDecoder->Input(aData);
-}
-
-void
-DecoderFuzzingWrapper::Flush()
-{
-  DFW_LOGV("Calling mDecoder[%p]->Flush()", mDecoder.get());
-  MOZ_ASSERT(mDecoder);
-  // Flush may output some frames (though unlikely).
-  // Flush may block a bit, it's ok if we output some frames in the meantime.
-  mDecoder->Flush();
-  DFW_LOGV("mDecoder[%p]->Flush()", mDecoder.get());
-  // Clear any delayed output we may have.
-  mCallbackWrapper->ClearDelayedOutput();
-}
-
-void
-DecoderFuzzingWrapper::Drain()
-{
-  DFW_LOGV("");
-  MOZ_ASSERT(mDecoder);
-  // Note: The decoder should callback DrainComplete(), we'll drain the
-  // delayed output (if any) then.
-  mDecoder->Drain();
-}
-
-void
-DecoderFuzzingWrapper::Shutdown()
-{
-  DFW_LOGV("");
-  MOZ_ASSERT(mDecoder);
-  // Both shutdowns below may block a bit.
-  mDecoder->Shutdown();
-  mCallbackWrapper->Shutdown();
-}
-
-bool
-DecoderFuzzingWrapper::IsHardwareAccelerated(nsACString& aFailureReason) const
-{
-  DFW_LOGV("");
-  MOZ_ASSERT(mDecoder);
-  return mDecoder->IsHardwareAccelerated(aFailureReason);
-}
-
-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);
-}
-
-DecoderCallbackFuzzingWrapper::~DecoderCallbackFuzzingWrapper()
-{
-  CFW_LOGV("");
-}
-
-void
-DecoderCallbackFuzzingWrapper::SetVideoOutputMinimumInterval(
-  TimeDuration aFrameOutputMinimumInterval)
-{
-  CFW_LOGD("aFrameOutputMinimumInterval=%fms",
-      aFrameOutputMinimumInterval.ToMilliseconds());
-  mFrameOutputMinimumInterval = aFrameOutputMinimumInterval;
-}
-
-void
-DecoderCallbackFuzzingWrapper::SetDontDelayInputExhausted(
-  bool aDontDelayInputExhausted)
-{
-  CFW_LOGD("aDontDelayInputExhausted=%d",
-      aDontDelayInputExhausted);
-  mDontDelayInputExhausted = aDontDelayInputExhausted;
-}
-
-void
-DecoderCallbackFuzzingWrapper::Output(MediaData* aData)
-{
-  if (!mTaskQueue->IsCurrentThreadIn()) {
-    nsCOMPtr<nsIRunnable> task =
-      NewRunnableMethod<StoreRefPtrPassByPtr<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<RefPtr<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<RefPtr<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);
-}
-
-void
-DecoderCallbackFuzzingWrapper::Error(const MediaResult& aError)
-{
-  if (!mTaskQueue->IsCurrentThreadIn()) {
-    mTaskQueue->Dispatch(NewRunnableMethod<MediaResult>(
-      this, &DecoderCallbackFuzzingWrapper::Error, aError));
-    return;
-  }
-  CFW_LOGV("");
-  MOZ_ASSERT(mCallback);
-  ClearDelayedOutput();
-  mCallback->Error(aError);
-}
-
-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::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::ReleaseMediaResources()
-{
-  if (!mTaskQueue->IsCurrentThreadIn()) {
-    mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::ReleaseMediaResources));
-    return;
-  }
-  CFW_LOGV("");
-  MOZ_ASSERT(mCallback);
-  mCallback->ReleaseMediaResources();
-}
-
-bool
-DecoderCallbackFuzzingWrapper::OnReaderTaskQueue()
-{
-  CFW_LOGV("");
-  MOZ_ASSERT(mCallback);
-  return mCallback->OnReaderTaskQueue();
-}
-
-void
-DecoderCallbackFuzzingWrapper::ScheduleOutputDelayedFrame()
-{
-  MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-  if (mDelayedOutputRequest.Exists()) {
-    // A delayed output is already scheduled, no need for more than one timer.
-    return;
-  }
-  RefPtr<DecoderCallbackFuzzingWrapper> self = this;
-  mDelayedOutputTimer->WaitUntil(
-    mPreviousOutput + mFrameOutputMinimumInterval,
-    __func__)
-  ->Then(mTaskQueue, __func__,
-         [self] () -> void {
-           if (self->mDelayedOutputRequest.Exists()) {
-             self->mDelayedOutputRequest.Complete();
-             self->OutputDelayedFrame();
-           }
-         },
-         [self] () -> void {
-           if (self->mDelayedOutputRequest.Exists()) {
-             self->mDelayedOutputRequest.Complete();
-             self->ClearDelayedOutput();
-           }
-         })
-  ->Track(mDelayedOutputRequest);
-}
-
-void
-DecoderCallbackFuzzingWrapper::OutputDelayedFrame()
-{
-  MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-  if (mDelayedOutput.empty()) {
-    if (mDraining) {
-      // No more output, and we were draining -> Send DrainComplete.
-      mDraining = false;
-      mCallback->DrainComplete();
-    }
-    return;
-  }
-  MediaDataAndInputExhausted& data = mDelayedOutput.front();
-  CFW_LOGD("Outputting delayed sample@%lld, remaining:%d",
-          data.first()->mTime, int(mDelayedOutput.size() - 1));
-  mPreviousOutput = TimeStamp::Now();
-  mCallback->Output(data.first());
-  if (data.second()) {
-    CFW_LOGD("InputExhausted after delayed sample@%lld", data.first()->mTime);
-    mCallback->InputExhausted();
-  }
-  mDelayedOutput.pop_front();
-  if (!mDelayedOutput.empty()) {
-    // More output -> Send it later.
-    ScheduleOutputDelayedFrame();
-  } else if (mDraining) {
-    // No more output, and we were draining -> Send DrainComplete.
-    CFW_LOGD("DrainComplete");
-    mDraining = false;
-    mCallback->DrainComplete();
-  }
-}
-
-void
-DecoderCallbackFuzzingWrapper::ClearDelayedOutput()
-{
-  if (!mTaskQueue->IsCurrentThreadIn()) {
-    DFW_LOGV("(dispatching self)");
-    mTaskQueue->Dispatch(NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::ClearDelayedOutput));
-    return;
-  }
-  DFW_LOGV("");
-  // In case a timer hasn't lapsed yet, before destroying the timer and its
-  // attached waitUntil() promise, the 'Then' request must be disconnected.
-  mDelayedOutputRequest.DisconnectIfExists();
-  mDelayedOutputTimer = nullptr;
-  mDelayedOutput.clear();
-}
-
-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");
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/platforms/wrappers/FuzzingWrapper.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(FuzzingWrapper_h_)
-#define FuzzingWrapper_h_
-
-#include "mozilla/Pair.h"
-#include "PlatformDecoderModule.h"
-
-#include <deque>
-
-namespace mozilla {
-
-// Fuzzing wrapper for media decoders.
-//
-// DecoderFuzzingWrapper owns the DecoderCallbackFuzzingWrapper, and inserts
-// itself between the reader and the decoder.
-// DecoderCallbackFuzzingWrapper inserts itself between a decoder and its
-// callback.
-// Together they are used to introduce some fuzzing, (e.g. delay output).
-//
-// Normally:
-//          ====================================>
-//   reader                                       decoder
-//          <------------------------------------
-//
-// With fuzzing:
-//          ======> DecoderFuzzingWrapper ======>
-//   reader                  v                    decoder
-//          <-- DecoderCallbackFuzzingWrapper <--
-//
-// Creation order should be:
-// 1. Create DecoderCallbackFuzzingWrapper, give the expected callback target.
-// 2. Create actual decoder, give DecoderCallbackFuzzingWrapper as callback.
-// 3. Create DecoderFuzzingWrapper, give decoder and DecoderCallbackFuzzingWrapper.
-// DecoderFuzzingWrapper is what the reader sees as decoder, it owns the
-// real decoder and the DecoderCallbackFuzzingWrapper.
-
-class DecoderCallbackFuzzingWrapper : public MediaDataDecoderCallback
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecoderCallbackFuzzingWrapper)
-
-  explicit DecoderCallbackFuzzingWrapper(MediaDataDecoderCallback* aCallback);
-
-  // Enforce a minimum interval between output frames (i.e., limit frame rate).
-  // Of course, if the decoder is even slower, this won't have any effect.
-  void SetVideoOutputMinimumInterval(TimeDuration aFrameOutputMinimumInterval);
-  // If false (default), if frames are delayed, any InputExhausted is delayed to
-  // be later sent after the corresponding delayed frame.
-  // If true, InputExhausted are passed through immediately; This could result
-  // in lots of frames being decoded and queued for delayed output!
-  void SetDontDelayInputExhausted(bool aDontDelayInputExhausted);
-
-private:
-  virtual ~DecoderCallbackFuzzingWrapper();
-
-  // MediaDataDecoderCallback implementation.
-  void Output(MediaData* aData) override;
-  void Error(const MediaResult& aError) override;
-  void InputExhausted() override;
-  void DrainComplete() override;
-  void ReleaseMediaResources() override;
-  bool OnReaderTaskQueue() override;
-
-  MediaDataDecoderCallback* mCallback;
-
-  // Settings for minimum frame output interval & InputExhausted,
-  // should be set during init and then only read on mTaskQueue.
-  TimeDuration mFrameOutputMinimumInterval;
-  bool mDontDelayInputExhausted;
-  // Members for minimum frame output interval & InputExhausted,
-  // should only be accessed on mTaskQueue.
-  TimeStamp mPreviousOutput;
-  // First member is the frame to be delayed.
-  // Second member is true if an 'InputExhausted' arrived after that frame; in
-  // which case an InputExhausted will be sent after finally outputting the frame.
-  typedef Pair<RefPtr<MediaData>, bool> MediaDataAndInputExhausted;
-  std::deque<MediaDataAndInputExhausted> mDelayedOutput;
-  RefPtr<MediaTimer> mDelayedOutputTimer;
-  MozPromiseRequestHolder<MediaTimerPromise> mDelayedOutputRequest;
-  // If draining, a 'DrainComplete' will be sent after all delayed frames have
-  // been output.
-  bool mDraining;
-  // All callbacks are redirected through this task queue, both to avoid locking
-  // and to have a consistent sequencing of callbacks.
-  RefPtr<TaskQueue> mTaskQueue;
-  void ScheduleOutputDelayedFrame();
-  void OutputDelayedFrame();
-public: // public for the benefit of DecoderFuzzingWrapper.
-  void ClearDelayedOutput();
-  void Shutdown();
-};
-
-class DecoderFuzzingWrapper : public MediaDataDecoder
-{
-public:
-  DecoderFuzzingWrapper(already_AddRefed<MediaDataDecoder> aDecoder,
-                        already_AddRefed<DecoderCallbackFuzzingWrapper> aCallbackWrapper);
-
-  // MediaDataDecoder implementation.
-  RefPtr<InitPromise> Init() override;
-  void Input(MediaRawData* aSample) override;
-  void Flush() override;
-  void Drain() override;
-  void Shutdown() override;
-  bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
-  const char* GetDescriptionName() const override
-  {
-    return mDecoder->GetDescriptionName();
-  }
-
-private:
-  virtual ~DecoderFuzzingWrapper();
-  RefPtr<MediaDataDecoder> mDecoder;
-  RefPtr<DecoderCallbackFuzzingWrapper> mCallbackWrapper;
-};
-
-} // namespace mozilla
-
-#endif