blob: ffd672a63ecb9119cbde526491c3f92e7b14bde1 [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>
brandtr49ce67c2017-02-11 00:25:18 -080016#include <memory>
Yves Gerey665174f2018-06-19 15:03:05 +020017#include <vector>
stefan@webrtc.org360e3762013-08-22 09:29:56 +000018
Yves Gerey3e707812018-11-28 16:47:49 +010019#include "api/video/encoded_image.h"
20#include "api/video/video_bitrate_allocation.h"
21#include "api/video/video_frame.h"
22#include "api/video_codecs/video_codec.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "api/video_codecs/video_encoder.h"
Yves Gerey3e707812018-11-28 16:47:49 +010024#include "common_types.h" // NOLINT(build/include)
25#include "modules/include/module_common_types.h"
26#include "modules/video_coding/include/video_codec_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/critical_section.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "rtc_base/sequenced_task_checker.h"
29#include "rtc_base/task_queue.h"
Yves Gerey3e707812018-11-28 16:47:49 +010030#include "rtc_base/thread_annotations.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "system_wrappers/include/clock.h"
stefan@webrtc.org360e3762013-08-22 09:29:56 +000032
33namespace webrtc {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000034namespace test {
stefan@webrtc.org360e3762013-08-22 09:29:56 +000035
36class FakeEncoder : public VideoEncoder {
37 public:
38 explicit FakeEncoder(Clock* clock);
brandtr49ce67c2017-02-11 00:25:18 -080039 virtual ~FakeEncoder() = default;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000040
pbos@webrtc.org3349ae02014-03-13 12:52:27 +000041 // Sets max bitrate. Not thread-safe, call before registering the encoder.
42 void SetMaxBitrate(int max_kbps);
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000043
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000044 int32_t InitEncode(const VideoCodec* config,
45 int32_t number_of_cores,
46 size_t max_payload_size) override;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070047 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000048 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -070049 const std::vector<FrameType>* frame_types) override;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000050 int32_t RegisterEncodeCompleteCallback(
51 EncodedImageCallback* callback) override;
52 int32_t Release() override;
Erik Språng566124a2018-04-23 12:32:22 +020053 int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
Erik Språng08127a92016-11-16 16:41:30 +010054 uint32_t framerate) override;
sprang4847ae62017-06-27 07:06:52 -070055 int GetConfiguredInputFramerate() const;
Erik Språngdf351f42018-11-06 11:33:15 +010056 EncoderInfo GetEncoderInfo() const override;
Peter Boströmb7d9a972015-12-18 16:01:11 +010057
58 static const char* kImplementationName;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000059
pbos@webrtc.org273a4142014-12-01 15:23:21 +000060 protected:
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020061 struct FrameInfo {
62 bool keyframe;
63 struct SpatialLayer {
64 SpatialLayer() = default;
65 SpatialLayer(int size, int temporal_id)
66 : size(size), temporal_id(temporal_id) {}
67 // Size of a current frame in the layer.
68 int size = 0;
69 // Temporal index of a current frame in the layer.
70 int temporal_id = 0;
71 };
72 std::vector<SpatialLayer> layers;
73 };
74
75 FrameInfo NextFrame(const std::vector<FrameType>* frame_types,
76 bool keyframe,
77 uint8_t num_simulcast_streams,
78 const VideoBitrateAllocation& target_bitrate,
79 SimulcastStream simulcast_streams[kMaxSimulcastStreams],
80 int framerate);
81
Niels Möllerd7380712019-03-06 10:09:47 +010082 // Called before the frame is passed to callback_->OnEncodedImage, to let
83 // subclasses fill out codec_specific, possibly modify encodedImage.
84 // Returns an RTPFragmentationHeader, if needed by the codec.
85 virtual std::unique_ptr<RTPFragmentationHeader> EncodeHook(
86 EncodedImage* encoded_image,
87 CodecSpecificInfo* codec_specific);
88
Yves Gerey04140402018-10-08 11:39:18 +020089 FrameInfo last_frame_info_ RTC_GUARDED_BY(crit_sect_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000090 Clock* const clock_;
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020091
danilchapa37de392017-09-09 04:17:22 -070092 VideoCodec config_ RTC_GUARDED_BY(crit_sect_);
93 EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_);
Erik Språng566124a2018-04-23 12:32:22 +020094 VideoBitrateAllocation target_bitrate_ RTC_GUARDED_BY(crit_sect_);
danilchapa37de392017-09-09 04:17:22 -070095 int configured_input_framerate_ RTC_GUARDED_BY(crit_sect_);
96 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,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000128 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -0700129 const std::vector<FrameType>* frame_types) override;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000130
131 private:
Niels Möller1e062892018-02-07 10:18:32 +0100132 int delay_ms_ RTC_GUARDED_BY(sequence_checker_);
brandtr49ce67c2017-02-11 00:25:18 -0800133 rtc::SequencedTaskChecker sequence_checker_;
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000134};
brandtr696c9c62016-12-19 05:47:28 -0800135
136// This class implements a multi-threaded fake encoder by posting
137// FakeH264Encoder::Encode(.) tasks to |queue1_| and |queue2_|, in an
brandtr49ce67c2017-02-11 00:25:18 -0800138// alternating fashion. The class itself does not need to be thread safe,
mflodmancc3d4422017-08-03 08:27:51 -0700139// as it is called from the task queue in VideoStreamEncoder.
brandtre78d2662017-01-16 05:57:16 -0800140class MultithreadedFakeH264Encoder : public test::FakeH264Encoder {
brandtr696c9c62016-12-19 05:47:28 -0800141 public:
brandtre78d2662017-01-16 05:57:16 -0800142 explicit MultithreadedFakeH264Encoder(Clock* clock);
brandtr49ce67c2017-02-11 00:25:18 -0800143 virtual ~MultithreadedFakeH264Encoder() = default;
144
145 int32_t InitEncode(const VideoCodec* config,
146 int32_t number_of_cores,
147 size_t max_payload_size) override;
brandtr696c9c62016-12-19 05:47:28 -0800148
149 int32_t Encode(const VideoFrame& input_image,
150 const CodecSpecificInfo* codec_specific_info,
151 const std::vector<FrameType>* frame_types) override;
152
153 int32_t EncodeCallback(const VideoFrame& input_image,
154 const CodecSpecificInfo* codec_specific_info,
155 const std::vector<FrameType>* frame_types);
156
brandtr49ce67c2017-02-11 00:25:18 -0800157 int32_t Release() override;
158
brandtr696c9c62016-12-19 05:47:28 -0800159 protected:
160 class EncodeTask;
161
Niels Möller1e062892018-02-07 10:18:32 +0100162 int current_queue_ RTC_GUARDED_BY(sequence_checker_);
163 std::unique_ptr<rtc::TaskQueue> queue1_ RTC_GUARDED_BY(sequence_checker_);
164 std::unique_ptr<rtc::TaskQueue> queue2_ RTC_GUARDED_BY(sequence_checker_);
brandtr49ce67c2017-02-11 00:25:18 -0800165 rtc::SequencedTaskChecker 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_