blob: 39838d16f146f4f83a1201cfd2384c81e760b37f [file] [log] [blame]
stefan@webrtc.org360e3762013-08-22 09:29:56 +00001/*
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 Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef TEST_FAKE_ENCODER_H_
12#define TEST_FAKE_ENCODER_H_
stefan@webrtc.org360e3762013-08-22 09:29:56 +000013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
brandtr49ce67c2017-02-11 00:25:18 -080017#include <memory>
Yves Gerey665174f2018-06-19 15:03:05 +020018#include <vector>
stefan@webrtc.org360e3762013-08-22 09:29:56 +000019
Elad Alon8f01c4e2019-06-28 15:19:43 +020020#include "api/fec_controller_override.h"
Danil Chapovalov22ed3662019-03-19 19:39:49 +010021#include "api/task_queue/task_queue_factory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "api/video/encoded_image.h"
23#include "api/video/video_bitrate_allocation.h"
24#include "api/video/video_frame.h"
25#include "api/video_codecs/video_codec.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "api/video_codecs/video_encoder.h"
Yves Gerey3e707812018-11-28 16:47:49 +010027#include "modules/include/module_common_types.h"
28#include "modules/video_coding/include/video_codec_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/critical_section.h"
Sebastian Janssonb55015e2019-04-09 13:44:04 +020030#include "rtc_base/synchronization/sequence_checker.h"
Yves Gerey3e707812018-11-28 16:47:49 +010031#include "rtc_base/thread_annotations.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "system_wrappers/include/clock.h"
stefan@webrtc.org360e3762013-08-22 09:29:56 +000033
34namespace webrtc {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000035namespace test {
stefan@webrtc.org360e3762013-08-22 09:29:56 +000036
37class FakeEncoder : public VideoEncoder {
38 public:
39 explicit FakeEncoder(Clock* clock);
brandtr49ce67c2017-02-11 00:25:18 -080040 virtual ~FakeEncoder() = default;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000041
pbos@webrtc.org3349ae02014-03-13 12:52:27 +000042 // Sets max bitrate. Not thread-safe, call before registering the encoder.
43 void SetMaxBitrate(int max_kbps);
Åsa Perssone644a032019-11-08 15:56:00 +010044 void SetQp(int qp);
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000045
Elad Alon8f01c4e2019-06-28 15:19:43 +020046 void SetFecControllerOverride(
47 FecControllerOverride* fec_controller_override) override;
48
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000049 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +020050 const Settings& settings) override;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070051 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +010052 const std::vector<VideoFrameType>* frame_types) override;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000053 int32_t RegisterEncodeCompleteCallback(
54 EncodedImageCallback* callback) override;
55 int32_t Release() override;
Erik Språng16cb8f52019-04-12 13:59:09 +020056 void SetRates(const RateControlParameters& parameters) override;
sprang4847ae62017-06-27 07:06:52 -070057 int GetConfiguredInputFramerate() const;
Erik Språngdf351f42018-11-06 11:33:15 +010058 EncoderInfo GetEncoderInfo() const override;
Peter Boströmb7d9a972015-12-18 16:01:11 +010059
60 static const char* kImplementationName;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000061
pbos@webrtc.org273a4142014-12-01 15:23:21 +000062 protected:
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020063 struct FrameInfo {
64 bool keyframe;
65 struct SpatialLayer {
66 SpatialLayer() = default;
67 SpatialLayer(int size, int temporal_id)
68 : size(size), temporal_id(temporal_id) {}
69 // Size of a current frame in the layer.
70 int size = 0;
71 // Temporal index of a current frame in the layer.
72 int temporal_id = 0;
73 };
74 std::vector<SpatialLayer> layers;
75 };
76
Niels Möller87e2d782019-03-07 10:18:23 +010077 FrameInfo NextFrame(const std::vector<VideoFrameType>* frame_types,
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020078 bool keyframe,
79 uint8_t num_simulcast_streams,
80 const VideoBitrateAllocation& target_bitrate,
81 SimulcastStream simulcast_streams[kMaxSimulcastStreams],
82 int framerate);
83
Niels Möllerd7380712019-03-06 10:09:47 +010084 // Called before the frame is passed to callback_->OnEncodedImage, to let
85 // subclasses fill out codec_specific, possibly modify encodedImage.
86 // Returns an RTPFragmentationHeader, if needed by the codec.
87 virtual std::unique_ptr<RTPFragmentationHeader> EncodeHook(
88 EncodedImage* encoded_image,
89 CodecSpecificInfo* codec_specific);
90
Yves Gerey04140402018-10-08 11:39:18 +020091 FrameInfo last_frame_info_ RTC_GUARDED_BY(crit_sect_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000092 Clock* const clock_;
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020093
danilchapa37de392017-09-09 04:17:22 -070094 VideoCodec config_ RTC_GUARDED_BY(crit_sect_);
95 EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_);
Erik Språng16cb8f52019-04-12 13:59:09 +020096 RateControlParameters current_rate_settings_ RTC_GUARDED_BY(crit_sect_);
danilchapa37de392017-09-09 04:17:22 -070097 int max_target_bitrate_kbps_ RTC_GUARDED_BY(crit_sect_);
98 bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_);
Per Kjellander17fc7e22018-11-06 11:01:06 +010099 uint32_t counter_ RTC_GUARDED_BY(crit_sect_);
brandtr49ce67c2017-02-11 00:25:18 -0800100 rtc::CriticalSection crit_sect_;
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +0200101 bool used_layers_[kMaxSimulcastStreams];
Åsa Perssone644a032019-11-08 15:56:00 +0100102 absl::optional<int> qp_ RTC_GUARDED_BY(crit_sect_);
sprang4847ae62017-06-27 07:06:52 -0700103
104 // Current byte debt to be payed over a number of frames.
105 // The debt is acquired by keyframes overshooting the bitrate target.
106 size_t debt_bytes_;
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000107};
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000108
Niels Möllerd7380712019-03-06 10:09:47 +0100109class FakeH264Encoder : public FakeEncoder {
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000110 public:
111 explicit FakeH264Encoder(Clock* clock);
brandtr49ce67c2017-02-11 00:25:18 -0800112 virtual ~FakeH264Encoder() = default;
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000113
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000114 private:
Niels Möllerd7380712019-03-06 10:09:47 +0100115 std::unique_ptr<RTPFragmentationHeader> EncodeHook(
116 EncodedImage* encoded_image,
117 CodecSpecificInfo* codec_specific) override;
118
danilchapa37de392017-09-09 04:17:22 -0700119 int idr_counter_ RTC_GUARDED_BY(local_crit_sect_);
brandtr49ce67c2017-02-11 00:25:18 -0800120 rtc::CriticalSection local_crit_sect_;
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000121};
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000122
123class DelayedEncoder : public test::FakeEncoder {
124 public:
125 DelayedEncoder(Clock* clock, int delay_ms);
brandtr49ce67c2017-02-11 00:25:18 -0800126 virtual ~DelayedEncoder() = default;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000127
perkj803d97f2016-11-01 11:45:46 -0700128 void SetDelay(int delay_ms);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700129 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +0100130 const std::vector<VideoFrameType>* frame_types) override;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000131
132 private:
Niels Möller1e062892018-02-07 10:18:32 +0100133 int delay_ms_ RTC_GUARDED_BY(sequence_checker_);
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200134 SequenceChecker sequence_checker_;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000135};
brandtr696c9c62016-12-19 05:47:28 -0800136
137// This class implements a multi-threaded fake encoder by posting
138// FakeH264Encoder::Encode(.) tasks to |queue1_| and |queue2_|, in an
brandtr49ce67c2017-02-11 00:25:18 -0800139// alternating fashion. The class itself does not need to be thread safe,
mflodmancc3d4422017-08-03 08:27:51 -0700140// as it is called from the task queue in VideoStreamEncoder.
brandtre78d2662017-01-16 05:57:16 -0800141class MultithreadedFakeH264Encoder : public test::FakeH264Encoder {
brandtr696c9c62016-12-19 05:47:28 -0800142 public:
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100143 MultithreadedFakeH264Encoder(Clock* clock,
144 TaskQueueFactory* task_queue_factory);
brandtr49ce67c2017-02-11 00:25:18 -0800145 virtual ~MultithreadedFakeH264Encoder() = default;
146
147 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +0200148 const Settings& settings) override;
brandtr696c9c62016-12-19 05:47:28 -0800149
150 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +0100151 const std::vector<VideoFrameType>* frame_types) override;
brandtr696c9c62016-12-19 05:47:28 -0800152
153 int32_t EncodeCallback(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +0100154 const std::vector<VideoFrameType>* frame_types);
brandtr696c9c62016-12-19 05:47:28 -0800155
brandtr49ce67c2017-02-11 00:25:18 -0800156 int32_t Release() override;
157
brandtr696c9c62016-12-19 05:47:28 -0800158 protected:
159 class EncodeTask;
160
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100161 TaskQueueFactory* const task_queue_factory_;
Niels Möller1e062892018-02-07 10:18:32 +0100162 int current_queue_ RTC_GUARDED_BY(sequence_checker_);
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100163 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue1_
164 RTC_GUARDED_BY(sequence_checker_);
165 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue2_
166 RTC_GUARDED_BY(sequence_checker_);
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200167 SequenceChecker sequence_checker_;
brandtr696c9c62016-12-19 05:47:28 -0800168};
169
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000170} // namespace test
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000171} // namespace webrtc
172
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200173#endif // TEST_FAKE_ENCODER_H_