Bug 1400758 - part2 : report the error description with InitPromise for agnostic decoders. draft
authorAlastor Wu <alwu@mozilla.com>
Mon, 18 Sep 2017 18:10:00 +0800
changeset 666242 eba38d2d663018b71db3aaf0e552ba5161e6b226
parent 666239 8064839a8a795c1efb07b8c4596836583f0b06ec
child 666243 b78843056a586642548b36524ac2b2408d7acf9d
push id80334
push useralwu@mozilla.com
push dateMon, 18 Sep 2017 10:10:09 +0000
bugs1400758
milestone57.0a1
Bug 1400758 - part2 : report the error description with InitPromise for agnostic decoders. MozReview-Commit-ID: BxTTHJPwDNq
dom/media/platforms/agnostic/AOMDecoder.cpp
dom/media/platforms/agnostic/OpusDecoder.cpp
dom/media/platforms/agnostic/TheoraDecoder.cpp
dom/media/platforms/agnostic/VorbisDecoder.cpp
--- a/dom/media/platforms/agnostic/AOMDecoder.cpp
+++ b/dom/media/platforms/agnostic/AOMDecoder.cpp
@@ -29,17 +29,17 @@ using namespace layers;
 
 
 static MediaResult
 InitContext(aom_codec_ctx_t* aCtx,
             const VideoInfo& aInfo)
 {
   aom_codec_iface_t* dx = aom_codec_av1_dx();
   if (!dx) {
-    return MediaResult(NS_ERROR_FAILURE,
+    return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                        RESULT_DETAIL("Couldn't get AV1 decoder interface."));
   }
 
   int decode_threads = 2;
   if (aInfo.mDisplay.width >= 2048) {
     decode_threads = 8;
   }
   else if (aInfo.mDisplay.width >= 1024) {
@@ -52,17 +52,17 @@ InitContext(aom_codec_ctx_t* aCtx,
   config.threads = decode_threads;
   config.w = config.h = 0; // set after decode
 
   aom_codec_flags_t flags = 0;
 
   auto res = aom_codec_dec_init(aCtx, dx, &config, flags);
   if (res != AOM_CODEC_OK) {
     LOG_RESULT(res, "Codec initialization failed!");
-    return MediaResult(NS_ERROR_FAILURE,
+    return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                        RESULT_DETAIL("AOM error initializing AV1 decoder: %s",
                                      aom_codec_err_to_string(res)));
   }
   return NS_OK;
 }
 
 AOMDecoder::AOMDecoder(const CreateDecoderParams& aParams)
   : mImageContainer(aParams.mImageContainer)
@@ -87,18 +87,19 @@ AOMDecoder::Shutdown()
     }
     return ShutdownPromise::CreateAndResolve(true, __func__);
   });
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
 AOMDecoder::Init()
 {
-  if (NS_FAILED(InitContext(&mCodec, mInfo))) {
-    return AOMDecoder::InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+  MediaResult rv = InitContext(&mCodec, mInfo);
+  if (NS_FAILED(rv)) {
+    return AOMDecoder::InitPromise::CreateAndReject(rv,
                                                     __func__);
   }
   return AOMDecoder::InitPromise::CreateAndResolve(TrackInfo::kVideoTrack,
                                                    __func__);
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 AOMDecoder::Flush()
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -64,24 +64,30 @@ OpusDataDecoder::AppendCodecDelay(MediaB
 
 RefPtr<MediaDataDecoder::InitPromise>
 OpusDataDecoder::Init()
 {
   size_t length = mInfo.mCodecSpecificConfig->Length();
   uint8_t *p = mInfo.mCodecSpecificConfig->Elements();
   if (length < sizeof(uint64_t)) {
     OPUS_DEBUG("CodecSpecificConfig too short to read codecDelay!");
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("CodecSpecificConfig too short to read codecDelay!")),
+      __func__);
   }
   int64_t codecDelay = BigEndian::readUint64(p);
   length -= sizeof(uint64_t);
   p += sizeof(uint64_t);
   if (NS_FAILED(DecodeHeader(p, length))) {
     OPUS_DEBUG("Error decoding header!");
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Error decoding header!")),
+      __func__);
   }
 
   int r;
   mOpusDecoder = opus_multistream_decoder_create(mOpusParser->mRate,
                                                  mOpusParser->mChannels,
                                                  mOpusParser->mStreams,
                                                  mOpusParser->mCoupledStreams,
                                                  mMappingTable,
@@ -98,17 +104,20 @@ OpusDataDecoder::Init()
   if (mInfo.mRate != (uint32_t)mOpusParser->mRate) {
     NS_WARNING("Invalid Opus header: container and codec rate do not match!");
   }
   if (mInfo.mChannels != (uint32_t)mOpusParser->mChannels) {
     NS_WARNING("Invalid Opus header: container and codec channels do not match!");
   }
 
   return r == OPUS_OK ? InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__)
-                      : InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+                      : InitPromise::CreateAndReject(
+                          MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                          RESULT_DETAIL("could not create opus multistream decoder!")),
+                          __func__);
 }
 
 nsresult
 OpusDataDecoder::DecodeHeader(const unsigned char* aData, size_t aLength)
 {
   MOZ_ASSERT(!mOpusParser);
   MOZ_ASSERT(!mOpusDecoder);
   MOZ_ASSERT(!mDecodedHeader);
--- a/dom/media/platforms/agnostic/TheoraDecoder.cpp
+++ b/dom/media/platforms/agnostic/TheoraDecoder.cpp
@@ -77,33 +77,44 @@ TheoraDecoder::Init()
   th_comment_init(&mTheoraComment);
   th_info_init(&mTheoraInfo);
 
   nsTArray<unsigned char*> headers;
   nsTArray<size_t> headerLens;
   if (!XiphExtradataToHeaders(headers, headerLens,
       mInfo.mCodecSpecificConfig->Elements(),
       mInfo.mCodecSpecificConfig->Length())) {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Could not get theora header.")),
+      __func__);
   }
   for (size_t i = 0; i < headers.Length(); i++) {
     if (NS_FAILED(DoDecodeHeader(headers[i], headerLens[i]))) {
-      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                          __func__);
+      return InitPromise::CreateAndReject(
+        MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                    RESULT_DETAIL("Could not decode theora header.")),
+        __func__);
     }
   }
   if (mPacketCount != 3) {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Packet count is wrong.")),
+      __func__);
   }
 
   mTheoraDecoderContext = th_decode_alloc(&mTheoraInfo, mTheoraSetupInfo);
   if (mTheoraDecoderContext) {
     return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
   } else {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_OUT_OF_MEMORY,
+                  RESULT_DETAIL("Could not allocate theora decoder.")),
+      __func__);
   }
 
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 TheoraDecoder::Flush()
 {
   return InvokeAsync(mTaskQueue, __func__, []() {
--- a/dom/media/platforms/agnostic/VorbisDecoder.cpp
+++ b/dom/media/platforms/agnostic/VorbisDecoder.cpp
@@ -70,49 +70,63 @@ VorbisDataDecoder::Init()
   PodZero(&mVorbisDsp);
   PodZero(&mVorbisBlock);
 
   AutoTArray<unsigned char*,4> headers;
   AutoTArray<size_t,4> headerLens;
   if (!XiphExtradataToHeaders(headers, headerLens,
                               mInfo.mCodecSpecificConfig->Elements(),
                               mInfo.mCodecSpecificConfig->Length())) {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Could not get vorbis header.")),
+      __func__);
   }
   for (size_t i = 0; i < headers.Length(); i++) {
     if (NS_FAILED(DecodeHeader(headers[i], headerLens[i]))) {
-      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                          __func__);
+      return InitPromise::CreateAndReject(
+        MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                    RESULT_DETAIL("Could not decode vorbis header.")),
+        __func__);
     }
   }
 
   MOZ_ASSERT(mPacketCount == 3);
 
   int r = vorbis_synthesis_init(&mVorbisDsp, &mVorbisInfo);
   if (r) {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Systhesis init fail.")),
+      __func__);
   }
 
   r = vorbis_block_init(&mVorbisDsp, &mVorbisBlock);
   if (r) {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Block init fail.")),
+      __func__);
   }
 
   if (mInfo.mRate != (uint32_t)mVorbisDsp.vi->rate) {
     LOG(LogLevel::Warning,
         ("Invalid Vorbis header: container and codec rate do not match!"));
   }
   if (mInfo.mChannels != (uint32_t)mVorbisDsp.vi->channels) {
     LOG(LogLevel::Warning,
         ("Invalid Vorbis header: container and codec channels do not match!"));
   }
 
   AudioConfig::ChannelLayout layout(mVorbisDsp.vi->channels);
   if (!layout.IsValid()) {
-    return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    return InitPromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                  RESULT_DETAIL("Invalid audio layout.")),
+      __func__);
   }
 
   return InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__);
 }
 
 nsresult
 VorbisDataDecoder::DecodeHeader(const unsigned char* aData, size_t aLength)
 {