Bug 1365524. P1 - Make MetadataHolder non-ref-counted. r?jya draft
authorJW Wang <jwwang@mozilla.com>
Thu, 18 May 2017 10:20:44 +0800
changeset 580252 45be779ff418bcb9cb6ef5227281b215abcb49ce
parent 580251 8c8ef6237a35d91123f8df7ae7b371e0fd447f0e
child 580253 b0edc1a68436d1476e7e882c52afabec98b823d6
push id59480
push userjwwang@mozilla.com
push dateThu, 18 May 2017 08:50:54 +0000
reviewersjya
bugs1365524
milestone55.0a1
Bug 1365524. P1 - Make MetadataHolder non-ref-counted. r?jya Since MozPromise supports move-only types, we don't need to make MetadataHolder a ref-counted type. MozReview-Commit-ID: E7KJuFQNWxe
dom/media/MediaDecoderReader.cpp
dom/media/MediaDecoderReader.h
dom/media/MediaDecoderReaderWrapper.cpp
dom/media/MediaDecoderReaderWrapper.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaFormatReader.cpp
dom/media/webaudio/MediaBufferDecoder.cpp
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -212,33 +212,36 @@ MediaDecoderReader::GetBuffered()
 
 RefPtr<MediaDecoderReader::MetadataPromise>
 MediaDecoderReader::AsyncReadMetadata()
 {
   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();
+  MetadataHolder metadata;
+  metadata.mInfo = MakeUnique<MediaInfo>();
+  MetadataTags* tags = nullptr;
+  nsresult rv = ReadMetadata(metadata.mInfo.get(), &tags);
+  metadata.mTags.reset(tags);
+  metadata.mInfo->AssertValid();
 
   // Update the buffer ranges before resolving the metadata promise. Bug 1320258.
   UpdateBuffered();
 
   // We're not waiting for anything. If we didn't get the metadata, that's an
   // error.
-  if (NS_FAILED(rv) || !metadata->mInfo.HasValidMedia()) {
+  if (NS_FAILED(rv) || !metadata.mInfo->HasValidMedia()) {
     DECODER_WARN("ReadMetadata failed, rv=%" PRIx32 " HasValidMedia=%d",
-                 static_cast<uint32_t>(rv), metadata->mInfo.HasValidMedia());
+                 static_cast<uint32_t>(rv), metadata.mInfo->HasValidMedia());
     return MetadataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
   }
 
   // Success!
-  return MetadataPromise::CreateAndResolve(metadata, __func__);
+  return MetadataPromise::CreateAndResolve(Move(metadata), __func__);
 }
 
 class ReRequestVideoWithSkipTask : public Runnable
 {
 public:
   ReRequestVideoWithSkipTask(MediaDecoderReader* aReader,
                              const media::TimeUnit& aTimeThreshold)
     : mReader(aReader)
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -50,25 +50,20 @@ struct SeekRejectValue
   MOZ_IMPLICIT SeekRejectValue(nsresult aResult)
     : mType(MediaData::NULL_DATA), mError(aResult) { }
   SeekRejectValue(MediaData::Type aType, const MediaResult& aError)
     : mType(aType), mError(aError) { }
   MediaData::Type mType;
   MediaResult mError;
 };
 
-class MetadataHolder
+struct MetadataHolder
 {
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataHolder)
-  MediaInfo mInfo;
-  nsAutoPtr<MetadataTags> mTags;
-
-private:
-  virtual ~MetadataHolder() { }
+  UniquePtr<MediaInfo> mInfo;
+  UniquePtr<MetadataTags> mTags;
 };
 
 // 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.
 // Unless otherwise specified, methods and fields of this class can only
 // be accessed on the decode task queue.
@@ -77,18 +72,17 @@ class MediaDecoderReader
   friend class ReRequestVideoWithSkipTask;
   friend class ReRequestAudioTask;
 
   static const bool IsExclusive = true;
 
 public:
   using TrackSet = EnumSet<TrackInfo::TrackType>;
 
-  using MetadataPromise =
-    MozPromise<RefPtr<MetadataHolder>, MediaResult, IsExclusive>;
+  using MetadataPromise = MozPromise<MetadataHolder, MediaResult, IsExclusive>;
 
   template <typename Type>
   using DataPromise = MozPromise<RefPtr<Type>, MediaResult, IsExclusive>;
   using AudioDataPromise = DataPromise<AudioData>;
   using VideoDataPromise = DataPromise<VideoData>;
 
   using SeekPromise = MozPromise<media::TimeUnit, SeekRejectValue, IsExclusive>;
 
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -133,28 +133,28 @@ MediaDecoderReaderWrapper::Shutdown()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   mShutdown = true;
   return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
                      &MediaDecoderReader::Shutdown);
 }
 
 RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
