blob: 566980e329cb83804839d4f580f580f7f0c2f887 [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);
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000044
Elad Alon8f01c4e2019-06-28 15:19:43 +020045 void SetFecControllerOverride(
46 FecControllerOverride* fec_controller_override) override;
47
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000048 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +020049 const Settings& settings) override;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070050 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +010051 const std::vector<VideoFrameType>* frame_types) override;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000052 int32_t RegisterEncodeCompleteCallback(
53 EncodedImageCallback* callback) override;
54 int32_t Release() override;
Erik Språng16cb8f52019-04-12 13:59:09 +020055 void SetRates(const RateControlParameters& parameters) override;
sprang4847ae62017-06-27 07:06:52 -070056 int GetConfiguredInputFramerate() const;
Erik Språngdf351f42018-11-06 11:33:15 +010057 EncoderInfo GetEncoderInfo() const override;
Peter Boströmb7d9a972015-12-18 16:01:11 +010058
59 static const char* kImplementationName;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000060
pbos@webrtc.org273a4142014-12-01 15:23:21 +000061 protected:
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020062 struct FrameInfo {
63 bool keyframe;
64 struct SpatialLayer {
65 SpatialLayer() = default;
66 SpatialLayer(int size, int temporal_id)
67 : size(size), temporal_id(temporal_id) {}
68 // Size of a current frame in the layer.
69 int size = 0;
70 // Temporal index of a current frame in the layer.
71 int temporal_id = 0;
72 };
73 std::vector<SpatialLayer> layers;
74 };
75
Niels Möller87e2d782019-03-07 10:18:23 +010076 FrameInfo NextFrame(const std::vector<VideoFrameType>* frame_types,
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020077 bool keyframe,
78 uint8_t num_simulcast_streams,
79 const VideoBitrateAllocation& target_bitrate,
80 SimulcastStream simulcast_streams[kMaxSimulcastStreams],
81 int framerate);
82
Niels Möllerd7380712019-03-06 10:09:47 +010083 // Called before the frame is passed to callback_->OnEncodedImage, to let
84 // subclasses fill out codec_specific, possibly modify encodedImage.
85 // Returns an RTPFragmentationHeader, if needed by the codec.
86 virtual std::unique_ptr<RTPFragmentationHeader> EncodeHook(
87 EncodedImage* encoded_image,
88 CodecSpecificInfo* codec_specific);
89
Yves Gerey04140402018-10-08 11:39:18 +020090 FrameInfo last_frame_info_ RTC_GUARDED_BY(crit_sect_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000091 Clock* const clock_;
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020092
danilchapa37de392017-09-09 04:17:22 -070093 VideoCodec config_ RTC_GUARDED_BY(crit_sect_);
94 EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_);
Erik Språng16cb8f52019-04-12 13:59:09 +020095 RateControlParameters current_rate_settings_ RTC_GUARDED_BY(crit_sect_);
danilchapa37de392017-09-09 04:17:22 -070096 int max_target_bitrate_kbps_ RTC_GUARDED_BY(crit_sect_);
97 bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_);
Per Kjellander17fc7e22018-11-06 11:01:06 +010098 uint32_t counter_ RTC_GUARDED_BY(crit_sect_);
brandtr49ce67c2017-02-11 00:25:18 -080099 rtc::CriticalSection crit_sect_;
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +0200100 bool used_layers_[kMaxSimulcastStreams];
sprang4847ae62017-06-27 07:06:52 -0700101
102 // Current byte debt to be payed over a number of frames.
103 // The debt is acquired by keyframes overshooting the bitrate target.
104 size_t debt_bytes_;
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000105};
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000106
Niels Möllerd7380712019-03-06 10:09:47 +0100107class FakeH264Encoder : public FakeEncoder {
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000108 public:
109 explicit FakeH264Encoder(Clock* clock);
brandtr49ce67c2017-02-11 00:25:18 -0800110 virtual ~FakeH264Encoder() = default;
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000111
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000112 private:
Niels Möllerd7380712019-03-06 10:09:47 +0100113 std::unique_ptr<RTPFragmentationHeader> EncodeHook(
114 EncodedImage* encoded_image,
115 CodecSpecificInfo* codec_specific) override;
116
danilchapa37de392017-09-09 04:17:22 -0700117 int idr_counter_ RTC_GUARDED_BY(local_crit_sect_);
brandtr49ce67c2017-02-11 00:25:18 -0800118 rtc::CriticalSection local_crit_sect_;
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000119};
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000120
121class DelayedEncoder : public test::FakeEncoder {
122 public:
123 DelayedEncoder(Clock* clock, int delay_ms);
brandtr49ce67c2017-02-11 00:25:18 -0800124 virtual ~DelayedEncoder() = default;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000125
perkj803d97f2016-11-01 11:45:46 -0700126 void SetDelay(int delay_ms);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700127 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +0100128 const std::vector<VideoFrameType>* frame_types) override;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000129
130 private:
Niels Möller1e062892018-02-07 10:18:32 +0100131 int delay_ms_ RTC_GUARDED_BY(sequence_checker_);
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200132 SequenceChecker sequence_checker_;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000133};
brandtr696c9c62016-12-19 05:47:28 -0800134
135// This class implements a multi-threaded fake encoder by posting
136// FakeH264Encoder::Encode(.) tasks to |queue1_| and |queue2_|, in an
brandtr49ce67c2017-02-11 00:25:18 -0800137// alternating fashion. The class itself does not need to be thread safe,
mflodmancc3d4422017-08-03 08:27:51 -0700138// as it is called from the task queue in VideoStreamEncoder.
brandtre78d2662017-01-16 05:57:16 -0800139class MultithreadedFakeH264Encoder : public test::FakeH264Encoder {
brandtr696c9c62016-12-19 05:47:28 -0800140 public:
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100141 MultithreadedFakeH264Encoder(Clock* clock,
142 TaskQueueFactory* task_queue_factory);
brandtr49ce67c2017-02-11 00:25:18 -0800143 virtual ~MultithreadedFakeH264Encoder() = default;
144
145 int32_t InitEncode(const VideoCodec* config,
Elad Alon370f93a2019-06-11 14:57:57 +0200146 const Settings& settings) override;
brandtr696c9c62016-12-19 05:47:28 -0800147
148 int32_t Encode(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +0100149 const std::vector<VideoFrameType>* frame_types) override;
brandtr696c9c62016-12-19 05:47:28 -0800150
151 int32_t EncodeCallback(const VideoFrame& input_image,
Niels Möller87e2d782019-03-07 10:18:23 +0100152 const std::vector<VideoFrameType>* frame_types);
brandtr696c9c62016-12-19 05:47:28 -0800153
brandtr49ce67c2017-02-11 00:25:18 -0800154 int32_t Release() override;
155
brandtr696c9c62016-12-19 05:47:28 -0800156 protected:
157 class EncodeTask;
158
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100159 TaskQueueFactory* const task_queue_factory_;
Niels Möller1e062892018-02-07 10:18:32 +0100160 int current_queue_ RTC_GUARDED_BY(sequence_checker_);
Danil Chapovalov22ed3662019-03-19 19:39:49 +0100161 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue1_
162 RTC_GUARDED_BY(sequence_checker_);
163 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> queue2_
164 RTC_GUARDED_BY(sequence_checker_);
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200165 SequenceChecker sequence_checker_;
brandtr696c9c62016-12-19 05:47:28 -0800166};
167
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000168} // namespace test
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000169} // namespace webrtc
170
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200171#endif // TEST_FAKE_ENCODER_H_