Bug 1397141 - part1 : update error description for getting more details draft
authorAlastor Wu <alwu@mozilla.com>
Wed, 13 Sep 2017 15:05:25 +0800
changeset 663586 8f8659fc37a21ed94c39535c91ca3d1d06554174
parent 663134 a73cc4e08bf5a005722c95b43f84ab0c8ff2bc7c
child 663587 e086c9d40284ae523489ee04b0e1505115a8a3b5
push id79482
push useralwu@mozilla.com
push dateWed, 13 Sep 2017 07:06:40 +0000
bugs1397141
milestone57.0a1
Bug 1397141 - part1 : update error description for getting more details We should report the more detailed error when creating the decoder failed, instead of just reporting "can not create decoder". MozReview-Commit-ID: 8vunP5c3zzI
dom/media/platforms/wmf/WMFDecoderModule.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.h
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -105,17 +105,21 @@ WMFDecoderModule::CreateVideoDecoder(con
   }
 
   nsAutoPtr<WMFVideoMFTManager> manager(
     new WMFVideoMFTManager(aParams.VideoConfig(),
                            aParams.mKnowsCompositor,
                            aParams.mImageContainer,
                            sDXVAEnabled));
 
-  if (!manager->Init()) {
+  MediaResult result = manager->Init();
+  if (NS_FAILED(result)) {
+    if (aParams.mError) {
+      *aParams.mError = result;
+    }
     return nullptr;
   }
 
   RefPtr<MediaDataDecoder> decoder =
     new WMFMediaDataDecoder(manager.forget(), aParams.mTaskQueue);
 
   return decoder.forget();
 }
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -518,34 +518,36 @@ WMFVideoMFTManager::InitializeDXVA()
     mozilla::SyncRunnable::DispatchToThread(
       SystemGroup::EventTargetFor(mozilla::TaskCategory::Other), event);
   }
   mDXVA2Manager = event->mDXVA2Manager;
 
   return mDXVA2Manager != nullptr;
 }
 
-bool
+MediaResult
 WMFVideoMFTManager::ValidateVideoInfo()
 {
   // The WMF H.264 decoder is documented to have a minimum resolution
   // 48x48 pixels. We've observed the decoder working for output smaller than
   // that, but on some output it hangs in IMFTransform::ProcessOutput(), so
   // we just reject streams which are less than the documented minimum.
   // https://msdn.microsoft.com/en-us/library/windows/desktop/dd797815(v=vs.85).aspx
   static const int32_t MIN_H264_FRAME_DIMENSION = 48;
   if (mStreamType == H264 &&
       (mVideoInfo.mImage.width < MIN_H264_FRAME_DIMENSION ||
        mVideoInfo.mImage.height < MIN_H264_FRAME_DIMENSION)) {
-    LogToBrowserConsole(NS_LITERAL_STRING(
-      "Can't decode H.264 stream with width or height less than 48 pixels."));
     mIsValid = false;
+    return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                       RESULT_DETAIL("Can't decode H.264 stream with width or "
+                                     "height less than 48 pixels."));
   }
 
-  return mIsValid;
+  return MediaResult(NS_OK);
+
 }
 
 already_AddRefed<MFTDecoder>
 WMFVideoMFTManager::LoadAMDVP9Decoder()
 {
   MOZ_ASSERT(mStreamType == VP9);
 
   RefPtr<MFTDecoder> decoder = new MFTDecoder();
@@ -564,48 +566,49 @@ WMFVideoMFTManager::LoadAMDVP9Decoder()
   if (!decoderDLL) {
     return nullptr;
   }
   hr = decoder->Create(decoderDLL, CLSID_AMDWebmMfVp9Dec);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
   return decoder.forget();
 }
 
-bool
+MediaResult
 WMFVideoMFTManager::Init()
 {
-  if (!ValidateVideoInfo()) {
-    return false;
+  MediaResult result = ValidateVideoInfo();
+  if (NS_FAILED(result)) {
+    return result;
   }
 
-  bool success = InitInternal();
-  if (!success && mAMDVP9InUse) {
+  result = InitInternal();
+  if (NS_FAILED(result) && mAMDVP9InUse) {
     // Something failed with the AMD VP9 decoder; attempt again defaulting back
     // to Microsoft MFT.
     mCheckForAMDDecoder = false;
     if (mDXVA2Manager) {
       DeleteOnMainThread(mDXVA2Manager);
     }
-    success = InitInternal();
+    result = InitInternal();
   }
 
-  if (success && mDXVA2Manager) {
+  if (NS_SUCCEEDED(result) && mDXVA2Manager) {
     // If we had some failures but eventually made it work,
     // make sure we preserve the messages.
     if (mDXVA2Manager->IsD3D11()) {
       mDXVAFailureReason.Append(NS_LITERAL_CSTRING("Using D3D11 API"));
     } else {
       mDXVAFailureReason.Append(NS_LITERAL_CSTRING("Using D3D9 API"));
     }
   }
 
-  return success;
+  return result;
 }
 
-bool
+MediaResult
 WMFVideoMFTManager::InitInternal()
 {
   // The H264 SanityTest uses a 132x132 videos to determine if DXVA can be used.
   // so we want to use the software decoder for videos with lower resolutions.
   static const int MIN_H264_HW_WIDTH = 132;
   static const int MIN_H264_HW_HEIGHT = 132;
 
   mUseHwAccel = false; // default value; changed if D3D setup succeeds.
@@ -623,17 +626,19 @@ WMFVideoMFTManager::InitInternal()
       mAMDVP9InUse = true;
     }
   }
   if (!decoder) {
     mCheckForAMDDecoder = false;
     mAMDVP9InUse = false;
     decoder = new MFTDecoder();
     hr = decoder->Create(GetMFTGUID());
-    NS_ENSURE_TRUE(SUCCEEDED(hr), false);
+    NS_ENSURE_TRUE(SUCCEEDED(hr),
+                   MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                               RESULT_DETAIL("Can't create the MFT decoder.")));
   }
 
   RefPtr<IMFAttributes> attr(decoder->GetAttributes());
   UINT32 aware = 0;
   if (attr) {
     attr->GetUINT32(MF_SA_D3D_AWARE, &aware);
     attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads,
       WMFDecoderModule::GetNumDecoderThreads());
@@ -665,46 +670,54 @@ WMFVideoMFTManager::InitInternal()
     }
     else {
       mDXVAFailureReason.AssignLiteral(
         "Decoder returned false for MF_SA_D3D_AWARE");
     }
   }
 
   if (!mUseHwAccel) {
-    // Use VP8/9 MFT only if HW acceleration is available
     if (mStreamType == VP9 || mStreamType == VP8) {
-      return false;
+      return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                         RESULT_DETAIL("Use VP8/9 MFT only if HW acceleration "
+                                       "is available."));
     }
     Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
                           uint32_t(media::MediaDecoderBackend::WMFSoftware));
   }
 
   mDecoder = decoder;
   hr = SetDecoderMediaTypes();
