Bug 1299072: P7. Use MediaResult with MetadataPromise. r?cpearce draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sat, 10 Sep 2016 19:56:50 +1000
changeset 412872 618c06a14e1a3160f7787a90e00cd5e2cd678657
parent 412871 6c12c60923f2fe4299fe53902ba00add3d834c92
child 412873 e1ac5bb8f35716d9e0b65504caca52bb6742b9c8
push id29276
push userbmo:jyavenard@mozilla.com
push dateTue, 13 Sep 2016 03:29:20 +0000
reviewerscpearce
bugs1299072
milestone51.0a1
Bug 1299072: P7. Use MediaResult with MetadataPromise. r?cpearce MozReview-Commit-ID: KrRr8wDuPNT
dom/media/MediaDecoderReader.cpp
dom/media/MediaDecoderReader.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaFormatReader.cpp
dom/media/gtest/TestMediaFormatReader.cpp
dom/media/omx/MediaOmxReader.cpp
dom/media/webaudio/MediaBufferDecoder.cpp
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -355,31 +355,29 @@ MediaDecoderReader::GetBuffered()
   }
 
   return GetEstimatedBufferedTimeRanges(stream, mDuration.Ref().ref().ToMicroseconds());
 }
 
 RefPtr<MediaDecoderReader::MetadataPromise>
 MediaDecoderReader::AsyncReadMetadata()
 {
-  typedef ReadMetadataFailureReason Reason;
-
   MOZ_ASSERT(OnTaskQueue());
   DECODER_LOG("MediaDecoderReader::AsyncReadMetadata");
 
   // Attempt to read the metadata.
   RefPtr<MetadataHolder> metadata = new MetadataHolder();
   nsresult rv = ReadMetadata(&metadata->mInfo, getter_Transfers(metadata->mTags));
   metadata->mInfo.AssertValid();
 
   // We're not waiting for anything. If we didn't get the metadata, that's an
   // error.
   if (NS_FAILED(rv) || !metadata->mInfo.HasValidMedia()) {
     DECODER_WARN("ReadMetadata failed, rv=%x HasValidMedia=%d", rv, metadata->mInfo.HasValidMedia());
-    return MetadataPromise::CreateAndReject(Reason::METADATA_ERROR, __func__);
+    return MetadataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
   }
 
   // Success!
   return MetadataPromise::CreateAndResolve(metadata, __func__);
 }
 
 class ReRequestVideoWithSkipTask : public Runnable
 {
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -46,38 +46,33 @@ public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataHolder)
   MediaInfo mInfo;
   nsAutoPtr<MetadataTags> mTags;
 
 private:
   virtual ~MetadataHolder() {}
 };
 
-enum class ReadMetadataFailureReason : int8_t
-{
-  METADATA_ERROR
-};
-
 // Encapsulates the decoding and reading of media data. Reading can either
 // synchronous and done on the calling "decode" thread, or asynchronous and
 // performed on a background thread, with the result being returned by
 // callback. Never hold the decoder monitor when calling into this class.
 // Unless otherwise specified, methods and fields of this class can only
 // be accessed on the decode task queue.
 class MediaDecoderReader {
   friend class ReRequestVideoWithSkipTask;
   friend class ReRequestAudioTask;
 
   static const bool IsExclusive = true;
 
 public:
   using TrackSet = EnumSet<TrackInfo::TrackType>;
 
   using MetadataPromise =
-    MozPromise<RefPtr<MetadataHolder>, ReadMetadataFailureReason, IsExclusive>;
+    MozPromise<RefPtr<MetadataHolder>, MediaResult, IsExclusive>;
   using MediaDataPromise =
     MozPromise<RefPtr<MediaData>, MediaResult, IsExclusive>;
   using SeekPromise = MozPromise<media::TimeUnit, nsresult, IsExclusive>;
 
   // Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
   // But in the current architecture it's only ever used exclusively (by MDSM),
   // so we mark it that way to verify our assumptions. If you have a use-case
   // for multiple WaitForData consumers, feel free to flip the exclusivity here.
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -258,18 +258,18 @@ public:
 
     // We disconnect mMetadataRequest in Exit() so it is fine to capture
     // a raw pointer here.
     mMetadataRequest.Begin(Reader()->ReadMetadata()
       ->Then(OwnerThread(), __func__,
         [this] (MetadataHolder* aMetadata) {
           OnMetadataRead(aMetadata);
         },
-        [this] (ReadMetadataFailureReason aReason) {
-          OnMetadataNotRead(aReason);
+        [this] (const MediaResult& aError) {
+          OnMetadataNotRead(aError);
         }));
   }
 
   void Exit() override
   {
     mMetadataRequest.DisconnectIfExists();
   }
 
@@ -350,21 +350,21 @@ private:
       // to become available so that we can build the correct decryptor/decoder.
       SetState(DECODER_STATE_WAIT_FOR_CDM);
       return;
     }
 
     SetState(DECODER_STATE_DECODING_FIRSTFRAME);
   }
 
