stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2013 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 | |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 11 | #ifndef TEST_FAKE_ENCODER_H_ |
| 12 | #define TEST_FAKE_ENCODER_H_ |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 13 | |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 14 | #include <stddef.h> |
| 15 | #include <stdint.h> |
Jonas Olsson | a4d8737 | 2019-07-05 17:08:33 | [diff] [blame] | 16 | |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 17 | #include <memory> |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 18 | #include <vector> |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 19 | |
Elad Alon | 8f01c4e | 2019-06-28 13:19:43 | [diff] [blame] | 20 | #include "api/fec_controller_override.h" |
Artem Titov | d15a575 | 2021-02-10 13:31:24 | [diff] [blame] | 21 | #include "api/sequence_checker.h" |
Danil Chapovalov | 22ed366 | 2019-03-19 18:39:49 | [diff] [blame] | 22 | #include "api/task_queue/task_queue_factory.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 23 | #include "api/video/encoded_image.h" |
| 24 | #include "api/video/video_bitrate_allocation.h" |
| 25 | #include "api/video/video_frame.h" |
| 26 | #include "api/video_codecs/video_codec.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 27 | #include "api/video_codecs/video_encoder.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 28 | #include "modules/video_coding/include/video_codec_interface.h" |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 29 | #include "rtc_base/synchronization/mutex.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 30 | #include "rtc_base/thread_annotations.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 31 | #include "system_wrappers/include/clock.h" |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 32 | |
| 33 | namespace webrtc { |
pbos@webrtc.org | cb5118c | 2013-09-03 09:10:37 | [diff] [blame] | 34 | namespace test { |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 35 | |
| 36 | class FakeEncoder : public VideoEncoder { |
| 37 | public: |
| 38 | explicit FakeEncoder(Clock* clock); |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 39 | virtual ~FakeEncoder() = default; |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 40 | |
pbos@webrtc.org | 3349ae0 | 2014-03-13 12:52:27 | [diff] [blame] | 41 | // Sets max bitrate. Not thread-safe, call before registering the encoder. |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 42 | void SetMaxBitrate(int max_kbps) RTC_LOCKS_EXCLUDED(mutex_); |
| 43 | void SetQp(int qp) RTC_LOCKS_EXCLUDED(mutex_); |
pbos@webrtc.org | cb5118c | 2013-09-03 09:10:37 | [diff] [blame] | 44 | |
Elad Alon | 8f01c4e | 2019-06-28 13:19:43 | [diff] [blame] | 45 | void SetFecControllerOverride( |
| 46 | FecControllerOverride* fec_controller_override) override; |
| 47 | |
Markus Handell | 409784d | 2020-05-18 21:15:21 | [diff] [blame] | 48 | int32_t InitEncode(const VideoCodec* config, const Settings& settings) |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 49 | RTC_LOCKS_EXCLUDED(mutex_) override; |
Miguel Casas-Sanchez | 4765070 | 2015-05-30 00:21:40 | [diff] [blame] | 50 | int32_t Encode(const VideoFrame& input_image, |
Markus Handell | 409784d | 2020-05-18 21:15:21 | [diff] [blame] | 51 | const std::vector<VideoFrameType>* frame_types) |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 52 | RTC_LOCKS_EXCLUDED(mutex_) override; |
Markus Handell | 409784d | 2020-05-18 21:15:21 | [diff] [blame] | 53 | int32_t RegisterEncodeCompleteCallback(EncodedImageCallback* callback) |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 54 | RTC_LOCKS_EXCLUDED(mutex_) override; |
kjellander@webrtc.org | 14665ff | 2015-03-04 12:58:35 | [diff] [blame] | 55 | int32_t Release() override; |
Markus Handell | 409784d | 2020-05-18 21:15:21 | [diff] [blame] | 56 | void SetRates(const RateControlParameters& parameters) |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 57 | RTC_LOCKS_EXCLUDED(mutex_) override; |
| 58 | int GetConfiguredInputFramerate() const RTC_LOCKS_EXCLUDED(mutex_); |
Erik Språng | df351f4 | 2018-11-06 10:33:15 | [diff] [blame] | 59 | EncoderInfo GetEncoderInfo() const override; |
Peter Boström | b7d9a97 | 2015-12-18 15:01:11 | [diff] [blame] | 60 | |
| 61 | static const char* kImplementationName; |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 62 | |
pbos@webrtc.org | 273a414 | 2014-12-01 15:23:21 | [diff] [blame] | 63 | protected: |
Ilya Nikolaevskiy | b0588e6 | 2018-08-27 12:12:27 | [diff] [blame] | 64 | struct FrameInfo { |
| 65 | bool keyframe; |
| 66 | struct SpatialLayer { |
| 67 | SpatialLayer() = default; |
| 68 | SpatialLayer(int size, int temporal_id) |
| 69 | : size(size), temporal_id(temporal_id) {} |
| 70 | // Size of a current frame in the layer. |
| 71 | int size = 0; |
| 72 | // Temporal index of a current frame in the layer. |
| 73 | int temporal_id = 0; |
| 74 | }; |
| 75 | std::vector<SpatialLayer> layers; |
| 76 | }; |
| 77 | |
Niels Möller | 87e2d78 | 2019-03-07 09:18:23 | [diff] [blame] | 78 | FrameInfo NextFrame(const std::vector<VideoFrameType>* frame_types, |
Ilya Nikolaevskiy | b0588e6 | 2018-08-27 12:12:27 | [diff] [blame] | 79 | bool keyframe, |
| 80 | uint8_t num_simulcast_streams, |
| 81 | const VideoBitrateAllocation& target_bitrate, |
Niels Möller | 5b69aa6 | 2020-08-14 13:32:14 | [diff] [blame] | 82 | SpatialLayer simulcast_streams[kMaxSimulcastStreams], |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 83 | int framerate) RTC_LOCKS_EXCLUDED(mutex_); |
Ilya Nikolaevskiy | b0588e6 | 2018-08-27 12:12:27 | [diff] [blame] | 84 | |
Niels Möller | d738071 | 2019-03-06 09:09:47 | [diff] [blame] | 85 | // Called before the frame is passed to callback_->OnEncodedImage, to let |
Niels Möller | 08ae7ce | 2020-09-23 13:58:12 | [diff] [blame] | 86 | // subclasses fill out CodecSpecificInfo, possibly modify |encoded_image| or |
| 87 | // |buffer|. |
| 88 | virtual CodecSpecificInfo EncodeHook( |
| 89 | EncodedImage& encoded_image, |
| 90 | rtc::scoped_refptr<EncodedImageBuffer> buffer); |
Niels Möller | d738071 | 2019-03-06 09:09:47 | [diff] [blame] | 91 | |
Markus Handell | 409784d | 2020-05-18 21:15:21 | [diff] [blame] | 92 | void SetRatesLocked(const RateControlParameters& parameters) |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 93 | RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
Markus Handell | 409784d | 2020-05-18 21:15:21 | [diff] [blame] | 94 | |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 95 | FrameInfo last_frame_info_ RTC_GUARDED_BY(mutex_); |
pbos@webrtc.org | de1429e | 2014-04-28 13:00:21 | [diff] [blame] | 96 | Clock* const clock_; |
Ilya Nikolaevskiy | b0588e6 | 2018-08-27 12:12:27 | [diff] [blame] | 97 | |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 98 | VideoCodec config_ RTC_GUARDED_BY(mutex_); |
| 99 | EncodedImageCallback* callback_ RTC_GUARDED_BY(mutex_); |
| 100 | RateControlParameters current_rate_settings_ RTC_GUARDED_BY(mutex_); |
| 101 | int max_target_bitrate_kbps_ RTC_GUARDED_BY(mutex_); |
| 102 | bool pending_keyframe_ RTC_GUARDED_BY(mutex_); |
| 103 | uint32_t counter_ RTC_GUARDED_BY(mutex_); |
| 104 | mutable Mutex mutex_; |
Ilya Nikolaevskiy | b0588e6 | 2018-08-27 12:12:27 | [diff] [blame] | 105 | bool used_layers_[kMaxSimulcastStreams]; |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 106 | absl::optional<int> qp_ RTC_GUARDED_BY(mutex_); |
sprang | 4847ae6 | 2017-06-27 14:06:52 | [diff] [blame] | 107 | |
| 108 | // Current byte debt to be payed over a number of frames. |
| 109 | // The debt is acquired by keyframes overshooting the bitrate target. |
| 110 | size_t debt_bytes_; |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 111 | }; |
stefan@webrtc.org | 79c3359 | 2014-08-06 09:24:53 | [diff] [blame] | 112 | |
Niels Möller | d738071 | 2019-03-06 09:09:47 | [diff] [blame] | 113 | class FakeH264Encoder : public FakeEncoder { |
stefan@webrtc.org | 79c3359 | 2014-08-06 09:24:53 | [diff] [blame] | 114 | public: |
| 115 | explicit FakeH264Encoder(Clock* clock); |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 116 | virtual ~FakeH264Encoder() = default; |
stefan@webrtc.org | 79c3359 | 2014-08-06 09:24:53 | [diff] [blame] | 117 | |
stefan@webrtc.org | 79c3359 | 2014-08-06 09:24:53 | [diff] [blame] | 118 | private: |
Niels Möller | 08ae7ce | 2020-09-23 13:58:12 | [diff] [blame] | 119 | CodecSpecificInfo EncodeHook( |
| 120 | EncodedImage& encoded_image, |
| 121 | rtc::scoped_refptr<EncodedImageBuffer> buffer) override; |
Niels Möller | d738071 | 2019-03-06 09:09:47 | [diff] [blame] | 122 | |
Markus Handell | a376518 | 2020-07-08 11:13:32 | [diff] [blame] | 123 | int idr_counter_ RTC_GUARDED_BY(local_mutex_); |
| 124 | Mutex local_mutex_; |
stefan@webrtc.org | 79c3359 | 2014-08-06 09:24:53 | [diff] [blame] | 125 | }; |
asapersson@webrtc.org | 049e4ec | 2014-11-20 10:19:46 | [diff] [blame] | 126 | |
| 127 | class DelayedEncoder : public test::FakeEncoder { |
| 128 | public: |
| 129 | DelayedEncoder(Clock* clock, int delay_ms); |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 130 | virtual ~DelayedEncoder() = default; |
asapersson@webrtc.org | 049e4ec | 2014-11-20 10:19:46 | [diff] [blame] | 131 | |
perkj | 803d97f | 2016-11-01 18:45:46 | [diff] [blame] | 132 | void SetDelay(int delay_ms); |
Miguel Casas-Sanchez | 4765070 | 2015-05-30 00:21:40 | [diff] [blame] | 133 | int32_t Encode(const VideoFrame& input_image, |
Niels Möller | 87e2d78 | 2019-03-07 09:18:23 | [diff] [blame] | 134 | const std::vector<VideoFrameType>* frame_types) override; |
asapersson@webrtc.org | 049e4ec | 2014-11-20 10:19:46 | [diff] [blame] | 135 | |
| 136 | private: |
Niels Möller | 1e06289 | 2018-02-07 09:18:32 | [diff] [blame] | 137 | int delay_ms_ RTC_GUARDED_BY(sequence_checker_); |
Sebastian Jansson | b55015e | 2019-04-09 11:44:04 | [diff] [blame] | 138 | SequenceChecker sequence_checker_; |
asapersson@webrtc.org | 049e4ec | 2014-11-20 10:19:46 | [diff] [blame] | 139 | }; |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 140 | |
| 141 | // This class implements a multi-threaded fake encoder by posting |
| 142 | // FakeH264Encoder::Encode(.) tasks to |queue1_| and |queue2_|, in an |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 143 | // alternating fashion. The class itself does not need to be thread safe, |
mflodman | cc3d442 | 2017-08-03 15:27:51 | [diff] [blame] | 144 | // as it is called from the task queue in VideoStreamEncoder. |
brandtr | e78d266 | 2017-01-16 13:57:16 | [diff] [blame] | 145 | class MultithreadedFakeH264Encoder : public test::FakeH264Encoder { |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 146 | public: |
Danil Chapovalov | 22ed366 | 2019-03-19 18:39:49 | [diff] [blame] | 147 | MultithreadedFakeH264Encoder(Clock* clock, |
| 148 | TaskQueueFactory* task_queue_factory); |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 149 | virtual ~MultithreadedFakeH264Encoder() = default; |
| 150 | |
| 151 | int32_t InitEncode(const VideoCodec* config, |
Elad Alon | 370f93a | 2019-06-11 12:57:57 | [diff] [blame] | 152 | const Settings& settings) override; |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 153 | |
| 154 | int32_t Encode(const VideoFrame& input_image, |
Niels Möller | 87e2d78 | 2019-03-07 09:18:23 | [diff] [blame] | 155 | const std::vector<VideoFrameType>* frame_types) override; |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 156 | |
| 157 | int32_t EncodeCallback(const VideoFrame& input_image, |
Niels Möller | 87e2d78 | 2019-03-07 09:18:23 | [diff] [blame] | 158 | const std::vector<VideoFrameType>* frame_types); |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 159 | |
brandtr | 49ce67c | 2017-02-11 08:25:18 | [diff] [blame] | 160 | int32_t Release() override; |
| 161 | |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 162 | protected: |
| 163 | class EncodeTask; |
| 164 | |
Danil Chapovalov | 22ed366 | 2019-03-19 18:39:49 | [diff] [blame] | 165 | TaskQueueFactory* const task_queue_factory_; |
Niels Möller | 1e06289 | 2018-02-07 09:18:32 | [diff] [blame] | 166 | int current_queue_ RTC_GUARDED_BY(sequence_checker_); |
Danil Chapovalov | 22ed366 | 2019-03-19 18:39:49 | [diff] [blame] | 167 | std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue1_ |
| 168 | RTC_GUARDED_BY(sequence_checker_); |
| 169 | std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue2_ |
| 170 | RTC_GUARDED_BY(sequence_checker_); |
Sebastian Jansson | b55015e | 2019-04-09 11:44:04 | [diff] [blame] | 171 | SequenceChecker sequence_checker_; |
brandtr | 696c9c6 | 2016-12-19 13:47:28 | [diff] [blame] | 172 | }; |
| 173 | |
pbos@webrtc.org | cb5118c | 2013-09-03 09:10:37 | [diff] [blame] | 174 | } // namespace test |
stefan@webrtc.org | 360e376 | 2013-08-22 09:29:56 | [diff] [blame] | 175 | } // namespace webrtc |
| 176 | |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 177 | #endif // TEST_FAKE_ENCODER_H_ |