Bug 1484242 - P3. Have MediaCapablities use GlobalAllocPolicy for creating decoders. r=bryce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sat, 18 Aug 2018 00:42:00 +0200
changeset 480910 5b802b94d59fbe606a9cd45c06b1f28febcbc242
parent 480909 114dacc6e603c411eb381a5ca371d436d108cdfd
child 480911 ebcdf2f8e40caa2dc71786df08c9316b4578bb32
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersbryce
bugs1484242
milestone63.0a1
Bug 1484242 - P3. Have MediaCapablities use GlobalAllocPolicy for creating decoders. r=bryce This ensures on platform that requires it, that only a single decoder at a time are used, in effect serialising all the MediaCapabilities.decodingInfo requests. Differential Revision: https://phabricator.services.mozilla.com/D3679
dom/media/mediacapabilities/MediaCapabilities.cpp
--- a/dom/media/mediacapabilities/MediaCapabilities.cpp
+++ b/dom/media/mediacapabilities/MediaCapabilities.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "MediaCapabilities.h"
+#include "AllocationPolicy.h"
 #include "Benchmark.h"
 #include "DecoderTraits.h"
 #include "Layers.h"
 #include "MediaInfo.h"
 #include "MediaRecorder.h"
 #include "PDMFactory.h"
 #include "VPXDecoder.h"
 #include "mozilla/Move.h"
@@ -323,78 +324,85 @@ MediaCapabilities::DecodingInfo(
         // 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 };
-
-        RefPtr<PDMFactory> pdm = new PDMFactory();
-        RefPtr<MediaDataDecoder> decoder = pdm->CreateDecoder(params);
-        if (!decoder) {
-          return CapabilitiesPromise::CreateAndReject(
-            MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, "Can't create decoder"),
-            __func__);
-        }
-        // We now query the decoder to determine if it's power efficient.
-        return decoder->Init()->Then(
+        return AllocationWrapper::CreateDecoder(params)->Then(
           taskQueue,
           __func__,
-          [taskQueue, decoder, frameRate, config = std::move(config)](
-            const MediaDataDecoder::InitPromise::ResolveOrRejectValue&
-              aValue) mutable {
-            RefPtr<CapabilitiesPromise> p;
+          [taskQueue, frameRate, config = std::move(config)](
+            const AllocationWrapper::AllocateDecoderPromise::
+              ResolveOrRejectValue& aValue) mutable {
             if (aValue.IsReject()) {
-              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 assume
-                // that if the video decoding is hardware accelerated it will be
-                // smooth and power efficient, otherwise we use the benchmark to
-                // estimate
-                powerEfficient = decoder->IsHardwareAccelerated(reason);
-                if (!powerEfficient && VPXDecoder::IsVP9(config->mMimeType)) {
-                  smooth = VP9Benchmark::IsVP9DecodeFast(true /* default */);
-                  uint32_t fps = VP9Benchmark::MediaBenchmarkVp9Fps();
-                  if (!smooth && fps > 0) {
-                    // The VP9 estimizer decode a 1280x720 video. Let's adjust
-                    // the result for the resolution and frame rate of what we
-                    // actually want. If the result is twice that we need we
-                    // assume it will be smooth.
-                    const auto& videoConfig = *config->GetAsVideoInfo();
-                    double needed =
-                      ((1280.0 * 720.0) /
-                       (videoConfig.mImage.width * videoConfig.mImage.height) *
-                       fps) /
-                      frameRate;
-                    smooth = needed > 2;
-                  }
-                }
-              }
-              p = CapabilitiesPromise::CreateAndResolve(
-                MediaCapabilitiesInfo(
-                  true /* supported */, smooth, powerEfficient),
-                __func__);
+              return CapabilitiesPromise::CreateAndReject(aValue.RejectValue(),
+                                                          __func__);
             }
-            MOZ_ASSERT(p.get(), "the promise has been created");
-            // Let's keep alive the decoder and the config object until the
-            // decoder has shutdown.
-            decoder->Shutdown()->Then(
+            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, config = std::move(config)](
-                const ShutdownPromise::ResolveOrRejectValue& aValue) {});
+              [taskQueue, decoder, frameRate, config = std::move(config)](
+                const MediaDataDecoder::InitPromise::ResolveOrRejectValue&
+                  aValue) mutable {
+                RefPtr<CapabilitiesPromise> p;
+                if (aValue.IsReject()) {
+                  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
+                    // assume that if the video decoding is hardware accelerated
+                    // it will be smooth and power efficient, otherwise we use
+                    // the benchmark to estimate
+                    powerEfficient = decoder->IsHardwareAccelerated(reason);
+                    if (!powerEfficient &&
+                        VPXDecoder::IsVP9(config->mMimeType)) {
+                      smooth =
+                        VP9Benchmark::IsVP9DecodeFast(true /* default */);
+                      uint32_t fps = VP9Benchmark::MediaBenchmarkVp9Fps();
+                      if (!smooth && fps > 0) {
+                        // The VP9 estimizer decode a 1280x720 video. Let's
+                        // adjust the result for the resolution and frame rate
+                        // of what we actually want. If the result is twice that
+                        // we need we assume it will be smooth.
+                        const auto& videoConfig = *config->GetAsVideoInfo();
+                        double needed = ((1280.0 * 720.0) /
+                                         (videoConfig.mImage.width *
+                                          videoConfig.mImage.height) *
+                                         fps) /
+                                        frameRate;
+                        smooth = needed > 2;
+                      }
+                    }
+                  }
+                  p = CapabilitiesPromise::CreateAndResolve(
+                    MediaCapabilitiesInfo(
+                      true /* supported */, smooth, powerEfficient),
+                    __func__);
+                }
+                MOZ_ASSERT(p.get(), "the promise has been created");
+                // Let's keep alive the decoder and the config object until the
+                // decoder has shutdown.
+                decoder->Shutdown()->Then(
+                  taskQueue,
+                  __func__,
+                  [taskQueue, decoder, config = std::move(config)](
+                    const ShutdownPromise::ResolveOrRejectValue& aValue) {});
+                return p;
+              });
             return p;
           });
       }));
   }
 
   auto holder =
     MakeRefPtr<DOMMozPromiseRequestHolder<CapabilitiesPromise::AllPromiseType>>(
       mParent);