Backed out changeset 157be32d85fe (bug 1504643) for conflicts while backing out bug 1471535
authorDorel Luca <dluca@mozilla.com>
Fri, 09 Nov 2018 12:13:54 +0200
changeset 445387 2f55b073ab557ba09694849b018f7eb13da2de0e
parent 445386 5c21b021bcf368a3e1c20083363c3ff7a51f6e37
child 445388 f6d29b57e6ba9d75d535c510d199df9b918e0c7b
push id35015
push userdluca@mozilla.com
push dateFri, 09 Nov 2018 17:45:20 +0000
treeherdermozilla-central@2f1158e5e0ce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1504643, 1471535
milestone65.0a1
backs out157be32d85fe86d9a091381ce7e304c834df4ce1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 157be32d85fe (bug 1504643) for conflicts while backing out bug 1471535
dom/media/Benchmark.cpp
dom/media/Benchmark.h
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/ipc/RemoteVideoDecoderChild.cpp
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderParent.cpp
dom/media/ipc/VideoDecoderParent.h
dom/media/mediacapabilities/MediaCapabilities.cpp
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
dom/media/platforms/android/RemoteDataDecoder.cpp
dom/media/platforms/apple/AppleATDecoder.cpp
dom/media/platforms/omx/OmxDataDecoder.cpp
dom/media/platforms/wrappers/MediaChangeMonitor.cpp
xpcom/threads/MozPromise.h
--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -330,17 +330,17 @@ BenchmarkPlayback::GlobalShutdown()
       },
       []() { MOZ_CRASH("not reached"); });
   } else {
     FinalizeShutdown();
   }
 }
 
 void
