xref: /aosp_15_r20/external/webrtc/test/fake_encoder.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef TEST_FAKE_ENCODER_H_
12*d9f75844SAndroid Build Coastguard Worker #define TEST_FAKE_ENCODER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <memory>
18*d9f75844SAndroid Build Coastguard Worker #include <vector>
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker #include "api/fec_controller_override.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_factory.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/video/encoded_image.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_bitrate_allocation.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_codec.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_encoder.h"
28*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/include/video_codec_interface.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h"
30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h"
31*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
32*d9f75844SAndroid Build Coastguard Worker 
33*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
34*d9f75844SAndroid Build Coastguard Worker namespace test {
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker class FakeEncoder : public VideoEncoder {
37*d9f75844SAndroid Build Coastguard Worker  public:
38*d9f75844SAndroid Build Coastguard Worker   explicit FakeEncoder(Clock* clock);
39*d9f75844SAndroid Build Coastguard Worker   virtual ~FakeEncoder() = default;
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker   // Sets max bitrate. Not thread-safe, call before registering the encoder.
42*d9f75844SAndroid Build Coastguard Worker   void SetMaxBitrate(int max_kbps) RTC_LOCKS_EXCLUDED(mutex_);
43*d9f75844SAndroid Build Coastguard Worker   void SetQp(int qp) RTC_LOCKS_EXCLUDED(mutex_);
44*d9f75844SAndroid Build Coastguard Worker 
45*d9f75844SAndroid Build Coastguard Worker   void SetFecControllerOverride(
46*d9f75844SAndroid Build Coastguard Worker       FecControllerOverride* fec_controller_override) override;
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker   int32_t InitEncode(const VideoCodec* config, const Settings& settings)
49*d9f75844SAndroid Build Coastguard Worker       RTC_LOCKS_EXCLUDED(mutex_) override;
50*d9f75844SAndroid Build Coastguard Worker   int32_t Encode(const VideoFrame& input_image,
51*d9f75844SAndroid Build Coastguard Worker                  const std::vector<VideoFrameType>* frame_types)
52*d9f75844SAndroid Build Coastguard Worker       RTC_LOCKS_EXCLUDED(mutex_) override;
53*d9f75844SAndroid Build Coastguard Worker   int32_t RegisterEncodeCompleteCallback(EncodedImageCallback* callback)
54*d9f75844SAndroid Build Coastguard Worker       RTC_LOCKS_EXCLUDED(mutex_) override;
55*d9f75844SAndroid Build Coastguard Worker   int32_t Release() override;
56*d9f75844SAndroid Build Coastguard Worker   void SetRates(const RateControlParameters& parameters)
57*d9f75844SAndroid Build Coastguard Worker       RTC_LOCKS_EXCLUDED(mutex_) override;
58*d9f75844SAndroid Build Coastguard Worker   EncoderInfo GetEncoderInfo() const override;
59*d9f75844SAndroid Build Coastguard Worker 
60*d9f75844SAndroid Build Coastguard Worker   int GetConfiguredInputFramerate() const RTC_LOCKS_EXCLUDED(mutex_);
61*d9f75844SAndroid Build Coastguard Worker   int GetNumInitializations() const RTC_LOCKS_EXCLUDED(mutex_);
62*d9f75844SAndroid Build Coastguard Worker   const VideoCodec& config() const RTC_LOCKS_EXCLUDED(mutex_);
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker   static const char* kImplementationName;
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker  protected:
67*d9f75844SAndroid Build Coastguard Worker   struct FrameInfo {
68*d9f75844SAndroid Build Coastguard Worker     bool keyframe;
69*d9f75844SAndroid Build Coastguard Worker     struct SpatialLayer {
70*d9f75844SAndroid Build Coastguard Worker       SpatialLayer() = default;
SpatialLayerFrameInfo::SpatialLayer71*d9f75844SAndroid Build Coastguard Worker       SpatialLayer(int size, int temporal_id)
72*d9f75844SAndroid Build Coastguard Worker           : size(size), temporal_id(temporal_id) {}
73*d9f75844SAndroid Build Coastguard Worker       // Size of a current frame in the layer.
74*d9f75844SAndroid Build Coastguard Worker       int size = 0;
75*d9f75844SAndroid Build Coastguard Worker       // Temporal index of a current frame in the layer.
76*d9f75844SAndroid Build Coastguard Worker       int temporal_id = 0;
77*d9f75844SAndroid Build Coastguard Worker     };
78*d9f75844SAndroid Build Coastguard Worker     std::vector<SpatialLayer> layers;
79*d9f75844SAndroid Build Coastguard Worker   };
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker   FrameInfo NextFrame(const std::vector<VideoFrameType>* frame_types,
82*d9f75844SAndroid Build Coastguard Worker                       bool keyframe,
83*d9f75844SAndroid Build Coastguard Worker                       uint8_t num_simulcast_streams,
84*d9f75844SAndroid Build Coastguard Worker                       const VideoBitrateAllocation& target_bitrate,
85*d9f75844SAndroid Build Coastguard Worker                       SimulcastStream simulcast_streams[kMaxSimulcastStreams],
86*d9f75844SAndroid Build Coastguard Worker                       int framerate) RTC_LOCKS_EXCLUDED(mutex_);
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   // Called before the frame is passed to callback_->OnEncodedImage, to let
89*d9f75844SAndroid Build Coastguard Worker   // subclasses fill out CodecSpecificInfo, possibly modify `encoded_image` or
90*d9f75844SAndroid Build Coastguard Worker   // `buffer`.
91*d9f75844SAndroid Build Coastguard Worker   virtual CodecSpecificInfo EncodeHook(
92*d9f75844SAndroid Build Coastguard Worker       EncodedImage& encoded_image,
93*d9f75844SAndroid Build Coastguard Worker       rtc::scoped_refptr<EncodedImageBuffer> buffer);
94*d9f75844SAndroid Build Coastguard Worker 
95*d9f75844SAndroid Build Coastguard Worker   void SetRatesLocked(const RateControlParameters& parameters)
96*d9f75844SAndroid Build Coastguard Worker       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
97*d9f75844SAndroid Build Coastguard Worker 
98*d9f75844SAndroid Build Coastguard Worker   FrameInfo last_frame_info_ RTC_GUARDED_BY(mutex_);
99*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker   VideoCodec config_ RTC_GUARDED_BY(mutex_);
102*d9f75844SAndroid Build Coastguard Worker   int num_initializations_ RTC_GUARDED_BY(mutex_);
103*d9f75844SAndroid Build Coastguard Worker   EncodedImageCallback* callback_ RTC_GUARDED_BY(mutex_);
104*d9f75844SAndroid Build Coastguard Worker   RateControlParameters current_rate_settings_ RTC_GUARDED_BY(mutex_);
105*d9f75844SAndroid Build Coastguard Worker   int max_target_bitrate_kbps_ RTC_GUARDED_BY(mutex_);
106*d9f75844SAndroid Build Coastguard Worker   bool pending_keyframe_ RTC_GUARDED_BY(mutex_);
107*d9f75844SAndroid Build Coastguard Worker   uint32_t counter_ RTC_GUARDED_BY(mutex_);
108*d9f75844SAndroid Build Coastguard Worker   mutable Mutex mutex_;
109*d9f75844SAndroid Build Coastguard Worker   bool used_layers_[kMaxSimulcastStreams];
110*d9f75844SAndroid Build Coastguard Worker   absl::optional<int> qp_ RTC_GUARDED_BY(mutex_);
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   // Current byte debt to be payed over a number of frames.
113*d9f75844SAndroid Build Coastguard Worker   // The debt is acquired by keyframes overshooting the bitrate target.
114*d9f75844SAndroid Build Coastguard Worker   size_t debt_bytes_;
115*d9f75844SAndroid Build Coastguard Worker };
116*d9f75844SAndroid Build Coastguard Worker 
117*d9f75844SAndroid Build Coastguard Worker class FakeH264Encoder : public FakeEncoder {
118*d9f75844SAndroid Build Coastguard Worker  public:
119*d9f75844SAndroid Build Coastguard Worker   explicit FakeH264Encoder(Clock* clock);
120*d9f75844SAndroid Build Coastguard Worker   virtual ~FakeH264Encoder() = default;
121*d9f75844SAndroid Build Coastguard Worker 
122*d9f75844SAndroid Build Coastguard Worker  private:
123*d9f75844SAndroid Build Coastguard Worker   CodecSpecificInfo EncodeHook(
124*d9f75844SAndroid Build Coastguard Worker       EncodedImage& encoded_image,
125*d9f75844SAndroid Build Coastguard Worker       rtc::scoped_refptr<EncodedImageBuffer> buffer) override;
126*d9f75844SAndroid Build Coastguard Worker 
127*d9f75844SAndroid Build Coastguard Worker   int idr_counter_ RTC_GUARDED_BY(local_mutex_);
128*d9f75844SAndroid Build Coastguard Worker   Mutex local_mutex_;
129*d9f75844SAndroid Build Coastguard Worker };
130*d9f75844SAndroid Build Coastguard Worker 
131*d9f75844SAndroid Build Coastguard Worker class DelayedEncoder : public test::FakeEncoder {
132*d9f75844SAndroid Build Coastguard Worker  public:
133*d9f75844SAndroid Build Coastguard Worker   DelayedEncoder(Clock* clock, int delay_ms);
134*d9f75844SAndroid Build Coastguard Worker   virtual ~DelayedEncoder() = default;
135*d9f75844SAndroid Build Coastguard Worker 
136*d9f75844SAndroid Build Coastguard Worker   void SetDelay(int delay_ms);
137*d9f75844SAndroid Build Coastguard Worker   int32_t Encode(const VideoFrame& input_image,
138*d9f75844SAndroid Build Coastguard Worker                  const std::vector<VideoFrameType>* frame_types) override;
139*d9f75844SAndroid Build Coastguard Worker 
140*d9f75844SAndroid Build Coastguard Worker  private:
141*d9f75844SAndroid Build Coastguard Worker   int delay_ms_ RTC_GUARDED_BY(sequence_checker_);
142*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker_;
143*d9f75844SAndroid Build Coastguard Worker };
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker // This class implements a multi-threaded fake encoder by posting
146*d9f75844SAndroid Build Coastguard Worker // FakeH264Encoder::Encode(.) tasks to `queue1_` and `queue2_`, in an
147*d9f75844SAndroid Build Coastguard Worker // alternating fashion. The class itself does not need to be thread safe,
148*d9f75844SAndroid Build Coastguard Worker // as it is called from the task queue in VideoStreamEncoder.
149*d9f75844SAndroid Build Coastguard Worker class MultithreadedFakeH264Encoder : public test::FakeH264Encoder {
150*d9f75844SAndroid Build Coastguard Worker  public:
151*d9f75844SAndroid Build Coastguard Worker   MultithreadedFakeH264Encoder(Clock* clock,
152*d9f75844SAndroid Build Coastguard Worker                                TaskQueueFactory* task_queue_factory);
153*d9f75844SAndroid Build Coastguard Worker   virtual ~MultithreadedFakeH264Encoder() = default;
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker   int32_t InitEncode(const VideoCodec* config,
156*d9f75844SAndroid Build Coastguard Worker                      const Settings& settings) override;
157*d9f75844SAndroid Build Coastguard Worker 
158*d9f75844SAndroid Build Coastguard Worker   int32_t Encode(const VideoFrame& input_image,
159*d9f75844SAndroid Build Coastguard Worker                  const std::vector<VideoFrameType>* frame_types) override;
160*d9f75844SAndroid Build Coastguard Worker 
161*d9f75844SAndroid Build Coastguard Worker   int32_t EncodeCallback(const VideoFrame& input_image,
162*d9f75844SAndroid Build Coastguard Worker                          const std::vector<VideoFrameType>* frame_types);
163*d9f75844SAndroid Build Coastguard Worker 
164*d9f75844SAndroid Build Coastguard Worker   int32_t Release() override;
165*d9f75844SAndroid Build Coastguard Worker 
166*d9f75844SAndroid Build Coastguard Worker  protected:
167*d9f75844SAndroid Build Coastguard Worker   TaskQueueFactory* const task_queue_factory_;
168*d9f75844SAndroid Build Coastguard Worker   int current_queue_ RTC_GUARDED_BY(sequence_checker_);
169*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue1_
170*d9f75844SAndroid Build Coastguard Worker       RTC_GUARDED_BY(sequence_checker_);
171*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue2_
172*d9f75844SAndroid Build Coastguard Worker       RTC_GUARDED_BY(sequence_checker_);
173*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker_;
174*d9f75844SAndroid Build Coastguard Worker };
175*d9f75844SAndroid Build Coastguard Worker 
176*d9f75844SAndroid Build Coastguard Worker }  // namespace test
177*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
178*d9f75844SAndroid Build Coastguard Worker 
179*d9f75844SAndroid Build Coastguard Worker #endif  // TEST_FAKE_ENCODER_H_
180