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