File: RemoteEncoderModule.cpp

package info (click to toggle)
firefox 147.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,532 kB
  • sloc: cpp: 7,607,356; javascript: 6,533,348; ansic: 3,775,236; python: 1,415,508; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,760; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (155 lines) | stat: -rw-r--r-- 5,362 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "RemoteEncoderModule.h"

#include "RemoteDecodeUtils.h"
#include "RemoteMediaDataEncoderChild.h"
#include "RemoteMediaManagerChild.h"

#ifdef MOZ_APPLEMEDIA
#  include "AppleUtils.h"
#endif

namespace mozilla {

extern LazyLogModule sPEMLog;

RemoteEncoderModule::RemoteEncoderModule(RemoteMediaIn aLocation)
    : mLocation(aLocation) {}

/* static */ already_AddRefed<PlatformEncoderModule>
RemoteEncoderModule::Create(RemoteMediaIn aLocation) {
  if (!XRE_IsContentProcess()) {
    // For now, the RemoteEncoderModule is only available in the content
    // process.
    MOZ_ASSERT_UNREACHABLE("Should not be created outside content process.");
    return nullptr;
  }

  RemoteMediaManagerChild::Init();
  return MakeAndAddRef<RemoteEncoderModule>(aLocation);
}

const char* RemoteEncoderModule::GetName() const {
  switch (mLocation) {
    case RemoteMediaIn::RddProcess:
      return "Remote Encoder Module (RDD)";
    case RemoteMediaIn::GpuProcess:
      return "Remote Encoder Module (GPU)";
    case RemoteMediaIn::UtilityProcess_Generic:
      return "Remote Encoder Module (Utility)";
    case RemoteMediaIn::UtilityProcess_AppleMedia:
      return "Remote Encoder Module (Utility AppleMedia)";
    case RemoteMediaIn::UtilityProcess_WMF:
      return "Remote Encoder Module (Utility WMF)";
    default:
      return "Remote Encoder Module";
  }
}

already_AddRefed<MediaDataEncoder> RemoteEncoderModule::CreateEncoder(
    const EncoderConfig& aConfig, const RefPtr<TaskQueue>& aTaskQueue) const {
  nsCOMPtr<nsISerialEventTarget> thread =
      RemoteMediaManagerChild::GetManagerThread();
  if (!thread) {
    // Shutdown has begun.
    MOZ_LOG(sPEMLog, LogLevel::Debug,
            ("Sandbox %s encoder requested codec %d after shutdown",
             RemoteMediaInToStr(mLocation), static_cast<int>(aConfig.mCodec)));
    return nullptr;
  }

  auto encoder =
      MakeRefPtr<RemoteMediaDataEncoderChild>(std::move(thread), mLocation);

  // This returns a promise, but we know that once it returns, the only
  // interactions the caller can do will require a dispatch to the manager
  // thread. The necessary IPDL constructor events are already queued so the
  // order of events is preserved.
  RemoteMediaManagerChild::InitializeEncoder(RefPtr{encoder}, aConfig);

  return encoder.forget();
}

RefPtr<PlatformEncoderModule::CreateEncoderPromise>
RemoteEncoderModule::AsyncCreateEncoder(const EncoderConfig& aEncoderConfig,
                                        const RefPtr<TaskQueue>& aTaskQueue) {
  nsCOMPtr<nsISerialEventTarget> thread =
      RemoteMediaManagerChild::GetManagerThread();
  if (!thread) {
    // Shutdown has begun.
    MOZ_LOG(sPEMLog, LogLevel::Debug,
            ("Sandbox %s encoder requested codec %d after shutdown",
             RemoteMediaInToStr(mLocation),
             static_cast<int>(aEncoderConfig.mCodec)));
    return PlatformEncoderModule::CreateEncoderPromise::CreateAndReject(
        MediaResult(NS_ERROR_DOM_MEDIA_CANCELED,
                    "Remote manager not available"),
        __func__);
  }

  auto encoder =
      MakeRefPtr<RemoteMediaDataEncoderChild>(std::move(thread), mLocation);
  return RemoteMediaManagerChild::InitializeEncoder(std::move(encoder),
                                                    aEncoderConfig);
}

media::EncodeSupportSet RemoteEncoderModule::Supports(
    const EncoderConfig& aConfig) const {
  if (!CanLikelyEncode(aConfig)) {
    return media::EncodeSupportSet{};
  }

  // TODO(aosmond): The platform specific criteria were copied from the various
  // PEMs in order to pass the WebCodecs WPTs but should eventually be rewritten
  // to generically support any PEM.

#ifdef MOZ_APPLEMEDIA
  // Only two temporal layers supported, and only from 11.3 and more recent
  if (aConfig.mCodec == CodecType::H264 &&
      (aConfig.mScalabilityMode == ScalabilityMode::L1T3 ||
       (aConfig.mScalabilityMode != ScalabilityMode::None &&
        !OSSupportsSVC()))) {
    return media::EncodeSupportSet{};
  }
#endif

#ifdef XP_WIN
  if (aConfig.mScalabilityMode != ScalabilityMode::None) {
    switch (aConfig.mCodec) {
      case CodecType::H264:
      case CodecType::VP8:
      case CodecType::VP9:
        // The codec type support check is sufficient.
        break;
      case CodecType::AV1:
        if (aConfig.mBitrateMode != BitrateMode::Constant) {
          return media::EncodeSupportSet{};
        }
        break;
      default:
        return media::EncodeSupportSet{};
    }
  }
#endif

  return SupportsCodec(aConfig.mCodec);
}

media::EncodeSupportSet RemoteEncoderModule::SupportsCodec(
    CodecType aCodecType) const {
  media::EncodeSupportSet supports =
      RemoteMediaManagerChild::Supports(mLocation, aCodecType);
  MOZ_LOG(sPEMLog, LogLevel::Debug,
          ("Sandbox %s encoder %s requested codec %d",
           RemoteMediaInToStr(mLocation),
           supports.isEmpty() ? "supports" : "rejects",
           static_cast<int>(aCodecType)));
  return supports;
}

}  // namespace mozilla