-MediaDecoderReaderWrapper::OnMetadataRead(RefPtr<MetadataHolder> aMetadata)
+MediaDecoderReaderWrapper::OnMetadataRead(MetadataHolder&& aMetadata)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   if (mShutdown) {
     return MetadataPromise::CreateAndReject(
       NS_ERROR_DOM_MEDIA_ABORT_ERR, __func__);
   }
 
   if (mStartTime.isNothing()) {
-    mStartTime.emplace(aMetadata->mInfo.mStartTime);
+    mStartTime.emplace(aMetadata.mInfo->mStartTime);
   }
-  return MetadataPromise::CreateAndResolve(aMetadata.forget(), __func__);
+  return MetadataPromise::CreateAndResolve(Move(aMetadata), __func__);
 }
 
 RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
 MediaDecoderReaderWrapper::OnMetadataNotRead(const MediaResult& aError)
 {
   return MetadataPromise::CreateAndReject(aError, __func__);
 }
 
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -85,17 +85,17 @@ public:
   }
 
   void SetCDMProxy(CDMProxy* aProxy) { mReader->SetCDMProxy(aProxy); }
 
   void SetVideoBlankDecode(bool aIsBlankDecode);
 
 private:
   ~MediaDecoderReaderWrapper();
-  RefPtr<MetadataPromise> OnMetadataRead(RefPtr<MetadataHolder> aMetadata);
+  RefPtr<MetadataPromise> OnMetadataRead(MetadataHolder&& aMetadata);
   RefPtr<MetadataPromise> OnMetadataNotRead(const MediaResult& aError);
 
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaDecoderReader> mReader;
 
   bool mShutdown = false;
   Maybe<media::TimeUnit> mStartTime;
 };
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -355,18 +355,18 @@ public:
 
     // Set mode to METADATA since we are about to read metadata.
     Resource()->SetReadMode(MediaCacheStream::MODE_METADATA);
 
     // We disconnect mMetadataRequest in Exit() so it is fine to capture
     // a raw pointer here.
     Reader()->ReadMetadata()
       ->Then(OwnerThread(), __func__,
-        [this] (RefPtr<MetadataHolder> aMetadata) {
-          OnMetadataRead(aMetadata);
+        [this] (MetadataHolder&& aMetadata) {
+          OnMetadataRead(Move(aMetadata));
         },
         [this] (const MediaResult& aError) {
           OnMetadataNotRead(aError);
         })
       ->Track(mMetadataRequest);
   }
 
   void Exit() override
@@ -392,17 +392,17 @@ public:
 
   void HandleResumeVideoDecoding(const TimeUnit&) override
   {
     // We never suspend video decoding in this state.
     MOZ_ASSERT(false, "Shouldn't have suspended video decoding.");
   }
 
 private:
-  void OnMetadataRead(MetadataHolder* aMetadata);
+  void OnMetadataRead(MetadataHolder&& aMetadata);
 
   void OnMetadataNotRead(const MediaResult& aError)
   {
     mMetadataRequest.Complete();
     SLOGW("Decode metadata failed, shutting down decoder");
     mMaster->DecodeError(aError);
   }
 
@@ -2125,24 +2125,24 @@ StateObject::SetSeekingState(SeekJob&& a
   }
 
   MOZ_ASSERT_UNREACHABLE("Unknown SeekTarget::Type.");
   return nullptr;
 }
 
 void
 MediaDecoderStateMachine::