-BenchmarkPlayback::Output(MediaDataDecoder::DecodedData&& aResults)
+BenchmarkPlayback::Output(const MediaDataDecoder::DecodedData& aResults)
 {
   MOZ_ASSERT(OnThread());
   MOZ_ASSERT(!mFinished);
 
   RefPtr<Benchmark> ref(mGlobalState);
   mFrameCount += aResults.Length();
   if (!mDecodeStartTime && mFrameCount >= ref->mParameters.mStartupFrame) {
     mDecodeStartTime = Some(TimeStamp::Now());
@@ -386,38 +386,38 @@ BenchmarkPlayback::InputExhausted()
   RefPtr<MediaRawData> sample = mSamples[mSampleIndex];
   RefPtr<Benchmark> ref(mGlobalState);
   RefPtr<MediaDataDecoder::DecodePromise> p = mDecoder->Decode(sample);
 
   mSampleIndex++;
   if (mSampleIndex == mSamples.Length() && !ref->mParameters.mStopAtFrame) {
     // Complete current frame decode then drain if still necessary.
     p->Then(Thread(), __func__,
-            [ref, this](MediaDataDecoder::DecodedData&& aResults) {
-              Output(std::move(aResults));
+            [ref, this](const MediaDataDecoder::DecodedData& aResults) {
+              Output(aResults);
               if (!mFinished) {
                 mDecoder->Drain()->Then(
                   Thread(), __func__,
-                  [ref, this](MediaDataDecoder::DecodedData&& aResults) {
+                  [ref, this](const MediaDataDecoder::DecodedData& aResults) {
                     mDrained = true;
-                    Output(std::move(aResults));
+                    Output(aResults);
                     MOZ_ASSERT(mFinished, "We must be done now");
                   },
                   [ref, this](const MediaResult& aError) { Error(aError); });
               }
             },
             [ref, this](const MediaResult& aError) { Error(aError); });
   } else {
     if (mSampleIndex == mSamples.Length() && ref->mParameters.mStopAtFrame) {
       mSampleIndex = 0;
     }
     // Continue decoding
     p->Then(Thread(), __func__,
-            [ref, this](MediaDataDecoder::DecodedData&& aResults) {
-              Output(std::move(aResults));
+            [ref, this](const MediaDataDecoder::DecodedData& aResults) {
+              Output(aResults);
               if (!mFinished) {
                 InputExhausted();
               }
             },
             [ref, this](const MediaResult& aError) { Error(aError); });
   }
 }
 
--- a/dom/media/Benchmark.h
+++ b/dom/media/Benchmark.h
@@ -24,17 +24,17 @@ class BenchmarkPlayback : public QueueOb
 {
   friend class Benchmark;
   BenchmarkPlayback(Benchmark* aGlobalState, MediaDataDemuxer* aDemuxer);
   void DemuxSamples();
   void DemuxNextSample();
   void GlobalShutdown();
   void InitDecoder(TrackInfo&& aInfo);
 
-  void Output(MediaDataDecoder::DecodedData&& aResults);
+  void Output(const MediaDataDecoder::DecodedData& aResults);
   void Error(const MediaResult& aError);
   void InputExhausted();
 
   // Shutdown trackdemuxer and demuxer if any and shutdown the task queues.
   void FinalizeShutdown();
 
   Atomic<Benchmark*> mGlobalState;
 
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1840,26 +1840,26 @@ MediaFormatReader::OnAudioDemuxCompleted
         uint64_t(aSamples->mSamples.Length()));
   mAudio.mDemuxRequest.Complete();
   mAudio.mQueuedSamples.AppendElements(aSamples->mSamples);
   ScheduleUpdate(TrackInfo::kAudioTrack);
 }
 
 void
 MediaFormatReader::NotifyNewOutput(
-  TrackType aTrack, MediaDataDecoder::DecodedData&& aResults)
+  TrackType aTrack, const MediaDataDecoder::DecodedData& aResults)
 {
   MOZ_ASSERT(OnTaskQueue());
   auto& decoder = GetDecoderData(aTrack);
   if (aResults.IsEmpty()) {
     DDLOG(DDLogCategory::Log,
           aTrack == TrackInfo::kAudioTrack ? "decoded_audio" : "decoded_video",
           "no output samples");
   } else
-    for (auto&& sample : aResults) {
+    for (auto& sample : aResults) {
       if (DecoderDoctorLogger::IsDDLoggingEnabled()) {
         switch (sample->mType) {
           case MediaData::AUDIO_DATA:
             DDLOGPR(DDLogCategory::Log,
                     aTrack == TrackInfo::kAudioTrack ? "decoded_audio"
                                                      : "decoded_got_audio!?",
                     "{\"type\":\"AudioData\", \"offset\":%" PRIi64
                     ", \"time_us\":%" PRIi64 ", \"timecode_us\":%" PRIi64
@@ -2175,19 +2175,19 @@ MediaFormatReader::DecodeDemuxedSamples(
           aSample->mTimecode.ToMicroseconds(),
           aSample->mDuration.ToMicroseconds(),
           aSample->mFrames,
           aSample->mKeyframe ? " kf" : "",
           aSample->mEOS ? " eos" : "");
   decoder.mDecoder->Decode(aSample)
     ->Then(mTaskQueue, __func__,
            [self, aTrack, &decoder]
-           (MediaDataDecoder::DecodedData&& aResults) {
+           (const MediaDataDecoder::DecodedData& aResults) {
              decoder.mDecodeRequest.Complete();
-             self->NotifyNewOutput(aTrack, std::move(aResults));
+             self->NotifyNewOutput(aTrack, aResults);
 
              // When we recovered from a GPU crash and get the first decoded
              // frame, report the recovery time telemetry.
              if (aTrack == TrackType::kVideoTrack) {
                GPUProcessCrashTelemetryLogger::ReportTelemetry(
                  self->mMediaDecoderOwnerID, decoder.mDecoder.get());
              }
            },
@@ -2390,23 +2390,23 @@ MediaFormatReader::DrainDecoder(TrackTyp
 
   decoder.mDrainState = DrainState::Draining;
 
   DDLOG(DDLogCategory::Log, "draining", DDNoValue{});
   RefPtr<MediaFormatReader> self = this;
   decoder.mDecoder->Drain()
     ->Then(mTaskQueue, __func__,
            [self, aTrack, &decoder]
-           (MediaDataDecoder::DecodedData&& aResults) {
+           (const MediaDataDecoder::DecodedData& aResults) {
              decoder.mDrainRequest.Complete();
              DDLOGEX(self.get(), DDLogCategory::Log, "drained", DDNoValue{});
              if (aResults.IsEmpty()) {
                decoder.mDrainState = DrainState::DrainCompleted;
              } else {
-               self->NotifyNewOutput(aTrack, std::move(aResults));
+               self->NotifyNewOutput(aTrack, aResults);
                // Let's see if we have any more data available to drain.
                decoder.mDrainState = DrainState::PartialDrainPending;
              }
              self->ScheduleUpdate(aTrack);
            },
            [self, aTrack, &decoder](const MediaResult& aError) {
              decoder.mDrainRequest.Complete();
              DDLOGEX(self.get(), DDLogCategory::Log, "draining_error", aError);
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -313,17 +313,17 @@ private:
 
   // Perform an internal seek to aTime. If aDropTarget is true then
   // the first sample past the target will be dropped.
   void InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget);
 
   // Drain the current decoder.
   void DrainDecoder(TrackType aTrack);
   void NotifyNewOutput(TrackType aTrack,
-                       MediaDataDecoder::DecodedData&& aResults);
+                       const MediaDataDecoder::DecodedData& aResults);
   void NotifyError(TrackType aTrack, const MediaResult& aError);
   void NotifyWaitingForData(TrackType aTrack);
   void NotifyWaitingForKey(TrackType aTrack);
   void NotifyEndOfStream(TrackType aTrack);
 
   void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
 
   // Initializes mLayersBackendType if possible.
--- a/dom/media/ipc/RemoteVideoDecoderChild.cpp
+++ b/dom/media/ipc/RemoteVideoDecoderChild.cpp
@@ -114,35 +114,35 @@ RemoteVideoDecoderChild::RecvVideoOutput
   mDecodedData.AppendElement(std::move(video));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 RemoteVideoDecoderChild::RecvInputExhausted()
 {
   AssertOnManagerThread();
-  mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
-  mDecodedData = MediaDataDecoder::DecodedData();
+  mDecodePromise.ResolveIfExists(mDecodedData, __func__);
+  mDecodedData.Clear();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 RemoteVideoDecoderChild::RecvDrainComplete()
 {
   AssertOnManagerThread();
-  mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
-  mDecodedData = MediaDataDecoder::DecodedData();
+  mDrainPromise.ResolveIfExists(mDecodedData, __func__);
+  mDecodedData.Clear();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 RemoteVideoDecoderChild::RecvError(const nsresult& aError)
 {
   AssertOnManagerThread();
-  mDecodedData = MediaDataDecoder::DecodedData();
+  mDecodedData.Clear();
   mDecodePromise.RejectIfExists(aError, __func__);
   mDrainPromise.RejectIfExists(aError, __func__);
   mFlushPromise.RejectIfExists(aError, __func__);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 RemoteVideoDecoderChild::RecvInitComplete(const nsCString& aDecoderDescription,
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -76,35 +76,35 @@ VideoDecoderChild::RecvOutput(const Vide
   mDecodedData.AppendElement(std::move(video));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderChild::RecvInputExhausted()
 {
   AssertOnManagerThread();
-  mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
-  mDecodedData = MediaDataDecoder::DecodedData();
+  mDecodePromise.ResolveIfExists(mDecodedData, __func__);
+  mDecodedData.Clear();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderChild::RecvDrainComplete()
 {
   AssertOnManagerThread();
-  mDrainPromise.ResolveIfExists(std::move(mDecodedData), __func__);
-  mDecodedData = MediaDataDecoder::DecodedData();
+  mDrainPromise.ResolveIfExists(mDecodedData, __func__);
+  mDecodedData.Clear();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderChild::RecvError(const nsresult& aError)
 {
   AssertOnManagerThread();
-  mDecodedData = MediaDataDecoder::DecodedData();
+  mDecodedData.Clear();
   mDecodePromise.RejectIfExists(aError, __func__);
   mDrainPromise.RejectIfExists(aError, __func__);
   mFlushPromise.RejectIfExists(aError, __func__);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderChild::RecvInitComplete(const nsCString& aDecoderDescription,
@@ -148,17 +148,17 @@ VideoDecoderChild::ActorDestroy(ActorDes
     // Defer reporting an error until we've recreated the manager so that
     // it'll be safe for MediaFormatReader to recreate decoders
     RefPtr<VideoDecoderChild> ref = this;
     GetManager()->RunWhenRecreated(
       NS_NewRunnableFunction("dom::VideoDecoderChild::ActorDestroy", [=]() {
         MediaResult error(NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER);
         error.SetGPUCrashTimeStamp(ref->mGPUCrashTime);
         if (ref->mInitialized) {
-          mDecodedData = MediaDataDecoder::DecodedData();
+          mDecodedData.Clear();
           mDecodePromise.RejectIfExists(error, __func__);
           mDrainPromise.RejectIfExists(error, __func__);
           mFlushPromise.RejectIfExists(error, __func__);
           // Make sure the next request will be rejected accordingly if ever
           // called.
           mNeedNewDecoder = true;
         } else {
           ref->mInitPromise.RejectIfExists(error, __func__);
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -160,51 +160,52 @@ VideoDecoderParent::RecvInput(const Medi
   data->mDuration = TimeUnit::FromMicroseconds(aData.base().duration());
   data->mKeyframe = aData.base().keyframe();
 
   DeallocShmem(aData.buffer());
 
   RefPtr<VideoDecoderParent> self = this;
   mDecoder->Decode(data)->Then(
     mManagerTaskQueue, __func__,
-    [self, this](MediaDataDecoder::DecodedData&& aResults) {
+    [self, this](const MediaDataDecoder::DecodedData& aResults) {
       if (mDestroyed) {
         return;
       }
-      ProcessDecodedData(std::move(aResults));
+      ProcessDecodedData(aResults);
       Unused << SendInputExhausted();
     },
     [self](const MediaResult& aError) { self->Error(aError); });
   return IPC_OK();
 }
 
 void
-VideoDecoderParent::ProcessDecodedData(MediaDataDecoder::DecodedData&& aData)
+VideoDecoderParent::ProcessDecodedData(
+  const MediaDataDecoder::DecodedData& aData)
 {
   MOZ_ASSERT(OnManagerThread());
 
   // If the video decoder bridge has shut down, stop.
   if (!mKnowsCompositor->GetTextureForwarder()) {
     return;
   }
 
-  for (auto&& data : aData) {
+  for (const auto& data : aData) {
     MOZ_ASSERT(data->mType == MediaData::VIDEO_DATA,
                 "Can only decode videos using VideoDecoderParent!");
     VideoData* video = static_cast<VideoData*>(data.get());
 
     MOZ_ASSERT(video->mImage, "Decoded video must output a layer::Image to "
                               "be used with VideoDecoderParent");
 
     RefPtr<TextureClient> texture =
       video->mImage->GetTextureClient(mKnowsCompositor);
 
     if (!texture) {
       texture = ImageClient::CreateTextureClientForImage(video->mImage,
-                                                         mKnowsCompositor);
+                                                          mKnowsCompositor);
     }
 
     if (texture && !texture->IsAddedToCompositableClient()) {
       texture->InitIPDLActor(mKnowsCompositor);
       texture->SetAddedToCompositableClient();
     }
 
     VideoDataIPDL output(
@@ -242,19 +243,19 @@ VideoDecoderParent::RecvFlush()
 mozilla::ipc::IPCResult
 VideoDecoderParent::RecvDrain()
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(OnManagerThread());
   RefPtr<VideoDecoderParent> self = this;
   mDecoder->Drain()->Then(
     mManagerTaskQueue, __func__,
-    [self, this](MediaDataDecoder::DecodedData&& aResults) {
+    [self, this](const MediaDataDecoder::DecodedData& aResults) {
       if (!mDestroyed) {
-        ProcessDecodedData(std::move(aResults));
+        ProcessDecodedData(aResults);
         Unused << SendDrainComplete();
       }
     },
     [self](const MediaResult& aError) { self->Error(aError); });
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
--- a/dom/media/ipc/VideoDecoderParent.h
+++ b/dom/media/ipc/VideoDecoderParent.h
@@ -48,17 +48,17 @@ public:
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
 private:
   bool OnManagerThread();
   void Error(const MediaResult& aError);
 
   ~VideoDecoderParent();
-  void ProcessDecodedData(MediaDataDecoder::DecodedData&& aData);
+  void ProcessDecodedData(const MediaDataDecoder::DecodedData& aData);
 
   RefPtr<VideoDecoderManagerParent> mParent;
   RefPtr<VideoDecoderParent> mIPDLSelfRef;
   RefPtr<TaskQueue> mManagerTaskQueue;
   RefPtr<TaskQueue> mDecodeTaskQueue;
   RefPtr<MediaDataDecoder> mDecoder;
   RefPtr<KnowsCompositorVideo> mKnowsCompositor;
 
--- a/dom/media/mediacapabilities/MediaCapabilities.cpp
+++ b/dom/media/mediacapabilities/MediaCapabilities.cpp
@@ -246,50 +246,48 @@ MediaCapabilities::DecodingInfo(
     // supporting MTA, which the main thread doesn't. So we use our task queue
     // to create such decoder and perform initialization.
 
     RefPtr<layers::KnowsCompositor> compositor = GetCompositor();
     double frameRate = videoContainer->ExtendedType().GetFramerate().ref();
     promises.AppendElement(InvokeAsync(
       taskQueue,
       __func__,
-      [ taskQueue,
-        frameRate,
-        compositor,
-        config = std::move(config) ]() mutable -> RefPtr<CapabilitiesPromise> {
+      [taskQueue, frameRate, compositor, config = std::move(config)]() mutable
+      -> RefPtr<CapabilitiesPromise> {
         // MediaDataDecoder keeps a reference to the config object, so we must
         // keep it alive until the decoder has been shutdown.
         CreateDecoderParams params{ *config,
                                     taskQueue,
                                     compositor,
                                     CreateDecoderParams::VideoFrameRate(
                                       frameRate),
                                     TrackInfo::kVideoTrack };
         return AllocationWrapper::CreateDecoder(params)->Then(
           taskQueue,
           __func__,
-          [ taskQueue, frameRate, config = std::move(config) ](
-            AllocationWrapper::AllocateDecoderPromise::ResolveOrRejectValue&&
-            aValue) mutable {
+          [taskQueue, frameRate, config = std::move(config)](
+            const AllocationWrapper::AllocateDecoderPromise::
+              ResolveOrRejectValue& aValue) mutable {
             if (aValue.IsReject()) {
-              return CapabilitiesPromise::CreateAndReject(
-                std::move(aValue.RejectValue()), __func__);
+              return CapabilitiesPromise::CreateAndReject(aValue.RejectValue(),
+                                                          __func__);
             }
-            RefPtr<MediaDataDecoder> decoder = std::move(aValue.ResolveValue());
+            RefPtr<MediaDataDecoder> decoder = aValue.ResolveValue();
             // We now query the decoder to determine if it's power efficient.
             RefPtr<CapabilitiesPromise> p = decoder->Init()->Then(
               taskQueue,
               __func__,
-              [ taskQueue, decoder, frameRate, config = std::move(config) ](
-                MediaDataDecoder::InitPromise::ResolveOrRejectValue&&
-                aValue) mutable {
+              [taskQueue, decoder, frameRate, config = std::move(config)](
+                const MediaDataDecoder::InitPromise::ResolveOrRejectValue&
+                  aValue) mutable {
                 RefPtr<CapabilitiesPromise> p;
                 if (aValue.IsReject()) {
-                  p = CapabilitiesPromise::CreateAndReject(
-                    std::move(aValue.RejectValue()), __func__);
+                  p = CapabilitiesPromise::CreateAndReject(aValue.RejectValue(),
+                                                           __func__);
                 } else {
                   MOZ_ASSERT(config->IsVideo());
                   nsAutoCString reason;
                   bool powerEfficient = true;
                   bool smooth = true;
                   if (config->GetAsVideoInfo()->mImage.height > 480) {
                     // Assume that we can do stuff at 480p or less in a power
                     // efficient manner and smoothly. If greater than 480p we
@@ -365,25 +363,24 @@ MediaCapabilities::DecodingInfo(
 
   // this is only captured for use with the LOG macro.
   RefPtr<MediaCapabilities> self = this;
 
   CapabilitiesPromise::All(targetThread, promises)
     ->Then(
       targetThread,
       __func__,
-      [
-        promise,
-        tracks = std::move(tracks),
-        workerRef,
-        holder,
-        aConfiguration,
-        self,
-        this
-      ](CapabilitiesPromise::AllPromiseType::ResolveOrRejectValue&& aValue) {
+      [promise,
+       tracks = std::move(tracks),
+       workerRef,
+       holder,
+       aConfiguration,
+       self,
+       this](const CapabilitiesPromise::AllPromiseType::ResolveOrRejectValue&
+               aValue) {
         holder->Complete();
         if (aValue.IsReject()) {
           auto info =
             MakeUnique<MediaCapabilitiesInfo>(false /* supported */,
                                               false /* smooth */,
                                               false /* power efficient */);
           LOG("%s -> %s",
               MediaDecodingConfigurationToStr(aConfiguration).get(),
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -209,22 +209,24 @@ public:
         __func__);
     } else {
       MOZ_ASSERT(!mIsShutdown);
       // The sample is no longer encrypted, so clear its crypto metadata.
       UniquePtr<MediaRawDataWriter> writer(aDecrypted.mSample->CreateWriter());
       writer->mCrypto = CryptoSample();
       RefPtr<EMEDecryptor> self = this;
       mDecoder->Decode(aDecrypted.mSample)
-        ->Then(mTaskQueue,
-               __func__,
-               [self](DecodePromise::ResolveOrRejectValue&& aValue) {
+        ->Then(mTaskQueue, __func__,
+               [self](const DecodedData& aResults) {
                  self->mDecodeRequest.Complete();
-                 self->mDecodePromise.ResolveOrReject(std::move(aValue),
-                                                      __func__);
+                 self->mDecodePromise.ResolveIfExists(aResults, __func__);
+               },
+               [self](const MediaResult& aError) {
+                 self->mDecodeRequest.Complete();
+                 self->mDecodePromise.RejectIfExists(aError, __func__);
                })
         ->Track(mDecodeRequest);
     }
   }
 
   RefPtr<FlushPromise> Flush() override
   {
     RefPtr<EMEDecryptor> self = this;
@@ -343,24 +345,26 @@ EMEMediaDataDecoderProxy::Decode(MediaRa
     RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
     mSamplesWaitingForKey->WaitIfKeyNotUsable(sample)
       ->Then(mTaskQueue,
              __func__,
              [self, this](RefPtr<MediaRawData> aSample) {
                mKeyRequest.Complete();
 
                MediaDataDecoderProxy::Decode(aSample)
-                 ->Then(
-                   mTaskQueue,
-                   __func__,
-                   [self, this](DecodePromise::ResolveOrRejectValue&& aValue) {
-                     mDecodeRequest.Complete();
-                     mDecodePromise.ResolveOrReject(std::move(aValue),
-                                                    __func__);
-                   })
+                 ->Then(mTaskQueue,
+                        __func__,
+                        [self, this](const DecodedData& aResults) {
+                          mDecodeRequest.Complete();
+                          mDecodePromise.Resolve(aResults, __func__);
+                        },
+                        [self, this](const MediaResult& aError) {
+                          mDecodeRequest.Complete();
+                          mDecodePromise.Reject(aError, __func__);
+                        })
                  ->Track(mDecodeRequest);
              },
              [self]() {
                self->mKeyRequest.Complete();
                MOZ_CRASH("Should never get here");
              })
       ->Track(mKeyRequest);
 
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
@@ -96,26 +96,26 @@ GMPVideoDecoder::ReceivedDecodedFrame(co
 {
   MOZ_ASSERT(IsOnGMPThread());
 }
 
 void
 GMPVideoDecoder::InputDataExhausted()
 {
   MOZ_ASSERT(IsOnGMPThread());
-  mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
-  mDecodedData = DecodedData();
+  mDecodePromise.ResolveIfExists(mDecodedData, __func__);
+  mDecodedData.Clear();
 }
 
 void
 GMPVideoDecoder::DrainComplete()
 {
   MOZ_ASSERT(IsOnGMPThread());
-  mDrainPromise.ResolveIfExists(std::move(mDecodedData), __func__);
-  mDecodedData = DecodedData();
+  mDrainPromise.ResolveIfExists(mDecodedData, __func__);
+  mDecodedData.Clear();
 }
 
 void
 GMPVideoDecoder::ResetComplete()
 {
   MOZ_ASSERT(IsOnGMPThread());
   mFlushPromise.ResolveIfExists(true, __func__);
 }
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -493,17 +493,17 @@ RemoteDataDecoder::RemoteDataDecoder(Med
 {
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 RemoteDataDecoder::Flush()
 {
   RefPtr<RemoteDataDecoder> self = this;
   return InvokeAsync(mTaskQueue, __func__, [self, this]() {
-    mDecodedData = DecodedData();
+    mDecodedData.Clear();
     mNumPendingInputs = 0;
     mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     mDrainPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     mDrainStatus = DrainStatus::DRAINED;
     mJavaDecoder->Flush();
     return FlushPromise::CreateAndResolve(true, __func__);
   });
 }
@@ -721,22 +721,22 @@ RemoteDataDecoder::UpdateOutputStatus(Re
 void
 RemoteDataDecoder::ReturnDecodedData()
 {
   AssertOnTaskQueue();
   MOZ_ASSERT(!mShutdown);
 
   // We only want to clear mDecodedData when we have resolved the promises.
   if (!mDecodePromise.IsEmpty()) {
-    mDecodePromise.Resolve(std::move(mDecodedData), __func__);
-    mDecodedData = DecodedData();
+    mDecodePromise.Resolve(mDecodedData, __func__);
+    mDecodedData.Clear();
   } else if (!mDrainPromise.IsEmpty() &&
              (!mDecodedData.IsEmpty() || mDrainStatus == DrainStatus::DRAINED)) {
-    mDrainPromise.Resolve(std::move(mDecodedData), __func__);
-    mDecodedData = DecodedData();
+    mDrainPromise.Resolve(mDecodedData, __func__);
+    mDecodedData.Clear();
   }
 }
 
 void
 RemoteDataDecoder::DrainComplete()
 {
   if (!mTaskQueue->IsCurrentThreadIn()) {
     nsresult rv =
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -218,19 +218,17 @@ AppleATDecoder::ProcessDecode(MediaRawDa
       if (NS_FAILED(rv)) {
         mErrored = true;
         return DecodePromise::CreateAndReject(rv, __func__);
       }
     }
     mQueuedSamples.Clear();
   }
 
-  DecodedData results = std::move(mDecodedSamples);
-  mDecodedSamples = DecodedData();
-  return DecodePromise::CreateAndResolve(std::move(results), __func__);
+  return DecodePromise::CreateAndResolve(std::move(mDecodedSamples), __func__);
 }
 
 MediaResult
 AppleATDecoder::DecodeSample(MediaRawData* aSample)
 {
   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
 
   // Array containing the queued decoded audio frames, about to be output.
--- a/dom/media/platforms/omx/OmxDataDecoder.cpp
+++ b/dom/media/platforms/omx/OmxDataDecoder.cpp
@@ -132,22 +132,25 @@ OmxDataDecoder::InitializationTask()
 void
 OmxDataDecoder::EndOfStream()
 {
   LOG("");
   MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
 
   RefPtr<OmxDataDecoder> self = this;
   mOmxLayer->SendCommand(OMX_CommandFlush, OMX_ALL, nullptr)
-    ->Then(mOmxTaskQueue,
-           __func__,
-           [self, this](OmxCommandPromise::ResolveOrRejectValue&& aValue) {
-             mDrainPromise.ResolveIfExists(std::move(mDecodedData), __func__);
-             mDecodedData = DecodedData();
-           });
+    ->Then(mOmxTaskQueue, __func__,
+        [self, this] () {
+          mDrainPromise.ResolveIfExists(mDecodedData, __func__);
+            mDecodedData.Clear();
+        },
+        [self, this] () {
+          mDrainPromise.ResolveIfExists(mDecodedData, __func__);
+          mDecodedData.Clear();
+        });
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
 OmxDataDecoder::Init()
 {
   LOG("");
 
   RefPtr<OmxDataDecoder> self = this;
@@ -393,18 +396,18 @@ OmxDataDecoder::EmptyBufferDone(BufferDa
     nsCOMPtr<nsIRunnable> r =
       NS_NewRunnableFunction("OmxDataDecoder::EmptyBufferDone", [self, this]() {
         mCheckingInputExhausted = false;
 
         if (mMediaRawDatas.Length()) {
           return;
         }
 
-        mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
-        mDecodedData = DecodedData();
+        mDecodePromise.ResolveIfExists(mDecodedData, __func__);
+        mDecodedData.Clear();
       });
 
     nsresult rv = mOmxTaskQueue->Dispatch(r.forget());
     MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
     Unused << rv;
   }
 }
 
@@ -414,17 +417,17 @@ OmxDataDecoder::EmptyBufferFailure(OmxBu
   NotifyError(aFailureHolder.mError, __func__);
 }
 
 void
 OmxDataDecoder::NotifyError(OMX_ERRORTYPE aOmxError, const char* aLine, const MediaResult& aError)
 {
   LOG("NotifyError %d (%s) at %s", static_cast<int>(aOmxError),
       aError.ErrorName().get(), aLine);
-  mDecodedData = DecodedData();
+  mDecodedData.Clear();
   mDecodePromise.RejectIfExists(aError, __func__);
   mDrainPromise.RejectIfExists(aError, __func__);
   mFlushPromise.RejectIfExists(aError, __func__);
 }
 
 void
 OmxDataDecoder::FillAndEmptyBuffers()
 {
@@ -847,17 +850,17 @@ OmxDataDecoder::SendEosBuffer()
   FillAndEmptyBuffers();
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 OmxDataDecoder::DoFlush()
 {
   MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
 
-  mDecodedData = DecodedData();
+  mDecodedData.Clear();
   mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   mDrainPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
 
   RefPtr<FlushPromise> p = mFlushPromise.Ensure(__func__);
 
   // 1. Call OMX command OMX_CommandFlush in Omx TaskQueue.
   // 2. Remove all elements in mMediaRawDatas when flush is completed.
   mOmxLayer->SendCommand(OMX_CommandFlush, OMX_ALL, nullptr)
--- a/dom/media/platforms/wrappers/MediaChangeMonitor.cpp
+++ b/dom/media/platforms/wrappers/MediaChangeMonitor.cpp
@@ -547,38 +547,38 @@ MediaChangeMonitor::CanRecycleDecoder() 
 }
 
 void
 MediaChangeMonitor::DecodeFirstSample(MediaRawData* aSample)
 {
   AssertOnTaskQueue();
 
   if (mNeedKeyframe && !aSample->mKeyframe) {
-    mDecodePromise.Resolve(std::move(mPendingFrames), __func__);
-    mPendingFrames = DecodedData();
+    mDecodePromise.Resolve(mPendingFrames, __func__);
+    mPendingFrames.Clear();
     return;
   }
 
   MediaResult rv = mChangeMonitor->PrepareSample(*mConversionRequired, aSample);
 
   if (NS_FAILED(rv)) {
     mDecodePromise.Reject(rv, __func__);
     return;
   }
 
   mNeedKeyframe = false;
 
   RefPtr<MediaChangeMonitor> self = this;
   mDecoder->Decode(aSample)
     ->Then(AbstractThread::GetCurrent()->AsTaskQueue(), __func__,
-           [self, this](MediaDataDecoder::DecodedData&& aResults) {
+           [self, this](const MediaDataDecoder::DecodedData& aResults) {
              mDecodePromiseRequest.Complete();
-             mPendingFrames.AppendElements(std::move(aResults));
-             mDecodePromise.Resolve(std::move(mPendingFrames), __func__);
-             mPendingFrames = DecodedData();
+             mPendingFrames.AppendElements(aResults);
+             mDecodePromise.Resolve(mPendingFrames, __func__);
+             mPendingFrames.Clear();
            },
            [self, this](const MediaResult& aError) {
              mDecodePromiseRequest.Complete();
              mDecodePromise.Reject(aError, __func__);
            })
     ->Track(mDecodePromiseRequest);
 }
 
@@ -614,25 +614,25 @@ MediaChangeMonitor::DrainThenFlushDecode
 {
   AssertOnTaskQueue();
 
   RefPtr<MediaRawData> sample = aPendingSample;
   RefPtr<MediaChangeMonitor> self = this;
   mDecoder->Drain()
     ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
            __func__,
-           [self, sample, this](MediaDataDecoder::DecodedData&& aResults) {
+           [self, sample, this](const MediaDataDecoder::DecodedData& aResults) {
              mDrainRequest.Complete();
              if (!mFlushPromise.IsEmpty()) {
                // A Flush is pending, abort the current operation.
                mFlushPromise.Resolve(true, __func__);
                return;
              }
              if (aResults.Length() > 0) {
-               mPendingFrames.AppendElements(std::move(aResults));
+               mPendingFrames.AppendElements(aResults);
                DrainThenFlushDecoder(sample);
                return;
              }
              // We've completed the draining operation, we can now flush the
              // decoder.
              FlushThenShutdownDecoder(sample);
            },
            [self, this](const MediaResult& aError) {
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -1214,21 +1214,16 @@ public:
       mMonitor->AssertCurrentThreadOwns();
     }
     return mPromise.forget();
   }
 
   template<typename ResolveValueType_>
   void Resolve(ResolveValueType_&& aResolveValue, const char* aMethodName)
   {
-    static_assert(
-      IsConvertible<ResolveValueType_,
-                    typename PromiseType::ResolveValueType>::value,
-      "Resolve() argument must be convertible to MozPromise's ResolveValueT");
-
     if (mMonitor) {
       mMonitor->AssertCurrentThreadOwns();
     }
     MOZ_ASSERT(mPromise);
     mPromise->Resolve(std::forward<ResolveValueType_>(aResolveValue),
                       aMethodName);
     mPromise = nullptr;
   }
@@ -1240,21 +1235,16 @@ public:
     if (!IsEmpty()) {
       Resolve(std::forward<ResolveValueType_>(aResolveValue), aMethodName);
     }
   }
 
   template<typename RejectValueType_>
   void Reject(RejectValueType_&& aRejectValue, const char* aMethodName)
   {
-    static_assert(
-      IsConvertible<RejectValueType_,
-                    typename PromiseType::RejectValueType>::value,
-      "Reject() argument must be convertible to MozPromise's RejectValueT");
-
     if (mMonitor) {
       mMonitor->AssertCurrentThreadOwns();
     }
     MOZ_ASSERT(mPromise);
     mPromise->Reject(std::forward<RejectValueType_>(aRejectValue), aMethodName);
     mPromise = nullptr;
   }