-  NS_ENSURE_TRUE(SUCCEEDED(hr), false);
+  NS_ENSURE_TRUE(SUCCEEDED(hr),
+                 MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                             RESULT_DETAIL("Fail to set the decoder media types.")));
 
   RefPtr<IMFMediaType> outputType;
   hr = mDecoder->GetOutputMediaType(outputType);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+  NS_ENSURE_TRUE(SUCCEEDED(hr),
+                 MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                            RESULT_DETAIL("Fail to get the output media type.")));
 
   if (mUseHwAccel && !CanUseDXVA(outputType)) {
     mDXVAEnabled = false;
     // DXVA initialization with current decoder actually failed,
     // re-do initialization.
     return InitInternal();
   }
 
   LOG("Video Decoder initialized, Using DXVA: %s",
       (mUseHwAccel ? "Yes" : "No"));
 
   if (mDXVA2Manager) {
     hr = mDXVA2Manager->ConfigureForSize(mVideoInfo.ImageRect().width,
                                          mVideoInfo.ImageRect().height);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+    NS_ENSURE_TRUE(SUCCEEDED(hr),
+                   MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                               RESULT_DETAIL("Fail to configure image size for "
+                                             "DXVA2Manager.")));
   } else {
     GetDefaultStride(outputType, mVideoInfo.ImageRect().width, &mVideoStride);
   }
   LOG("WMFVideoMFTManager frame geometry stride=%u picture=(%d, %d, %d, %d) "
       "display=(%d,%d)",
       mVideoStride,
       mVideoInfo.ImageRect().x,
       mVideoInfo.ImageRect().y,
@@ -724,17 +737,17 @@ WMFVideoMFTManager::InitInternal()
       HRESULT hr =
         device->QueryInterface((ID3D10Multithread**)getter_AddRefs(multi));
       if (SUCCEEDED(hr) && multi) {
         multi->SetMultithreadProtected(TRUE);
         mIMFUsable = true;
       }
     }
   }
-  return true;
+  return MediaResult(NS_OK);
 }
 
 HRESULT
 WMFVideoMFTManager::SetDecoderMediaTypes()
 {
   // Setup the input/output media types.
   RefPtr<IMFMediaType> inputType;
   HRESULT hr = wmf::MFCreateMediaType(getter_AddRefs(inputType));
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -3,16 +3,17 @@
 /* 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(WMFVideoMFTManager_h_)
 #define WMFVideoMFTManager_h_
 
 #include "MFTDecoder.h"
+#include "MediaResult.h"
 #include "WMF.h"
 #include "WMFMediaDataDecoder.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/RefPtr.h"
 #include "nsAutoPtr.h"
 #include "mozilla/gfx/Rect.h"
 
 namespace mozilla {
@@ -23,17 +24,17 @@ class WMFVideoMFTManager : public MFTMan
 {
 public:
   WMFVideoMFTManager(const VideoInfo& aConfig,
                      layers::KnowsCompositor* aKnowsCompositor,
                      layers::ImageContainer* aImageContainer,
                      bool aDXVAEnabled);
   ~WMFVideoMFTManager();
 
-  bool Init();
+  MediaResult Init();
 
   HRESULT Input(MediaRawData* aSample) override;
 
   HRESULT Output(int64_t aStreamOffset, RefPtr<MediaData>& aOutput) override;
 
   void Shutdown() override;
 
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
@@ -58,21 +59,21 @@ public:
   MediaDataDecoder::ConversionRequired NeedsConversion() const override
   {
     return mStreamType == H264
            ? MediaDataDecoder::ConversionRequired::kNeedAnnexB
            : MediaDataDecoder::ConversionRequired::kNeedNone;
   }
 
 private:
-  bool ValidateVideoInfo();
+  MediaResult ValidateVideoInfo();
 
   bool InitializeDXVA();
 
-  bool InitInternal();
+  MediaResult InitInternal();
 
   HRESULT CreateBasicVideoFrame(IMFSample* aSample,
                                 int64_t aStreamOffset,
                                 VideoData** aOutVideoData);
 
   HRESULT CreateD3DVideoFrame(IMFSample* aSample,
                               int64_t aStreamOffset,
                               VideoData** aOutVideoData);