1 /*
2  *  Copyright (c) 2018 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 
11 #ifndef MODULES_VIDEO_CODING_CODECS_VP8_LIBVPX_VP8_ENCODER_H_
12 #define MODULES_VIDEO_CODING_CODECS_VP8_LIBVPX_VP8_ENCODER_H_
13 
14 #include <memory>
15 #include <string>
16 #include <vector>
17 
18 #include "api/fec_controller_override.h"
19 #include "api/video/encoded_image.h"
20 #include "api/video/video_frame.h"
21 #include "api/video_codecs/video_encoder.h"
22 #include "api/video_codecs/vp8_frame_buffer_controller.h"
23 #include "api/video_codecs/vp8_frame_config.h"
24 #include "modules/video_coding/codecs/vp8/include/vp8.h"
25 #include "modules/video_coding/codecs/vp8/libvpx_interface.h"
26 #include "modules/video_coding/include/video_codec_interface.h"
27 #include "modules/video_coding/utility/framerate_controller.h"
28 #include "rtc_base/experiments/cpu_speed_experiment.h"
29 #include "rtc_base/experiments/rate_control_settings.h"
30 #include "vpx/vp8cx.h"
31 #include "vpx/vpx_encoder.h"
32 
33 namespace webrtc {
34 
35 class LibvpxVp8Encoder : public VideoEncoder {
36  public:
37   LibvpxVp8Encoder(std::unique_ptr<LibvpxInterface> interface,
38                    VP8Encoder::Settings settings);
39   ~LibvpxVp8Encoder() override;
40 
41   int Release() override;
42 
43   void SetFecControllerOverride(
44       FecControllerOverride* fec_controller_override) override;
45 
46   int InitEncode(const VideoCodec* codec_settings,
47                  const VideoEncoder::Settings& settings) override;
48 
49   int Encode(const VideoFrame& input_image,
50              const std::vector<VideoFrameType>* frame_types) override;
51 
52   int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
53 
54   void SetRates(const RateControlParameters& parameters) override;
55 
56   void OnPacketLossRateUpdate(float packet_loss_rate) override;
57 
58   void OnRttUpdate(int64_t rtt_ms) override;
59 
60   void OnLossNotification(const LossNotification& loss_notification) override;
61 
62   EncoderInfo GetEncoderInfo() const override;
63 
64   static vpx_enc_frame_flags_t EncodeFlags(const Vp8FrameConfig& references);
65 
66  private:
67   // Get the cpu_speed setting for encoder based on resolution and/or platform.
68   int GetCpuSpeed(int width, int height);
69 
70   // Determine number of encoder threads to use.
71   int NumberOfThreads(int width, int height, int number_of_cores);
72 
73   // Call encoder initialize function and set control settings.
74   int InitAndSetControlSettings();
75 
76   void PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
77                              const vpx_codec_cx_pkt& pkt,
78                              int stream_idx,
79                              int encoder_idx,
80                              uint32_t timestamp);
81 
82   int GetEncodedPartitions(const VideoFrame& input_image,
83                            bool retransmission_allowed);
84 
85   // Set the stream state for stream |stream_idx|.
86   void SetStreamState(bool send_stream, int stream_idx);
87 
88   uint32_t MaxIntraTarget(uint32_t optimal_buffer_size);
89 
90   uint32_t FrameDropThreshold(size_t spatial_idx) const;
91 
92   size_t SteadyStateSize(int sid, int tid);
93 
94   bool UpdateVpxConfiguration(size_t stream_index);
95 
96   void MaybeUpdatePixelFormat(vpx_img_fmt fmt);
97   void PrepareI420Image(const I420BufferInterface* frame);
98   void PrepareNV12Image(const NV12BufferInterface* frame);
99 
100   const std::unique_ptr<LibvpxInterface> libvpx_;
101 
102   const CpuSpeedExperiment experimental_cpu_speed_config_arm_;
103   const RateControlSettings rate_control_settings_;
104 
105   // EncoderInfo::requested_resolution_alignment override from field trial.
106   const absl::optional<int> requested_resolution_alignment_override_;
107 
108   EncodedImageCallback* encoded_complete_callback_ = nullptr;
109   VideoCodec codec_;
110   bool inited_ = false;
111   int64_t timestamp_ = 0;
112   int qp_max_ = 56;
113   int cpu_speed_default_ = -6;
114   int number_of_cores_ = 0;
115   uint32_t rc_max_intra_target_ = 0;
116   int num_active_streams_ = 0;
117   const std::unique_ptr<Vp8FrameBufferControllerFactory>
118       frame_buffer_controller_factory_;
119   std::unique_ptr<Vp8FrameBufferController> frame_buffer_controller_;
120   const std::vector<VideoEncoder::ResolutionBitrateLimits>
121       resolution_bitrate_limits_;
122   std::vector<bool> key_frame_request_;
123   std::vector<bool> send_stream_;
124   std::vector<int> cpu_speed_;
125   std::vector<vpx_image_t> raw_images_;
126   std::vector<EncodedImage> encoded_images_;
127   std::vector<vpx_codec_ctx_t> encoders_;
128   std::vector<vpx_codec_enc_cfg_t> vpx_configs_;
129   std::vector<Vp8EncoderConfig> config_overrides_;
130   std::vector<vpx_rational_t> downsampling_factors_;
131 
132   // Variable frame-rate screencast related fields and methods.
133   const struct VariableFramerateExperiment {
134     bool enabled = false;
135     // Framerate is limited to this value in steady state.
136     float framerate_limit = 5.0;
137     // This qp or below is considered a steady state.
138     int steady_state_qp = 15;
139     // Frames of at least this percentage below ideal for configured bitrate are
140     // considered in a steady state.
141     int steady_state_undershoot_percentage = 30;
142   } variable_framerate_experiment_;
143   static VariableFramerateExperiment ParseVariableFramerateConfig(
144       std::string group_name);
145   FramerateController framerate_controller_;
146   int num_steady_state_frames_ = 0;
147 
148   FecControllerOverride* fec_controller_override_ = nullptr;
149 };
150 
151 }  // namespace webrtc
152 
153 #endif  // MODULES_VIDEO_CODING_CODECS_VP8_LIBVPX_VP8_ENCODER_H_
154