xref: /aosp_15_r20/external/webrtc/media/engine/fake_webrtc_video_engine.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "media/engine/fake_webrtc_video_engine.h"
12 
13 #include <algorithm>
14 #include <memory>
15 
16 #include "absl/strings/match.h"
17 #include "media/base/codec.h"
18 #include "media/base/media_constants.h"
19 #include "media/engine/simulcast_encoder_adapter.h"
20 #include "modules/video_coding/include/video_error_codes.h"
21 #include "rtc_base/time_utils.h"
22 
23 namespace cricket {
24 
25 namespace {
26 
27 static constexpr webrtc::TimeDelta kEventTimeout =
28     webrtc::TimeDelta::Seconds(10);
29 
30 }  // namespace
31 
32 // Decoder.
FakeWebRtcVideoDecoder(FakeWebRtcVideoDecoderFactory * factory)33 FakeWebRtcVideoDecoder::FakeWebRtcVideoDecoder(
34     FakeWebRtcVideoDecoderFactory* factory)
35     : num_frames_received_(0), factory_(factory) {}
36 
~FakeWebRtcVideoDecoder()37 FakeWebRtcVideoDecoder::~FakeWebRtcVideoDecoder() {
38   if (factory_) {
39     factory_->DecoderDestroyed(this);
40   }
41 }
42 
Configure(const Settings & settings)43 bool FakeWebRtcVideoDecoder::Configure(const Settings& settings) {
44   return true;
45 }
46 
Decode(const webrtc::EncodedImage &,bool,int64_t)47 int32_t FakeWebRtcVideoDecoder::Decode(const webrtc::EncodedImage&,
48                                        bool,
49                                        int64_t) {
50   num_frames_received_++;
51   return WEBRTC_VIDEO_CODEC_OK;
52 }
53 
RegisterDecodeCompleteCallback(webrtc::DecodedImageCallback *)54 int32_t FakeWebRtcVideoDecoder::RegisterDecodeCompleteCallback(
55     webrtc::DecodedImageCallback*) {
56   return WEBRTC_VIDEO_CODEC_OK;
57 }
58 
Release()59 int32_t FakeWebRtcVideoDecoder::Release() {
60   return WEBRTC_VIDEO_CODEC_OK;
61 }
62 
GetNumFramesReceived() const63 int FakeWebRtcVideoDecoder::GetNumFramesReceived() const {
64   return num_frames_received_;
65 }
66 
67 // Decoder factory.
FakeWebRtcVideoDecoderFactory()68 FakeWebRtcVideoDecoderFactory::FakeWebRtcVideoDecoderFactory()
69     : num_created_decoders_(0) {}
70 
71 std::vector<webrtc::SdpVideoFormat>
GetSupportedFormats() const72 FakeWebRtcVideoDecoderFactory::GetSupportedFormats() const {
73   std::vector<webrtc::SdpVideoFormat> formats;
74 
75   for (const webrtc::SdpVideoFormat& format : supported_codec_formats_) {
76     // Don't add same codec twice.
77     if (!format.IsCodecInList(formats))
78       formats.push_back(format);
79   }
80 
81   return formats;
82 }
83 
84 std::unique_ptr<webrtc::VideoDecoder>
CreateVideoDecoder(const webrtc::SdpVideoFormat & format)85 FakeWebRtcVideoDecoderFactory::CreateVideoDecoder(
86     const webrtc::SdpVideoFormat& format) {
87   if (format.IsCodecInList(supported_codec_formats_)) {
88     num_created_decoders_++;
89     std::unique_ptr<FakeWebRtcVideoDecoder> decoder =
90         std::make_unique<FakeWebRtcVideoDecoder>(this);
91     decoders_.push_back(decoder.get());
92     return decoder;
93   }
94 
95   return nullptr;
96 }
97 
DecoderDestroyed(FakeWebRtcVideoDecoder * decoder)98 void FakeWebRtcVideoDecoderFactory::DecoderDestroyed(
99     FakeWebRtcVideoDecoder* decoder) {
100   decoders_.erase(std::remove(decoders_.begin(), decoders_.end(), decoder),
101                   decoders_.end());
102 }
103 
AddSupportedVideoCodecType(const std::string & name)104 void FakeWebRtcVideoDecoderFactory::AddSupportedVideoCodecType(
105     const std::string& name) {
106   // This is to match the default H264 params of cricket::VideoCodec.
107   cricket::VideoCodec video_codec(name);
108   supported_codec_formats_.push_back(
109       webrtc::SdpVideoFormat(video_codec.name, video_codec.params));
110 }
111 
GetNumCreatedDecoders()112 int FakeWebRtcVideoDecoderFactory::GetNumCreatedDecoders() {
113   return num_created_decoders_;
114 }
115 
116 const std::vector<FakeWebRtcVideoDecoder*>&
decoders()117 FakeWebRtcVideoDecoderFactory::decoders() {
118   return decoders_;
119 }
120 
121 // Encoder.
FakeWebRtcVideoEncoder(FakeWebRtcVideoEncoderFactory * factory)122 FakeWebRtcVideoEncoder::FakeWebRtcVideoEncoder(
123     FakeWebRtcVideoEncoderFactory* factory)
124     : num_frames_encoded_(0), factory_(factory) {}
125 
~FakeWebRtcVideoEncoder()126 FakeWebRtcVideoEncoder::~FakeWebRtcVideoEncoder() {
127   if (factory_) {
128     factory_->EncoderDestroyed(this);
129   }
130 }
131 
SetFecControllerOverride(webrtc::FecControllerOverride * fec_controller_override)132 void FakeWebRtcVideoEncoder::SetFecControllerOverride(
133     webrtc::FecControllerOverride* fec_controller_override) {
134   // Ignored.
135 }
136 
InitEncode(const webrtc::VideoCodec * codecSettings,const VideoEncoder::Settings & settings)137 int32_t FakeWebRtcVideoEncoder::InitEncode(
138     const webrtc::VideoCodec* codecSettings,
139     const VideoEncoder::Settings& settings) {
140   webrtc::MutexLock lock(&mutex_);
141   codec_settings_ = *codecSettings;
142   init_encode_event_.Set();
143   return WEBRTC_VIDEO_CODEC_OK;
144 }
145 
Encode(const webrtc::VideoFrame & inputImage,const std::vector<webrtc::VideoFrameType> * frame_types)146 int32_t FakeWebRtcVideoEncoder::Encode(
147     const webrtc::VideoFrame& inputImage,
148     const std::vector<webrtc::VideoFrameType>* frame_types) {
149   webrtc::MutexLock lock(&mutex_);
150   ++num_frames_encoded_;
151   init_encode_event_.Set();
152   return WEBRTC_VIDEO_CODEC_OK;
153 }
154 
RegisterEncodeCompleteCallback(webrtc::EncodedImageCallback * callback)155 int32_t FakeWebRtcVideoEncoder::RegisterEncodeCompleteCallback(
156     webrtc::EncodedImageCallback* callback) {
157   return WEBRTC_VIDEO_CODEC_OK;
158 }
159 
Release()160 int32_t FakeWebRtcVideoEncoder::Release() {
161   return WEBRTC_VIDEO_CODEC_OK;
162 }
163 
SetRates(const RateControlParameters & parameters)164 void FakeWebRtcVideoEncoder::SetRates(const RateControlParameters& parameters) {
165 }
166 
GetEncoderInfo() const167 webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()
168     const {
169   EncoderInfo info;
170   info.is_hardware_accelerated = true;
171   return info;
172 }
173 
WaitForInitEncode()174 bool FakeWebRtcVideoEncoder::WaitForInitEncode() {
175   return init_encode_event_.Wait(kEventTimeout);
176 }
177 
GetCodecSettings()178 webrtc::VideoCodec FakeWebRtcVideoEncoder::GetCodecSettings() {
179   webrtc::MutexLock lock(&mutex_);
180   return codec_settings_;
181 }
182 
GetNumEncodedFrames()183 int FakeWebRtcVideoEncoder::GetNumEncodedFrames() {
184   webrtc::MutexLock lock(&mutex_);
185   return num_frames_encoded_;
186 }
187 
188 // Video encoder factory.
FakeWebRtcVideoEncoderFactory()189 FakeWebRtcVideoEncoderFactory::FakeWebRtcVideoEncoderFactory()
190     : num_created_encoders_(0),
191       vp8_factory_mode_(false) {}
192 
193 std::vector<webrtc::SdpVideoFormat>
GetSupportedFormats() const194 FakeWebRtcVideoEncoderFactory::GetSupportedFormats() const {
195   std::vector<webrtc::SdpVideoFormat> formats;
196 
197   for (const webrtc::SdpVideoFormat& format : formats_) {
198     // Don't add same codec twice.
199     if (!format.IsCodecInList(formats))
200       formats.push_back(format);
201   }
202 
203   return formats;
204 }
205 
206 std::unique_ptr<webrtc::VideoEncoder>
CreateVideoEncoder(const webrtc::SdpVideoFormat & format)207 FakeWebRtcVideoEncoderFactory::CreateVideoEncoder(
208     const webrtc::SdpVideoFormat& format) {
209   webrtc::MutexLock lock(&mutex_);
210   std::unique_ptr<webrtc::VideoEncoder> encoder;
211   if (format.IsCodecInList(formats_)) {
212     if (absl::EqualsIgnoreCase(format.name, kVp8CodecName) &&
213         !vp8_factory_mode_) {
214       // The simulcast adapter will ask this factory for multiple VP8
215       // encoders. Enter vp8_factory_mode so that we now create these encoders
216       // instead of more adapters.
217       vp8_factory_mode_ = true;
218       encoder = std::make_unique<webrtc::SimulcastEncoderAdapter>(this, format);
219     } else {
220       num_created_encoders_++;
221       created_video_encoder_event_.Set();
222       encoder = std::make_unique<FakeWebRtcVideoEncoder>(this);
223       encoders_.push_back(static_cast<FakeWebRtcVideoEncoder*>(encoder.get()));
224     }
225   }
226   return encoder;
227 }
228 
WaitForCreatedVideoEncoders(int num_encoders)229 bool FakeWebRtcVideoEncoderFactory::WaitForCreatedVideoEncoders(
230     int num_encoders) {
231   int64_t start_offset_ms = rtc::TimeMillis();
232   int64_t wait_time = kEventTimeout.ms();
233   do {
234     if (GetNumCreatedEncoders() >= num_encoders)
235       return true;
236     wait_time = kEventTimeout.ms() - (rtc::TimeMillis() - start_offset_ms);
237   } while (wait_time > 0 && created_video_encoder_event_.Wait(
238                                 webrtc::TimeDelta::Millis(wait_time)));
239   return false;
240 }
241 
EncoderDestroyed(FakeWebRtcVideoEncoder * encoder)242 void FakeWebRtcVideoEncoderFactory::EncoderDestroyed(
243     FakeWebRtcVideoEncoder* encoder) {
244   webrtc::MutexLock lock(&mutex_);
245   encoders_.erase(std::remove(encoders_.begin(), encoders_.end(), encoder),
246                   encoders_.end());
247 }
248 
AddSupportedVideoCodec(const webrtc::SdpVideoFormat & format)249 void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodec(
250     const webrtc::SdpVideoFormat& format) {
251   formats_.push_back(format);
252 }
253 
AddSupportedVideoCodecType(const std::string & name)254 void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodecType(
255     const std::string& name) {
256   // This is to match the default H264 params of cricket::VideoCodec.
257   cricket::VideoCodec video_codec(name);
258   formats_.push_back(
259       webrtc::SdpVideoFormat(video_codec.name, video_codec.params));
260 }
261 
GetNumCreatedEncoders()262 int FakeWebRtcVideoEncoderFactory::GetNumCreatedEncoders() {
263   webrtc::MutexLock lock(&mutex_);
264   return num_created_encoders_;
265 }
266 
267 const std::vector<FakeWebRtcVideoEncoder*>
encoders()268 FakeWebRtcVideoEncoderFactory::encoders() {
269   webrtc::MutexLock lock(&mutex_);
270   return encoders_;
271 }
272 
273 }  // namespace cricket
274