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