-  void OnMetadataNotRead(ReadMetadataFailureReason aReason)
+  void OnMetadataNotRead(const MediaResult& aError)
   {
     mMetadataRequest.Complete();
     SWARN("Decode metadata failed, shutting down decoder");
-    mMaster->DecodeError();
+    mMaster->DecodeError(aError);
   }
 
   MozPromiseRequestHolder<MediaDecoderReader::MetadataPromise> mMetadataRequest;
 
   // True if we need to enter dormant state after reading metadata. Note that
   // we can't enter dormant state until reading metadata is done for some
   // limitations of the reader.
   bool mPendingDormant = false;
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -88,17 +88,17 @@ MediaFormatReader::~MediaFormatReader()
 }
 
 RefPtr<ShutdownPromise>
 MediaFormatReader::Shutdown()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   mDemuxerInitRequest.DisconnectIfExists();
-  mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+  mMetadataPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   mSeekPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   mSkipRequest.DisconnectIfExists();
 
   if (mAudio.mDecoder) {
     Reset(TrackInfo::kAudioTrack);
     if (mAudio.HasPromise()) {
       mAudio.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     }
@@ -278,26 +278,26 @@ MediaFormatReader::OnDemuxerInitDone(nsr
   // To decode, we need valid video and a place to put it.
   bool videoActive = !!mDemuxer->GetNumberTracks(TrackInfo::kVideoTrack) &&
     GetImageContainer();
 
   if (videoActive) {
     // We currently only handle the first video track.
     mVideo.mTrackDemuxer = mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
     if (!mVideo.mTrackDemuxer) {
-      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
       return;
     }
 
     UniquePtr<TrackInfo> videoInfo = mVideo.mTrackDemuxer->GetInfo();
     videoActive = videoInfo && videoInfo->IsValid();
     if (videoActive) {
       if (platform && !platform->SupportsMimeType(videoInfo->mMimeType, nullptr)) {
         // We have no decoder for this track. Error.
-        mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+        mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
         return;
       }
       mInfo.mVideo = *videoInfo->GetAsVideoInfo();
       for (const MetadataTag& tag : videoInfo->mTags) {
         tags->Put(tag.mKey, tag.mValue);
       }
       mVideo.mCallback = new DecoderCallback(this, TrackInfo::kVideoTrack);
       mVideo.mTimeRanges = mVideo.mTrackDemuxer->GetBuffered();
@@ -307,17 +307,17 @@ MediaFormatReader::OnDemuxerInitDone(nsr
       mVideo.mTrackDemuxer = nullptr;
     }
   }
 
   bool audioActive = !!mDemuxer->GetNumberTracks(TrackInfo::kAudioTrack);
   if (audioActive) {
     mAudio.mTrackDemuxer = mDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
     if (!mAudio.mTrackDemuxer) {
-      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
       return;
     }
 
     UniquePtr<TrackInfo> audioInfo = mAudio.mTrackDemuxer->GetInfo();
     // We actively ignore audio tracks that we know we can't play.
     audioActive = audioInfo && audioInfo->IsValid() &&
                   (!platform ||
                    platform->SupportsMimeType(audioInfo->mMimeType, nullptr));
@@ -359,32 +359,32 @@ MediaFormatReader::OnDemuxerInitDone(nsr
     mInfo.mMetadataDuration = Some(TimeUnit::FromMicroseconds(duration));
   }
 
   mInfo.mMediaSeekable = mDemuxer->IsSeekable();
   mInfo.mMediaSeekableOnlyInBufferedRanges =
     mDemuxer->IsSeekableOnlyInBufferedRanges();
 
   if (!videoActive && !audioActive) {
-    mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+    mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
     return;
   }
 
   mInitDone = true;
   RefPtr<MetadataHolder> metadata = new MetadataHolder();
   metadata->mInfo = mInfo;
   metadata->mTags = tags->Count() ? tags.release() : nullptr;
   mMetadataPromise.Resolve(metadata, __func__);
 }
 
 void
 MediaFormatReader::OnDemuxerInitFailed(DemuxerFailureReason aFailure)
 {
   mDemuxerInitRequest.Complete();
-  mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+  mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
 }
 
 bool
 MediaFormatReader::EnsureDecoderCreated(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_DIAGNOSTIC_ASSERT(!IsSuspended());
 
--- a/dom/media/gtest/TestMediaFormatReader.cpp
+++ b/dom/media/gtest/TestMediaFormatReader.cpp
@@ -83,17 +83,17 @@ public:
   {
     EXPECT_TRUE(aMetadata);
     mReader->RequestVideoData(true, 0)
       ->Then(mReader->OwnerThread(), __func__, this,
              &MediaFormatReaderBinding::OnVideoRawDataDemuxed,
              &MediaFormatReaderBinding::OnNotDemuxed);
   }
 
-  void OnMetadataNotRead(ReadMetadataFailureReason aReason) {
+  void OnMetadataNotRead(const MediaResult& aError) {
     EXPECT_TRUE(false);
     ReaderShutdown();
   }
 
   void OnAudioRawDataDemuxed(MediaData* aAudioSample)
   {
     EXPECT_TRUE(aAudioSample);
     EXPECT_EQ(MediaData::RAW_DATA, aAudioSample->mType);
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -170,17 +170,17 @@ MediaOmxReader::Shutdown()
   p->Then(AbstractThread::MainThread(), __func__, this, &MediaOmxReader::ReleaseDecoder, &MediaOmxReader::ReleaseDecoder);
 
   return p;
 }
 
 void MediaOmxReader::ReleaseResources()
 {
   mMediaResourceRequest.DisconnectIfExists();
-  mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+  mMetadataPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
 
   ResetDecode();
   // Before freeing a video codec, all video buffers needed to be released
   // even from graphics pipeline.
   VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
   if (container) {
     container->ClearCurrentFrame();
   }
@@ -216,17 +216,17 @@ MediaOmxReader::AsyncReadMetadata()
 {
   MOZ_ASSERT(OnTaskQueue());
   EnsureActive();
 
   // Initialize the internal OMX Decoder.
   nsresult rv = InitOmxDecoder();
   if (NS_FAILED(rv)) {
     return MediaDecoderReader::MetadataPromise::CreateAndReject(
-             ReadMetadataFailureReason::METADATA_ERROR, __func__);
+             NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
   }
 
   bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
   if (isMP3) {
     // When read sdcard's file on b2g platform at constructor,
     // the mDecoder->GetResource()->GetLength() would return -1.
     // Delay set the total duration on this function.
     mMP3FrameParser.SetLength(mDecoder->GetResource()->GetLength());
@@ -238,29 +238,29 @@ MediaOmxReader::AsyncReadMetadata()
   RefPtr<MediaOmxReader> self = this;
   mMediaResourceRequest.Begin(mOmxDecoder->AllocateMediaResources()
     ->Then(OwnerThread(), __func__,
       [self] (bool) -> void {
         self->mMediaResourceRequest.Complete();
         self->HandleResourceAllocated();
       }, [self] (bool) -> void {
         self->mMediaResourceRequest.Complete();
-        self->mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+        self->mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
       }));
 
   return p;
 }
 
 void MediaOmxReader::HandleResourceAllocated()
 {
   EnsureActive();
 
   // After resources are available, set the metadata.
   if (!mOmxDecoder->EnsureMetadata()) {
-    mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+    mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
     return;
   }
 
   bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
   if (isMP3 && mMP3FrameParser.IsMP3()) {
     // Check if the MP3 frame parser found a duration.
     mLastParserDuration = mMP3FrameParser.GetDuration();
   }
@@ -284,17 +284,17 @@ void MediaOmxReader::HandleResourceAlloc
                                     &width, &height);
     nsIntRect pictureRect(0, 0, width, height);
 
     // Validate the container-reported frame and pictureRect sizes. This ensures
     // that our video frame creation code doesn't overflow.
     nsIntSize displaySize(displayWidth, displayHeight);
     nsIntSize frameSize(width, height);
     if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) {
-      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      mMetadataPromise.RejectNS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
       return;
     }
 
     // Video track's frame sizes will not overflow. Activate the video track.
     mHasVideo = true;
     mInfo.mVideo.mDisplay = displaySize;
     mPicture = pictureRect;
     mInitialFrame = frameSize;
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -127,17 +127,17 @@ private:
       nsCOMPtr<nsIRunnable> event =
         new ReportResultTask(mDecodeJob, &WebAudioDecodeJob::OnFailure, aErrorCode);
       NS_DispatchToMainThread(event);
     }
   }
 
   void Decode();
   void OnMetadataRead(MetadataHolder* aMetadata);
-  void OnMetadataNotRead(ReadMetadataFailureReason aReason);
+  void OnMetadataNotRead(const MediaResult& aError);
   void RequestSample();
   void SampleDecoded(MediaData* aData);
   void SampleNotDecoded(const MediaResult& aError);
   void FinishDecode();
   void AllocateBuffer();
   void CallbackTheResult();
 
   void Cleanup()
@@ -305,17 +305,17 @@ MediaDecodeTask::OnMetadataRead(Metadata
     Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
   });
   AbstractThread::MainThread()->Dispatch(task.forget());
 
   RequestSample();
 }
 
 void
-MediaDecodeTask::OnMetadataNotRead(ReadMetadataFailureReason aReason)
+MediaDecodeTask::OnMetadataNotRead(const MediaResult& aReason)
 {
   mDecoderReader->Shutdown();
   ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent);
 }
 
 void
 MediaDecodeTask::RequestSample()
 {