-DecodeMetadataState::OnMetadataRead(MetadataHolder* aMetadata)
+DecodeMetadataState::OnMetadataRead(MetadataHolder&& aMetadata)
 {
   mMetadataRequest.Complete();
 
   // Set mode to PLAYBACK after reading metadata.
   Resource()->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
 
-  mMaster->mInfo.emplace(aMetadata->mInfo);
+  mMaster->mInfo.emplace(*aMetadata.mInfo);
   mMaster->mMediaSeekable = Info().mMediaSeekable;
   mMaster->mMediaSeekableOnlyInBufferedRanges =
     Info().mMediaSeekableOnlyInBufferedRanges;
 
   if (Info().mMetadataDuration.isSome()) {
     mMaster->RecomputeDuration();
   } else if (Info().mUnadjustedMetadataEndTime.isSome()) {
     const TimeUnit unadjusted = Info().mUnadjustedMetadataEndTime.ref();
@@ -2161,18 +2161,18 @@ DecodeMetadataState::OnMetadataRead(Meta
          Reader()->IsAsync(),
          Reader()->VideoIsHardwareAccelerated(),
          mMaster->GetAmpleVideoFrames());
   }
 
   MOZ_ASSERT(mMaster->mDuration.Ref().isSome());
 
   mMaster->mMetadataLoadedEvent.Notify(
-    nsAutoPtr<MediaInfo>(new MediaInfo(aMetadata->mInfo)),
-    Move(aMetadata->mTags),
+    nsAutoPtr<MediaInfo>(aMetadata.mInfo.release()),
+    nsAutoPtr<MetadataTags>(aMetadata.mTags.release()),
     MediaDecoderEventVisibility::Observable);
 
   if (Info().IsEncrypted() && !mMaster->mCDMProxy) {
     // Metadata parsing was successful but we're still waiting for CDM caps
     // to become available so that we can build the correct decryptor/decoder.
     SetState<WaitForCDMState>();
   } else {
     SetState<DecodingFirstFrameState>();
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1313,20 +1313,19 @@ RefPtr<MediaDecoderReader::MetadataPromi
 MediaFormatReader::AsyncReadMetadata()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   MOZ_DIAGNOSTIC_ASSERT(mMetadataPromise.IsEmpty());
 
   if (mInitDone) {
     // We are returning from dormant.
-    RefPtr<MetadataHolder> metadata = new MetadataHolder();
-    metadata->mInfo = mInfo;
-    metadata->mTags = nullptr;
-    return MetadataPromise::CreateAndResolve(metadata, __func__);
+    MetadataHolder metadata;
+    metadata.mInfo = MakeUnique<MediaInfo>(mInfo);
+    return MetadataPromise::CreateAndResolve(Move(metadata), __func__);
   }
 
   RefPtr<MetadataPromise> p = mMetadataPromise.Ensure(__func__);
 
   mDemuxer->Init()
     ->Then(OwnerThread(), __func__, this,
            &MediaFormatReader::OnDemuxerInitDone,
            &MediaFormatReader::OnDemuxerInitFailed)
@@ -1491,26 +1490,26 @@ MediaFormatReader::MaybeResolveMetadataP
   TimeUnit startTime =
     std::min(mAudio.mFirstDemuxedSampleTime.refOr(TimeUnit::FromInfinity()),
              mVideo.mFirstDemuxedSampleTime.refOr(TimeUnit::FromInfinity()));
 
   if (!startTime.IsInfinite()) {
     mInfo.mStartTime = startTime; // mInfo.mStartTime is initialized to 0.
   }
 
-  RefPtr<MetadataHolder> metadata = new MetadataHolder();
-  metadata->mInfo = mInfo;
-  metadata->mTags = mTags->Count() ? mTags.release() : nullptr;
+  MetadataHolder metadata;
+  metadata.mInfo = MakeUnique<MediaInfo>(mInfo);
+  metadata.mTags = mTags->Count() ? Move(mTags) : nullptr;
 
   // We now have all the informations required to calculate the initial buffered
   // range.
   mHasStartTime = true;
   UpdateBuffered();
 
-  mMetadataPromise.Resolve(metadata, __func__);
+  mMetadataPromise.Resolve(Move(metadata), __func__);
 }
 
 bool
 MediaFormatReader::IsEncrypted() const
 {
   return (HasAudio() && mInfo.mAudio.mCrypto.mValid)
          || (HasVideo() && mInfo.mVideo.mCrypto.mValid);
 }
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -109,17 +109,17 @@ private:
 
       nsCOMPtr<nsIRunnable> event =
         new ReportResultTask(mDecodeJob, &WebAudioDecodeJob::OnFailure, aErrorCode);
       mMainThread->Dispatch(event.forget());
     }
   }
 
   void Decode();
-  void OnMetadataRead(RefPtr<MetadataHolder> aMetadata);
+  void OnMetadataRead(MetadataHolder&& aMetadata);
   void OnMetadataNotRead(const MediaResult& aError);
   void RequestSample();
   void SampleDecoded(RefPtr<AudioData> aData);
   void SampleNotDecoded(const MediaResult& aError);
   void FinishDecode();
   void AllocateBuffer();
   void CallbackTheResult();
 
@@ -264,19 +264,19 @@ MediaDecodeTask::Decode()
   mDecoderReader->SetIgnoreAudioOutputFormat();
 
   mDecoderReader->AsyncReadMetadata()->Then(mDecoderReader->OwnerThread(), __func__, this,
                                        &MediaDecodeTask::OnMetadataRead,
                                        &MediaDecodeTask::OnMetadataNotRead);
 }
 
 void
-MediaDecodeTask::OnMetadataRead(RefPtr<MetadataHolder> aMetadata)
+MediaDecodeTask::OnMetadataRead(MetadataHolder&& aMetadata)
 {
-  mMediaInfo = aMetadata->mInfo;
+  mMediaInfo = *aMetadata.mInfo;
   if (!mMediaInfo.HasAudio()) {
     mDecoderReader->Shutdown();
     ReportFailureOnMainThread(WebAudioDecodeJob::NoAudio);
     return;
   }
 
   nsCString codec;
   if (!mMediaInfo.mAudio.GetAsAudioInfo()->mMimeType.IsEmpty()) {