1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/platform/peerconnection/video_codec_factory.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "build/build_config.h"
9 #include "media/video/gpu_video_accelerator_factories.h"
10 #include "third_party/blink/public/platform/platform.h"
11 #include "third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.h"
12 #include "third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.h"
13 #include "third_party/webrtc/api/video_codecs/video_decoder_software_fallback_wrapper.h"
14 #include "third_party/webrtc/api/video_codecs/video_encoder_software_fallback_wrapper.h"
15 #include "third_party/webrtc/media/base/codec.h"
16 #include "third_party/webrtc/media/engine/encoder_simulcast_proxy.h"
17 #include "third_party/webrtc/media/engine/internal_decoder_factory.h"
18 #include "third_party/webrtc/media/engine/internal_encoder_factory.h"
19 #include "third_party/webrtc/media/engine/simulcast_encoder_adapter.h"
20
21 #if defined(OS_ANDROID)
22 #include "media/base/android/media_codec_util.h"
23 #endif
24
25 namespace blink {
26
27 namespace {
28
IsFormatSupported(const std::vector<webrtc::SdpVideoFormat> & supported_formats,const webrtc::SdpVideoFormat & format)29 bool IsFormatSupported(
30 const std::vector<webrtc::SdpVideoFormat>& supported_formats,
31 const webrtc::SdpVideoFormat& format) {
32 for (const webrtc::SdpVideoFormat& supported_format : supported_formats) {
33 if (cricket::IsSameCodec(format.name, format.parameters,
34 supported_format.name,
35 supported_format.parameters)) {
36 return true;
37 }
38 }
39 return false;
40 }
41
42 template <typename Factory>
IsFormatSupported(const Factory * factory,const webrtc::SdpVideoFormat & format)43 bool IsFormatSupported(const Factory* factory,
44 const webrtc::SdpVideoFormat& format) {
45 return factory && IsFormatSupported(factory->GetSupportedFormats(), format);
46 }
47
48 // Merge |formats1| and |formats2|, but avoid adding duplicate formats.
MergeFormats(std::vector<webrtc::SdpVideoFormat> formats1,const std::vector<webrtc::SdpVideoFormat> & formats2)49 std::vector<webrtc::SdpVideoFormat> MergeFormats(
50 std::vector<webrtc::SdpVideoFormat> formats1,
51 const std::vector<webrtc::SdpVideoFormat>& formats2) {
52 for (const webrtc::SdpVideoFormat& format : formats2) {
53 // Don't add same format twice.
54 if (!IsFormatSupported(formats1, format))
55 formats1.push_back(format);
56 }
57 return formats1;
58 }
59
CreateDecoder(webrtc::VideoDecoderFactory * factory,const webrtc::SdpVideoFormat & format)60 std::unique_ptr<webrtc::VideoDecoder> CreateDecoder(
61 webrtc::VideoDecoderFactory* factory,
62 const webrtc::SdpVideoFormat& format) {
63 return factory ? factory->CreateVideoDecoder(format) : nullptr;
64 }
65
Wrap(std::unique_ptr<webrtc::VideoDecoder> software_decoder,std::unique_ptr<webrtc::VideoDecoder> hardware_decoder)66 std::unique_ptr<webrtc::VideoDecoder> Wrap(
67 std::unique_ptr<webrtc::VideoDecoder> software_decoder,
68 std::unique_ptr<webrtc::VideoDecoder> hardware_decoder) {
69 if (software_decoder && hardware_decoder) {
70 return webrtc::CreateVideoDecoderSoftwareFallbackWrapper(
71 std::move(software_decoder), std::move(hardware_decoder));
72 }
73 return hardware_decoder ? std::move(hardware_decoder)
74 : std::move(software_decoder);
75 }
76
Wrap(std::unique_ptr<webrtc::VideoEncoder> software_encoder,std::unique_ptr<webrtc::VideoEncoder> hardware_encoder)77 std::unique_ptr<webrtc::VideoEncoder> Wrap(
78 std::unique_ptr<webrtc::VideoEncoder> software_encoder,
79 std::unique_ptr<webrtc::VideoEncoder> hardware_encoder) {
80 if (software_encoder && hardware_encoder) {
81 return webrtc::CreateVideoEncoderSoftwareFallbackWrapper(
82 std::move(software_encoder), std::move(hardware_encoder));
83 }
84 return hardware_encoder ? std::move(hardware_encoder)
85 : std::move(software_encoder);
86 }
87
88 // This class combines a hardware factory with the internal factory and adds
89 // internal SW codecs, simulcast, and SW fallback wrappers.
90 class EncoderAdapter : public webrtc::VideoEncoderFactory {
91 public:
EncoderAdapter(std::unique_ptr<webrtc::VideoEncoderFactory> hardware_encoder_factory)92 explicit EncoderAdapter(
93 std::unique_ptr<webrtc::VideoEncoderFactory> hardware_encoder_factory)
94 : hardware_encoder_factory_(std::move(hardware_encoder_factory)) {}
95
QueryVideoEncoder(const webrtc::SdpVideoFormat & format) const96 webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
97 const webrtc::SdpVideoFormat& format) const override {
98 const webrtc::VideoEncoderFactory* factory =
99 IsFormatSupported(hardware_encoder_factory_.get(), format)
100 ? hardware_encoder_factory_.get()
101 : &software_encoder_factory_;
102 return factory->QueryVideoEncoder(format);
103 }
104
CreateVideoEncoder(const webrtc::SdpVideoFormat & format)105 std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
106 const webrtc::SdpVideoFormat& format) override {
107 const bool supported_in_software =
108 IsFormatSupported(&software_encoder_factory_, format);
109 const bool supported_in_hardware =
110 IsFormatSupported(hardware_encoder_factory_.get(), format);
111
112 if (!supported_in_software && !supported_in_hardware)
113 return nullptr;
114
115 if (base::EqualsCaseInsensitiveASCII(format.name.c_str(),
116 cricket::kVp9CodecName) ||
117 base::EqualsCaseInsensitiveASCII(format.name.c_str(),
118 cricket::kAv1CodecName)) {
119 // For VP9 and AV1 we don't use simulcast.
120 if (supported_in_hardware && supported_in_software) {
121 return Wrap(software_encoder_factory_.CreateVideoEncoder(format),
122 hardware_encoder_factory_->CreateVideoEncoder(format));
123 } else if (supported_in_software) {
124 return software_encoder_factory_.CreateVideoEncoder(format);
125 }
126 return hardware_encoder_factory_->CreateVideoEncoder(format);
127 }
128
129 if (!supported_in_hardware || !hardware_encoder_factory_.get()) {
130 return std::make_unique<webrtc::SimulcastEncoderAdapter>(
131 &software_encoder_factory_, nullptr, format);
132 } else if (!supported_in_software) {
133 return std::make_unique<webrtc::SimulcastEncoderAdapter>(
134 hardware_encoder_factory_.get(), nullptr, format);
135 }
136
137 return std::make_unique<webrtc::SimulcastEncoderAdapter>(
138 hardware_encoder_factory_.get(), &software_encoder_factory_, format);
139 }
140
GetSupportedFormats() const141 std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
142 std::vector<webrtc::SdpVideoFormat> software_formats =
143 software_encoder_factory_.GetSupportedFormats();
144 return hardware_encoder_factory_
145 ? MergeFormats(software_formats,
146 hardware_encoder_factory_->GetSupportedFormats())
147 : software_formats;
148 }
149
150 private:
151 webrtc::InternalEncoderFactory software_encoder_factory_;
152 const std::unique_ptr<webrtc::VideoEncoderFactory> hardware_encoder_factory_;
153 };
154
155 // This class combines a hardware codec factory with the internal factory and
156 // adds internal SW codecs and SW fallback wrappers.
157 class DecoderAdapter : public webrtc::VideoDecoderFactory {
158 public:
DecoderAdapter(std::unique_ptr<webrtc::VideoDecoderFactory> hardware_decoder_factory)159 explicit DecoderAdapter(
160 std::unique_ptr<webrtc::VideoDecoderFactory> hardware_decoder_factory)
161 : hardware_decoder_factory_(std::move(hardware_decoder_factory)) {}
162
CreateVideoDecoder(const webrtc::SdpVideoFormat & format)163 std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
164 const webrtc::SdpVideoFormat& format) override {
165 std::unique_ptr<webrtc::VideoDecoder> software_decoder =
166 CreateDecoder(&software_decoder_factory_, format);
167
168 std::unique_ptr<webrtc::VideoDecoder> hardware_decoder =
169 CreateDecoder(hardware_decoder_factory_.get(), format);
170
171 return Wrap(std::move(software_decoder), std::move(hardware_decoder));
172 }
173
GetSupportedFormats() const174 std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
175 std::vector<webrtc::SdpVideoFormat> software_formats =
176 software_decoder_factory_.GetSupportedFormats();
177 return hardware_decoder_factory_
178 ? MergeFormats(software_formats,
179 hardware_decoder_factory_->GetSupportedFormats())
180 : software_formats;
181 }
182
183 private:
184 webrtc::InternalDecoderFactory software_decoder_factory_;
185 const std::unique_ptr<webrtc::VideoDecoderFactory> hardware_decoder_factory_;
186 };
187
188 } // namespace
189
CreateHWVideoEncoderFactory(media::GpuVideoAcceleratorFactories * gpu_factories)190 std::unique_ptr<webrtc::VideoEncoderFactory> CreateHWVideoEncoderFactory(
191 media::GpuVideoAcceleratorFactories* gpu_factories) {
192 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
193
194 if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled() &&
195 Platform::Current()->IsWebRtcHWEncodingEnabled()) {
196 encoder_factory = std::make_unique<RTCVideoEncoderFactory>(gpu_factories);
197 }
198
199 #if defined(OS_ANDROID)
200 if (!media::MediaCodecUtil::SupportsSetParameters())
201 encoder_factory.reset();
202 #endif
203
204 return encoder_factory;
205 }
206
CreateWebrtcVideoEncoderFactory(media::GpuVideoAcceleratorFactories * gpu_factories)207 std::unique_ptr<webrtc::VideoEncoderFactory> CreateWebrtcVideoEncoderFactory(
208 media::GpuVideoAcceleratorFactories* gpu_factories) {
209 return std::make_unique<EncoderAdapter>(
210 CreateHWVideoEncoderFactory(gpu_factories));
211 }
212
CreateWebrtcVideoDecoderFactory(media::GpuVideoAcceleratorFactories * gpu_factories)213 std::unique_ptr<webrtc::VideoDecoderFactory> CreateWebrtcVideoDecoderFactory(
214 media::GpuVideoAcceleratorFactories* gpu_factories) {
215 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
216
217 if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled() &&
218 Platform::Current()->IsWebRtcHWDecodingEnabled()) {
219 decoder_factory = std::make_unique<RTCVideoDecoderFactory>(gpu_factories);
220 }
221
222 return std::make_unique<DecoderAdapter>(std::move(decoder_factory));
223 }
224
225 } // namespace blink
226