tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RemoteEncoderModule.cpp (5362B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "RemoteEncoderModule.h"
      8 
      9 #include "RemoteDecodeUtils.h"
     10 #include "RemoteMediaDataEncoderChild.h"
     11 #include "RemoteMediaManagerChild.h"
     12 
     13 #ifdef MOZ_APPLEMEDIA
     14 #  include "AppleUtils.h"
     15 #endif
     16 
     17 namespace mozilla {
     18 
     19 extern LazyLogModule sPEMLog;
     20 
     21 RemoteEncoderModule::RemoteEncoderModule(RemoteMediaIn aLocation)
     22    : mLocation(aLocation) {}
     23 
     24 /* static */ already_AddRefed<PlatformEncoderModule>
     25 RemoteEncoderModule::Create(RemoteMediaIn aLocation) {
     26  if (!XRE_IsContentProcess()) {
     27    // For now, the RemoteEncoderModule is only available in the content
     28    // process.
     29    MOZ_ASSERT_UNREACHABLE("Should not be created outside content process.");
     30    return nullptr;
     31  }
     32 
     33  RemoteMediaManagerChild::Init();
     34  return MakeAndAddRef<RemoteEncoderModule>(aLocation);
     35 }
     36 
     37 const char* RemoteEncoderModule::GetName() const {
     38  switch (mLocation) {
     39    case RemoteMediaIn::RddProcess:
     40      return "Remote Encoder Module (RDD)";
     41    case RemoteMediaIn::GpuProcess:
     42      return "Remote Encoder Module (GPU)";
     43    case RemoteMediaIn::UtilityProcess_Generic:
     44      return "Remote Encoder Module (Utility)";
     45    case RemoteMediaIn::UtilityProcess_AppleMedia:
     46      return "Remote Encoder Module (Utility AppleMedia)";
     47    case RemoteMediaIn::UtilityProcess_WMF:
     48      return "Remote Encoder Module (Utility WMF)";
     49    default:
     50      return "Remote Encoder Module";
     51  }
     52 }
     53 
     54 already_AddRefed<MediaDataEncoder> RemoteEncoderModule::CreateEncoder(
     55    const EncoderConfig& aConfig, const RefPtr<TaskQueue>& aTaskQueue) const {
     56  nsCOMPtr<nsISerialEventTarget> thread =
     57      RemoteMediaManagerChild::GetManagerThread();
     58  if (!thread) {
     59    // Shutdown has begun.
     60    MOZ_LOG(sPEMLog, LogLevel::Debug,
     61            ("Sandbox %s encoder requested codec %d after shutdown",
     62             RemoteMediaInToStr(mLocation), static_cast<int>(aConfig.mCodec)));
     63    return nullptr;
     64  }
     65 
     66  auto encoder =
     67      MakeRefPtr<RemoteMediaDataEncoderChild>(std::move(thread), mLocation);
     68 
     69  // This returns a promise, but we know that once it returns, the only
     70  // interactions the caller can do will require a dispatch to the manager
     71  // thread. The necessary IPDL constructor events are already queued so the
     72  // order of events is preserved.
     73  RemoteMediaManagerChild::InitializeEncoder(RefPtr{encoder}, aConfig);
     74 
     75  return encoder.forget();
     76 }
     77 
     78 RefPtr<PlatformEncoderModule::CreateEncoderPromise>
     79 RemoteEncoderModule::AsyncCreateEncoder(const EncoderConfig& aEncoderConfig,
     80                                        const RefPtr<TaskQueue>& aTaskQueue) {
     81  nsCOMPtr<nsISerialEventTarget> thread =
     82      RemoteMediaManagerChild::GetManagerThread();
     83  if (!thread) {
     84    // Shutdown has begun.
     85    MOZ_LOG(sPEMLog, LogLevel::Debug,
     86            ("Sandbox %s encoder requested codec %d after shutdown",
     87             RemoteMediaInToStr(mLocation),
     88             static_cast<int>(aEncoderConfig.mCodec)));
     89    return PlatformEncoderModule::CreateEncoderPromise::CreateAndReject(
     90        MediaResult(NS_ERROR_DOM_MEDIA_CANCELED,
     91                    "Remote manager not available"),
     92        __func__);
     93  }
     94 
     95  auto encoder =
     96      MakeRefPtr<RemoteMediaDataEncoderChild>(std::move(thread), mLocation);
     97  return RemoteMediaManagerChild::InitializeEncoder(std::move(encoder),
     98                                                    aEncoderConfig);
     99 }
    100 
    101 media::EncodeSupportSet RemoteEncoderModule::Supports(
    102    const EncoderConfig& aConfig) const {
    103  if (!CanLikelyEncode(aConfig)) {
    104    return media::EncodeSupportSet{};
    105  }
    106 
    107  // TODO(aosmond): The platform specific criteria were copied from the various
    108  // PEMs in order to pass the WebCodecs WPTs but should eventually be rewritten
    109  // to generically support any PEM.
    110 
    111 #ifdef MOZ_APPLEMEDIA
    112  // Only two temporal layers supported, and only from 11.3 and more recent
    113  if (aConfig.mCodec == CodecType::H264 &&
    114      (aConfig.mScalabilityMode == ScalabilityMode::L1T3 ||
    115       (aConfig.mScalabilityMode != ScalabilityMode::None &&
    116        !OSSupportsSVC()))) {
    117    return media::EncodeSupportSet{};
    118  }
    119 #endif
    120 
    121 #ifdef XP_WIN
    122  if (aConfig.mScalabilityMode != ScalabilityMode::None) {
    123    switch (aConfig.mCodec) {
    124      case CodecType::H264:
    125      case CodecType::VP8:
    126      case CodecType::VP9:
    127        // The codec type support check is sufficient.
    128        break;
    129      case CodecType::AV1:
    130        if (aConfig.mBitrateMode != BitrateMode::Constant) {
    131          return media::EncodeSupportSet{};
    132        }
    133        break;
    134      default:
    135        return media::EncodeSupportSet{};
    136    }
    137  }
    138 #endif
    139 
    140  return SupportsCodec(aConfig.mCodec);
    141 }
    142 
    143 media::EncodeSupportSet RemoteEncoderModule::SupportsCodec(
    144    CodecType aCodecType) const {
    145  media::EncodeSupportSet supports =
    146      RemoteMediaManagerChild::Supports(mLocation, aCodecType);
    147  MOZ_LOG(sPEMLog, LogLevel::Debug,
    148          ("Sandbox %s encoder %s requested codec %d",
    149           RemoteMediaInToStr(mLocation),
    150           supports.isEmpty() ? "supports" : "rejects",
    151           static_cast<int>(aCodecType)));
    152  return supports;
    153 }
    154 
    155 }  // namespace mozilla