| /* 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 MODULES_VIDEO_CODING_CODECS_VP8_SCREENSHARE_LAYERS_H_ |
| #define MODULES_VIDEO_CODING_CODECS_VP8_SCREENSHARE_LAYERS_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "api/video_codecs/vp8_frame_config.h" |
| #include "api/video_codecs/vp8_temporal_layers.h" |
| #include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h" |
| #include "modules/video_coding/include/video_codec_interface.h" |
| #include "modules/video_coding/utility/frame_dropper.h" |
| #include "rtc_base/rate_statistics.h" |
| #include "rtc_base/time_utils.h" |
| |
| namespace webrtc { |
| |
| struct CodecSpecificInfoVP8; |
| class Clock; |
| |
| class ScreenshareLayers final : public Vp8FrameBufferController { |
| public: |
| static const double kMaxTL0FpsReduction; |
| static const double kAcceptableTargetOvershoot; |
| static const int kMaxFrameIntervalMs; |
| |
| explicit ScreenshareLayers(int num_temporal_layers); |
| ~ScreenshareLayers() override; |
| |
| void SetQpLimits(size_t stream_index, int min_qp, int max_qp) override; |
| |
| size_t StreamCount() const override; |
| |
| bool SupportsEncoderFrameDropping(size_t stream_index) const override; |
| |
| // Returns the recommended VP8 encode flags needed. May refresh the decoder |
| // and/or update the reference buffers. |
| Vp8FrameConfig NextFrameConfig(size_t stream_index, |
| uint32_t rtp_timestamp) override; |
| |
| // New target bitrate, per temporal layer. |
| void OnRatesUpdated(size_t stream_index, |
| const std::vector<uint32_t>& bitrates_bps, |
| int framerate_fps) override; |
| |
| Vp8EncoderConfig UpdateConfiguration(size_t stream_index) override; |
| |
| void OnEncodeDone(size_t stream_index, |
| uint32_t rtp_timestamp, |
| size_t size_bytes, |
| bool is_keyframe, |
| int qp, |
| CodecSpecificInfo* info) override; |
| |
| void OnFrameDropped(size_t stream_index, uint32_t rtp_timestamp) override; |
| |
| void OnPacketLossRateUpdate(float packet_loss_rate) override; |
| |
| void OnRttUpdate(int64_t rtt_ms) override; |
| |
| void OnLossNotification( |
| const VideoEncoder::LossNotification& loss_notification) override; |
| |
| private: |
| enum class TemporalLayerState : int { kDrop, kTl0, kTl1, kTl1Sync }; |
| |
| struct DependencyInfo { |
| DependencyInfo() = default; |
| DependencyInfo(absl::string_view indication_symbols, |
| Vp8FrameConfig frame_config) |
| : decode_target_indications( |
| webrtc_impl::StringToDecodeTargetIndications(indication_symbols)), |
| frame_config(frame_config) {} |
| |
| absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications; |
| Vp8FrameConfig frame_config; |
| }; |
| |
| bool TimeToSync(int64_t timestamp) const; |
| uint32_t GetCodecTargetBitrateKbps() const; |
| |
| const int number_of_temporal_layers_; |
| |
| // TODO(eladalon/sprang): These should be made into const-int set in the ctor. |
| absl::optional<int> min_qp_; |
| absl::optional<int> max_qp_; |
| |
| int active_layer_; |
| int64_t last_timestamp_; |
| int64_t last_sync_timestamp_; |
| int64_t last_emitted_tl0_timestamp_; |
| int64_t last_frame_time_ms_; |
| rtc::TimestampWrapAroundHandler time_wrap_handler_; |
| uint32_t max_debt_bytes_; |
| |
| std::map<uint32_t, DependencyInfo> pending_frame_configs_; |
| |
| // Configured max framerate. |
| absl::optional<uint32_t> target_framerate_; |
| // Incoming framerate from capturer. |
| absl::optional<uint32_t> capture_framerate_; |
| |
| // Tracks what framerate we actually encode, and drops frames on overshoot. |
| RateStatistics encode_framerate_; |
| bool bitrate_updated_; |
| |
| static constexpr int kMaxNumTemporalLayers = 2; |
| struct TemporalLayer { |
| TemporalLayer() |
| : state(State::kNormal), |
| enhanced_max_qp(-1), |
| last_qp(-1), |
| debt_bytes_(0), |
| target_rate_kbps_(0) {} |
| |
| enum class State { |
| kNormal, |
| kDropped, |
| kReencoded, |
| kQualityBoost, |
| kKeyFrame |
| } state; |
| |
| int enhanced_max_qp; |
| int last_qp; |
| uint32_t debt_bytes_; |
| uint32_t target_rate_kbps_; |
| |
| void UpdateDebt(int64_t delta_ms); |
| } layers_[kMaxNumTemporalLayers]; |
| |
| void UpdateHistograms(); |
| FrameDependencyStructure GetTemplateStructure(int num_layers) const; |
| |
| // Data for histogram statistics. |
| struct Stats { |
| int64_t first_frame_time_ms_ = -1; |
| int64_t num_tl0_frames_ = 0; |
| int64_t num_tl1_frames_ = 0; |
| int64_t num_dropped_frames_ = 0; |
| int64_t num_overshoots_ = 0; |
| int64_t tl0_qp_sum_ = 0; |
| int64_t tl1_qp_sum_ = 0; |
| int64_t tl0_target_bitrate_sum_ = 0; |
| int64_t tl1_target_bitrate_sum_ = 0; |
| } stats_; |
| |
| Vp8EncoderConfig encoder_config_; |
| |
| // Optional utility used to verify reference validity. |
| std::unique_ptr<TemporalLayersChecker> checker_; |
| }; |
| } // namespace webrtc |
| |
| #endif // MODULES_VIDEO_CODING_CODECS_VP8_SCREENSHARE_LAYERS_H_ |