Bug 1341210 - refactor ProcessOutput() to remove mDecodePromise and mDrainPromise. r?jya draft
authorJW Wang <jwwang@mozilla.com>
Tue, 21 Feb 2017 15:27:36 +0800
changeset 488511 132d501e60621f2d2e7d9a2c98eec7e27688ee88
parent 488510 02ef2647e271430fad3f05d77fa9101fd04a5c6e
child 546748 f9dc40ef964e791dd08218419b7087c8adc445ca
push id46550
push userjwwang@mozilla.com
push dateThu, 23 Feb 2017 07:45:19 +0000
reviewersjya
bugs1341210
milestone54.0a1
Bug 1341210 - refactor ProcessOutput() to remove mDecodePromise and mDrainPromise. r?jya MozReview-Commit-ID: 9kK7lzJriqC
dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
dom/media/platforms/wmf/WMFMediaDataDecoder.h
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -102,85 +102,67 @@ WMFMediaDataDecoder::Decode(MediaRawData
   MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
 
   return InvokeAsync<MediaRawData*>(mTaskQueue, this, __func__,
                                     &WMFMediaDataDecoder::ProcessDecode,
                                     aSample);
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
+WMFMediaDataDecoder::ProcessError(HRESULT aError, const char* aReason)
+{
+  if (!mRecordedError) {
+    SendTelemetry(aError);
+    mRecordedError = true;
+  }
+  return DecodePromise::CreateAndReject(
+    MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+                RESULT_DETAIL("%s:%x", aReason, aError)),
+    __func__);
+}
+
+RefPtr<MediaDataDecoder::DecodePromise>
 WMFMediaDataDecoder::ProcessDecode(MediaRawData* aSample)
 {
+  DecodedData results;
   HRESULT hr = mMFTManager->Input(aSample);
   if (hr == MF_E_NOTACCEPTING) {
-    ProcessOutput();
+    ProcessOutput(results);
     hr = mMFTManager->Input(aSample);
   }
 
   if (FAILED(hr)) {
     NS_WARNING("MFTManager rejected sample");
-    if (!mRecordedError) {
-      SendTelemetry(hr);
-      mRecordedError = true;
-    }
-    return DecodePromise::CreateAndReject(
-      MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
-                  RESULT_DETAIL("MFTManager::Input:%x", hr)),
-      __func__);
+    return ProcessError(hr, "MFTManager::Input");
   }
 
   mDrainStatus = DrainStatus::DRAINABLE;
   mLastStreamOffset = aSample->mOffset;
 
-  RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
-  ProcessOutput();
-  return p;
+  hr = ProcessOutput(results);
+  if (SUCCEEDED(hr) || hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+    return DecodePromise::CreateAndResolve(Move(results), __func__);
+  }
+  return ProcessError(hr, "MFTManager::Output");
 }
 
-void
-WMFMediaDataDecoder::ProcessOutput()
+HRESULT
+WMFMediaDataDecoder::ProcessOutput(DecodedData& aResults)
 {
   RefPtr<MediaData> output;
   HRESULT hr = S_OK;
-  DecodedData results;
   while (SUCCEEDED(hr = mMFTManager->Output(mLastStreamOffset, output))) {
     MOZ_ASSERT(output.get(), "Upon success, we must receive an output");
     mHasSuccessfulOutput = true;
-    results.AppendElement(Move(output));
+    aResults.AppendElement(Move(output));
     if (mDrainStatus == DrainStatus::DRAINING) {
       break;
     }
   }
-
-  if (SUCCEEDED(hr) || hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
-    if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT && !mDrainPromise.IsEmpty()) {
-      mDrainStatus = DrainStatus::DRAINED;
-    }
-    if (!mDecodePromise.IsEmpty()) {
-      mDecodePromise.Resolve(Move(results), __func__);
-    } else {
-      mDrainPromise.Resolve(Move(results), __func__);
-    }
-    return;
-  }
-
-  NS_WARNING("WMFMediaDataDecoder failed to output data");
-  const auto error = MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
-                                  RESULT_DETAIL("MFTManager::Output:%x", hr));
-  if (!mDecodePromise.IsEmpty()) {
-    mDecodePromise.Reject(error, __func__);
-  }
-  else {
-    mDrainPromise.Reject(error, __func__);
-  }
-
-  if (!mRecordedError) {
-    SendTelemetry(hr);
-    mRecordedError = true;
-  }
+  return hr;
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 WMFMediaDataDecoder::ProcessFlush()
 {
   if (mMFTManager) {
     mMFTManager->Flush();
   }
@@ -198,25 +180,33 @@ WMFMediaDataDecoder::Flush()
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 WMFMediaDataDecoder::ProcessDrain()
 {
   if (!mMFTManager || mDrainStatus == DrainStatus::DRAINED) {
     return DecodePromise::CreateAndResolve(DecodedData(), __func__);
   }
+
   if (mDrainStatus != DrainStatus::DRAINING) {
     // Order the decoder to drain...
     mMFTManager->Drain();
     mDrainStatus = DrainStatus::DRAINING;
   }
+
   // Then extract all available output.
-  RefPtr<DecodePromise> p = mDrainPromise.Ensure(__func__);
-  ProcessOutput();
-  return p;
+  DecodedData results;
+  HRESULT hr = ProcessOutput(results);
+  if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+    mDrainStatus = DrainStatus::DRAINED;
+  }
+  if (SUCCEEDED(hr) || hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+    return DecodePromise::CreateAndResolve(Move(results), __func__);
+  }
+  return ProcessError(hr, "MFTManager::Output");
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 WMFMediaDataDecoder::Drain()
 {
   MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
 
   return InvokeAsync(mTaskQueue, this, __func__,
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -112,23 +112,25 @@ public:
     MOZ_ASSERT(mMFTManager);
     return mMFTManager->NeedsConversion();
   }
 
   virtual void SetSeekThreshold(const media::TimeUnit& aTime) override;
 
 private:
 
+  RefPtr<DecodePromise> ProcessError(HRESULT aError, const char* aReason);
+
   // Called on the task queue. Inserts the sample into the decoder, and
   // extracts output if available.
   RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
 
   // Called on the task queue. Extracts output if available, and delivers
   // it to the reader. Called after ProcessDecode() and ProcessDrain().
-  void ProcessOutput();
+  HRESULT ProcessOutput(DecodedData& aResults);
 
   // Called on the task queue. Orders the MFT to flush.  There is no output to
   // extract.
   RefPtr<FlushPromise> ProcessFlush();
 
   // Called on the task queue. Orders the MFT to drain, and then extracts
   // all available output.
   RefPtr<DecodePromise> ProcessDrain();
@@ -140,18 +142,16 @@ private:
   nsAutoPtr<MFTManager> mMFTManager;
 
   // The last offset into the media resource that was passed into Input().
   // This is used to approximate the decoder's position in the media resource.
   int64_t mLastStreamOffset;
 
   bool mIsShutDown = false;
 
-  MozPromiseHolder<DecodePromise> mDecodePromise;
-  MozPromiseHolder<DecodePromise> mDrainPromise;
   enum class DrainStatus
   {
     DRAINED,
     DRAINABLE,
     DRAINING,
   };
   DrainStatus mDrainStatus = DrainStatus::DRAINED;