1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2014 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 12*d9f75844SAndroid Build Coastguard Worker #ifndef MEDIA_ENGINE_SIMULCAST_ENCODER_ADAPTER_H_ 13*d9f75844SAndroid Build Coastguard Worker #define MEDIA_ENGINE_SIMULCAST_ENCODER_ADAPTER_H_ 14*d9f75844SAndroid Build Coastguard Worker 15*d9f75844SAndroid Build Coastguard Worker #include <atomic> 16*d9f75844SAndroid Build Coastguard Worker #include <list> 17*d9f75844SAndroid Build Coastguard Worker #include <memory> 18*d9f75844SAndroid Build Coastguard Worker #include <stack> 19*d9f75844SAndroid Build Coastguard Worker #include <string> 20*d9f75844SAndroid Build Coastguard Worker #include <utility> 21*d9f75844SAndroid Build Coastguard Worker #include <vector> 22*d9f75844SAndroid Build Coastguard Worker 23*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 24*d9f75844SAndroid Build Coastguard Worker #include "api/fec_controller_override.h" 25*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 26*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/sdp_video_format.h" 27*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_encoder.h" 28*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_encoder_factory.h" 29*d9f75844SAndroid Build Coastguard Worker #include "common_video/framerate_controller.h" 30*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/include/video_codec_interface.h" 31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/experiments/encoder_info_settings.h" 32*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h" 33*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 36*d9f75844SAndroid Build Coastguard Worker 37*d9f75844SAndroid Build Coastguard Worker // SimulcastEncoderAdapter implements simulcast support by creating multiple 38*d9f75844SAndroid Build Coastguard Worker // webrtc::VideoEncoder instances with the given VideoEncoderFactory. 39*d9f75844SAndroid Build Coastguard Worker // The object is created and destroyed on the worker thread, but all public 40*d9f75844SAndroid Build Coastguard Worker // interfaces should be called from the encoder task queue. 41*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder { 42*d9f75844SAndroid Build Coastguard Worker public: 43*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11000): Remove when downstream usage is gone. 44*d9f75844SAndroid Build Coastguard Worker SimulcastEncoderAdapter(VideoEncoderFactory* primarty_factory, 45*d9f75844SAndroid Build Coastguard Worker const SdpVideoFormat& format); 46*d9f75844SAndroid Build Coastguard Worker // `primary_factory` produces the first-choice encoders to use. 47*d9f75844SAndroid Build Coastguard Worker // `fallback_factory`, if non-null, is used to create fallback encoder that 48*d9f75844SAndroid Build Coastguard Worker // will be used if InitEncode() fails for the primary encoder. 49*d9f75844SAndroid Build Coastguard Worker SimulcastEncoderAdapter(VideoEncoderFactory* primary_factory, 50*d9f75844SAndroid Build Coastguard Worker VideoEncoderFactory* fallback_factory, 51*d9f75844SAndroid Build Coastguard Worker const SdpVideoFormat& format); 52*d9f75844SAndroid Build Coastguard Worker ~SimulcastEncoderAdapter() override; 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker // Implements VideoEncoder. 55*d9f75844SAndroid Build Coastguard Worker void SetFecControllerOverride( 56*d9f75844SAndroid Build Coastguard Worker FecControllerOverride* fec_controller_override) override; 57*d9f75844SAndroid Build Coastguard Worker int Release() override; 58*d9f75844SAndroid Build Coastguard Worker int InitEncode(const VideoCodec* codec_settings, 59*d9f75844SAndroid Build Coastguard Worker const VideoEncoder::Settings& settings) override; 60*d9f75844SAndroid Build Coastguard Worker int Encode(const VideoFrame& input_image, 61*d9f75844SAndroid Build Coastguard Worker const std::vector<VideoFrameType>* frame_types) override; 62*d9f75844SAndroid Build Coastguard Worker int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; 63*d9f75844SAndroid Build Coastguard Worker void SetRates(const RateControlParameters& parameters) override; 64*d9f75844SAndroid Build Coastguard Worker void OnPacketLossRateUpdate(float packet_loss_rate) override; 65*d9f75844SAndroid Build Coastguard Worker void OnRttUpdate(int64_t rtt_ms) override; 66*d9f75844SAndroid Build Coastguard Worker void OnLossNotification(const LossNotification& loss_notification) override; 67*d9f75844SAndroid Build Coastguard Worker 68*d9f75844SAndroid Build Coastguard Worker EncoderInfo GetEncoderInfo() const override; 69*d9f75844SAndroid Build Coastguard Worker 70*d9f75844SAndroid Build Coastguard Worker private: 71*d9f75844SAndroid Build Coastguard Worker class EncoderContext { 72*d9f75844SAndroid Build Coastguard Worker public: 73*d9f75844SAndroid Build Coastguard Worker EncoderContext(std::unique_ptr<VideoEncoder> encoder, 74*d9f75844SAndroid Build Coastguard Worker bool prefer_temporal_support, 75*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo primary_info, 76*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo fallback_info); 77*d9f75844SAndroid Build Coastguard Worker EncoderContext& operator=(EncoderContext&&) = delete; 78*d9f75844SAndroid Build Coastguard Worker encoder()79*d9f75844SAndroid Build Coastguard Worker VideoEncoder& encoder() { return *encoder_; } prefer_temporal_support()80*d9f75844SAndroid Build Coastguard Worker bool prefer_temporal_support() { return prefer_temporal_support_; } 81*d9f75844SAndroid Build Coastguard Worker void Release(); 82*d9f75844SAndroid Build Coastguard Worker PrimaryInfo()83*d9f75844SAndroid Build Coastguard Worker const VideoEncoder::EncoderInfo& PrimaryInfo() { return primary_info_; } 84*d9f75844SAndroid Build Coastguard Worker FallbackInfo()85*d9f75844SAndroid Build Coastguard Worker const VideoEncoder::EncoderInfo& FallbackInfo() { return fallback_info_; } 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker private: 88*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<VideoEncoder> encoder_; 89*d9f75844SAndroid Build Coastguard Worker bool prefer_temporal_support_; 90*d9f75844SAndroid Build Coastguard Worker const VideoEncoder::EncoderInfo primary_info_; 91*d9f75844SAndroid Build Coastguard Worker const VideoEncoder::EncoderInfo fallback_info_; 92*d9f75844SAndroid Build Coastguard Worker }; 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker class StreamContext : public EncodedImageCallback { 95*d9f75844SAndroid Build Coastguard Worker public: 96*d9f75844SAndroid Build Coastguard Worker StreamContext(SimulcastEncoderAdapter* parent, 97*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<EncoderContext> encoder_context, 98*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FramerateController> framerate_controller, 99*d9f75844SAndroid Build Coastguard Worker int stream_idx, 100*d9f75844SAndroid Build Coastguard Worker uint16_t width, 101*d9f75844SAndroid Build Coastguard Worker uint16_t height, 102*d9f75844SAndroid Build Coastguard Worker bool send_stream); 103*d9f75844SAndroid Build Coastguard Worker StreamContext(StreamContext&& rhs); 104*d9f75844SAndroid Build Coastguard Worker StreamContext& operator=(StreamContext&&) = delete; 105*d9f75844SAndroid Build Coastguard Worker ~StreamContext() override; 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker Result OnEncodedImage( 108*d9f75844SAndroid Build Coastguard Worker const EncodedImage& encoded_image, 109*d9f75844SAndroid Build Coastguard Worker const CodecSpecificInfo* codec_specific_info) override; 110*d9f75844SAndroid Build Coastguard Worker void OnDroppedFrame(DropReason reason) override; 111*d9f75844SAndroid Build Coastguard Worker encoder()112*d9f75844SAndroid Build Coastguard Worker VideoEncoder& encoder() { return encoder_context_->encoder(); } encoder()113*d9f75844SAndroid Build Coastguard Worker const VideoEncoder& encoder() const { return encoder_context_->encoder(); } stream_idx()114*d9f75844SAndroid Build Coastguard Worker int stream_idx() const { return stream_idx_; } width()115*d9f75844SAndroid Build Coastguard Worker uint16_t width() const { return width_; } height()116*d9f75844SAndroid Build Coastguard Worker uint16_t height() const { return height_; } is_keyframe_needed()117*d9f75844SAndroid Build Coastguard Worker bool is_keyframe_needed() const { 118*d9f75844SAndroid Build Coastguard Worker return !is_paused_ && is_keyframe_needed_; 119*d9f75844SAndroid Build Coastguard Worker } set_is_keyframe_needed()120*d9f75844SAndroid Build Coastguard Worker void set_is_keyframe_needed() { is_keyframe_needed_ = true; } is_paused()121*d9f75844SAndroid Build Coastguard Worker bool is_paused() const { return is_paused_; } set_is_paused(bool is_paused)122*d9f75844SAndroid Build Coastguard Worker void set_is_paused(bool is_paused) { is_paused_ = is_paused; } target_fps()123*d9f75844SAndroid Build Coastguard Worker absl::optional<double> target_fps() const { 124*d9f75844SAndroid Build Coastguard Worker return framerate_controller_ == nullptr 125*d9f75844SAndroid Build Coastguard Worker ? absl::nullopt 126*d9f75844SAndroid Build Coastguard Worker : absl::optional<double>( 127*d9f75844SAndroid Build Coastguard Worker framerate_controller_->GetMaxFramerate()); 128*d9f75844SAndroid Build Coastguard Worker } 129*d9f75844SAndroid Build Coastguard Worker 130*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<EncoderContext> ReleaseEncoderContext() &&; 131*d9f75844SAndroid Build Coastguard Worker void OnKeyframe(Timestamp timestamp); 132*d9f75844SAndroid Build Coastguard Worker bool ShouldDropFrame(Timestamp timestamp); 133*d9f75844SAndroid Build Coastguard Worker 134*d9f75844SAndroid Build Coastguard Worker private: 135*d9f75844SAndroid Build Coastguard Worker SimulcastEncoderAdapter* const parent_; 136*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<EncoderContext> encoder_context_; 137*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FramerateController> framerate_controller_; 138*d9f75844SAndroid Build Coastguard Worker const int stream_idx_; 139*d9f75844SAndroid Build Coastguard Worker const uint16_t width_; 140*d9f75844SAndroid Build Coastguard Worker const uint16_t height_; 141*d9f75844SAndroid Build Coastguard Worker bool is_keyframe_needed_; 142*d9f75844SAndroid Build Coastguard Worker bool is_paused_; 143*d9f75844SAndroid Build Coastguard Worker }; 144*d9f75844SAndroid Build Coastguard Worker 145*d9f75844SAndroid Build Coastguard Worker bool Initialized() const; 146*d9f75844SAndroid Build Coastguard Worker 147*d9f75844SAndroid Build Coastguard Worker void DestroyStoredEncoders(); 148*d9f75844SAndroid Build Coastguard Worker 149*d9f75844SAndroid Build Coastguard Worker // This method creates encoder. May reuse previously created encoders from 150*d9f75844SAndroid Build Coastguard Worker // `cached_encoder_contexts_`. It's const because it's used from 151*d9f75844SAndroid Build Coastguard Worker // const GetEncoderInfo(). 152*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<EncoderContext> FetchOrCreateEncoderContext( 153*d9f75844SAndroid Build Coastguard Worker bool is_lowest_quality_stream) const; 154*d9f75844SAndroid Build Coastguard Worker 155*d9f75844SAndroid Build Coastguard Worker webrtc::VideoCodec MakeStreamCodec(const webrtc::VideoCodec& codec, 156*d9f75844SAndroid Build Coastguard Worker int stream_idx, 157*d9f75844SAndroid Build Coastguard Worker uint32_t start_bitrate_kbps, 158*d9f75844SAndroid Build Coastguard Worker bool is_lowest_quality_stream, 159*d9f75844SAndroid Build Coastguard Worker bool is_highest_quality_stream); 160*d9f75844SAndroid Build Coastguard Worker 161*d9f75844SAndroid Build Coastguard Worker EncodedImageCallback::Result OnEncodedImage( 162*d9f75844SAndroid Build Coastguard Worker size_t stream_idx, 163*d9f75844SAndroid Build Coastguard Worker const EncodedImage& encoded_image, 164*d9f75844SAndroid Build Coastguard Worker const CodecSpecificInfo* codec_specific_info); 165*d9f75844SAndroid Build Coastguard Worker 166*d9f75844SAndroid Build Coastguard Worker void OnDroppedFrame(size_t stream_idx); 167*d9f75844SAndroid Build Coastguard Worker 168*d9f75844SAndroid Build Coastguard Worker void OverrideFromFieldTrial(VideoEncoder::EncoderInfo* info) const; 169*d9f75844SAndroid Build Coastguard Worker 170*d9f75844SAndroid Build Coastguard Worker std::atomic<int> inited_; 171*d9f75844SAndroid Build Coastguard Worker VideoEncoderFactory* const primary_encoder_factory_; 172*d9f75844SAndroid Build Coastguard Worker VideoEncoderFactory* const fallback_encoder_factory_; 173*d9f75844SAndroid Build Coastguard Worker const SdpVideoFormat video_format_; 174*d9f75844SAndroid Build Coastguard Worker VideoCodec codec_; 175*d9f75844SAndroid Build Coastguard Worker int total_streams_count_; 176*d9f75844SAndroid Build Coastguard Worker bool bypass_mode_; 177*d9f75844SAndroid Build Coastguard Worker std::vector<StreamContext> stream_contexts_; 178*d9f75844SAndroid Build Coastguard Worker EncodedImageCallback* encoded_complete_callback_; 179*d9f75844SAndroid Build Coastguard Worker 180*d9f75844SAndroid Build Coastguard Worker // Used for checking the single-threaded access of the encoder interface. 181*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker encoder_queue_; 182*d9f75844SAndroid Build Coastguard Worker 183*d9f75844SAndroid Build Coastguard Worker // Store previously created and released encoders , so they don't have to be 184*d9f75844SAndroid Build Coastguard Worker // recreated. Remaining encoders are destroyed by the destructor. 185*d9f75844SAndroid Build Coastguard Worker // Marked as `mutable` becuase we may need to temporarily create encoder in 186*d9f75844SAndroid Build Coastguard Worker // GetEncoderInfo(), which is const. 187*d9f75844SAndroid Build Coastguard Worker mutable std::list<std::unique_ptr<EncoderContext>> cached_encoder_contexts_; 188*d9f75844SAndroid Build Coastguard Worker 189*d9f75844SAndroid Build Coastguard Worker const absl::optional<unsigned int> experimental_boosted_screenshare_qp_; 190*d9f75844SAndroid Build Coastguard Worker const bool boost_base_layer_quality_; 191*d9f75844SAndroid Build Coastguard Worker const bool prefer_temporal_support_on_base_layer_; 192*d9f75844SAndroid Build Coastguard Worker 193*d9f75844SAndroid Build Coastguard Worker const SimulcastEncoderAdapterEncoderInfoSettings encoder_info_override_; 194*d9f75844SAndroid Build Coastguard Worker }; 195*d9f75844SAndroid Build Coastguard Worker 196*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 197*d9f75844SAndroid Build Coastguard Worker 198*d9f75844SAndroid Build Coastguard Worker #endif // MEDIA_ENGINE_SIMULCAST_ENCODER_ADAPTER_H_ 199