xref: /aosp_15_r20/external/webrtc/api/video_codecs/video_encoder.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 #ifndef API_VIDEO_CODECS_VIDEO_ENCODER_H_
12*d9f75844SAndroid Build Coastguard Worker #define API_VIDEO_CODECS_VIDEO_ENCODER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <limits>
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <string>
17*d9f75844SAndroid Build Coastguard Worker #include <vector>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "absl/container/inlined_vector.h"
20*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/fec_controller_override.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/units/data_rate.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/video/encoded_image.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_bitrate_allocation.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_codec_constants.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_codec.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h"
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
32*d9f75844SAndroid Build Coastguard Worker 
33*d9f75844SAndroid Build Coastguard Worker // TODO(pbos): Expose these through a public (root) header or change these APIs.
34*d9f75844SAndroid Build Coastguard Worker struct CodecSpecificInfo;
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker constexpr int kDefaultMinPixelsPerFrame = 320 * 180;
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT EncodedImageCallback {
39*d9f75844SAndroid Build Coastguard Worker  public:
~EncodedImageCallback()40*d9f75844SAndroid Build Coastguard Worker   virtual ~EncodedImageCallback() {}
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker   struct Result {
43*d9f75844SAndroid Build Coastguard Worker     enum Error {
44*d9f75844SAndroid Build Coastguard Worker       OK,
45*d9f75844SAndroid Build Coastguard Worker 
46*d9f75844SAndroid Build Coastguard Worker       // Failed to send the packet.
47*d9f75844SAndroid Build Coastguard Worker       ERROR_SEND_FAILED,
48*d9f75844SAndroid Build Coastguard Worker     };
49*d9f75844SAndroid Build Coastguard Worker 
ResultResult50*d9f75844SAndroid Build Coastguard Worker     explicit Result(Error error) : error(error) {}
ResultResult51*d9f75844SAndroid Build Coastguard Worker     Result(Error error, uint32_t frame_id) : error(error), frame_id(frame_id) {}
52*d9f75844SAndroid Build Coastguard Worker 
53*d9f75844SAndroid Build Coastguard Worker     Error error;
54*d9f75844SAndroid Build Coastguard Worker 
55*d9f75844SAndroid Build Coastguard Worker     // Frame ID assigned to the frame. The frame ID should be the same as the ID
56*d9f75844SAndroid Build Coastguard Worker     // seen by the receiver for this frame. RTP timestamp of the frame is used
57*d9f75844SAndroid Build Coastguard Worker     // as frame ID when RTP is used to send video. Must be used only when
58*d9f75844SAndroid Build Coastguard Worker     // error=OK.
59*d9f75844SAndroid Build Coastguard Worker     uint32_t frame_id = 0;
60*d9f75844SAndroid Build Coastguard Worker 
61*d9f75844SAndroid Build Coastguard Worker     // Tells the encoder that the next frame is should be dropped.
62*d9f75844SAndroid Build Coastguard Worker     bool drop_next_frame = false;
63*d9f75844SAndroid Build Coastguard Worker   };
64*d9f75844SAndroid Build Coastguard Worker 
65*d9f75844SAndroid Build Coastguard Worker   // Used to signal the encoder about reason a frame is dropped.
66*d9f75844SAndroid Build Coastguard Worker   // kDroppedByMediaOptimizations - dropped by MediaOptimizations (for rate
67*d9f75844SAndroid Build Coastguard Worker   // limiting purposes).
68*d9f75844SAndroid Build Coastguard Worker   // kDroppedByEncoder - dropped by encoder's internal rate limiter.
69*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/10164): Delete this enum? It duplicates the more
70*d9f75844SAndroid Build Coastguard Worker   // general VideoStreamEncoderObserver::DropReason. Also,
71*d9f75844SAndroid Build Coastguard Worker   // kDroppedByMediaOptimizations is not produced by any encoder, but by
72*d9f75844SAndroid Build Coastguard Worker   // VideoStreamEncoder.
73*d9f75844SAndroid Build Coastguard Worker   enum class DropReason : uint8_t {
74*d9f75844SAndroid Build Coastguard Worker     kDroppedByMediaOptimizations,
75*d9f75844SAndroid Build Coastguard Worker     kDroppedByEncoder
76*d9f75844SAndroid Build Coastguard Worker   };
77*d9f75844SAndroid Build Coastguard Worker 
78*d9f75844SAndroid Build Coastguard Worker   // Callback function which is called when an image has been encoded.
79*d9f75844SAndroid Build Coastguard Worker   virtual Result OnEncodedImage(
80*d9f75844SAndroid Build Coastguard Worker       const EncodedImage& encoded_image,
81*d9f75844SAndroid Build Coastguard Worker       const CodecSpecificInfo* codec_specific_info) = 0;
82*d9f75844SAndroid Build Coastguard Worker 
OnDroppedFrame(DropReason reason)83*d9f75844SAndroid Build Coastguard Worker   virtual void OnDroppedFrame(DropReason reason) {}
84*d9f75844SAndroid Build Coastguard Worker };
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT VideoEncoder {
87*d9f75844SAndroid Build Coastguard Worker  public:
88*d9f75844SAndroid Build Coastguard Worker   struct QpThresholds {
QpThresholdsQpThresholds89*d9f75844SAndroid Build Coastguard Worker     QpThresholds(int l, int h) : low(l), high(h) {}
QpThresholdsQpThresholds90*d9f75844SAndroid Build Coastguard Worker     QpThresholds() : low(-1), high(-1) {}
91*d9f75844SAndroid Build Coastguard Worker     int low;
92*d9f75844SAndroid Build Coastguard Worker     int high;
93*d9f75844SAndroid Build Coastguard Worker   };
94*d9f75844SAndroid Build Coastguard Worker 
95*d9f75844SAndroid Build Coastguard Worker   // Quality scaling is enabled if thresholds are provided.
96*d9f75844SAndroid Build Coastguard Worker   struct RTC_EXPORT ScalingSettings {
97*d9f75844SAndroid Build Coastguard Worker    private:
98*d9f75844SAndroid Build Coastguard Worker     // Private magic type for kOff, implicitly convertible to
99*d9f75844SAndroid Build Coastguard Worker     // ScalingSettings.
100*d9f75844SAndroid Build Coastguard Worker     struct KOff {};
101*d9f75844SAndroid Build Coastguard Worker 
102*d9f75844SAndroid Build Coastguard Worker    public:
103*d9f75844SAndroid Build Coastguard Worker     // TODO(bugs.webrtc.org/9078): Since absl::optional should be trivially copy
104*d9f75844SAndroid Build Coastguard Worker     // constructible, this magic value can likely be replaced by a constexpr
105*d9f75844SAndroid Build Coastguard Worker     // ScalingSettings value.
106*d9f75844SAndroid Build Coastguard Worker     static constexpr KOff kOff = {};
107*d9f75844SAndroid Build Coastguard Worker 
108*d9f75844SAndroid Build Coastguard Worker     ScalingSettings(int low, int high);
109*d9f75844SAndroid Build Coastguard Worker     ScalingSettings(int low, int high, int min_pixels);
110*d9f75844SAndroid Build Coastguard Worker     ScalingSettings(const ScalingSettings&);
111*d9f75844SAndroid Build Coastguard Worker     ScalingSettings(KOff);  // NOLINT(runtime/explicit)
112*d9f75844SAndroid Build Coastguard Worker     ~ScalingSettings();
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker     absl::optional<QpThresholds> thresholds;
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker     // We will never ask for a resolution lower than this.
117*d9f75844SAndroid Build Coastguard Worker     // TODO(kthelgason): Lower this limit when better testing
118*d9f75844SAndroid Build Coastguard Worker     // on MediaCodec and fallback implementations are in place.
119*d9f75844SAndroid Build Coastguard Worker     // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206
120*d9f75844SAndroid Build Coastguard Worker     int min_pixels_per_frame = kDefaultMinPixelsPerFrame;
121*d9f75844SAndroid Build Coastguard Worker 
122*d9f75844SAndroid Build Coastguard Worker    private:
123*d9f75844SAndroid Build Coastguard Worker     // Private constructor; to get an object without thresholds, use
124*d9f75844SAndroid Build Coastguard Worker     // the magic constant ScalingSettings::kOff.
125*d9f75844SAndroid Build Coastguard Worker     ScalingSettings();
126*d9f75844SAndroid Build Coastguard Worker   };
127*d9f75844SAndroid Build Coastguard Worker 
128*d9f75844SAndroid Build Coastguard Worker   // Bitrate limits for resolution.
129*d9f75844SAndroid Build Coastguard Worker   struct ResolutionBitrateLimits {
ResolutionBitrateLimitsResolutionBitrateLimits130*d9f75844SAndroid Build Coastguard Worker     ResolutionBitrateLimits(int frame_size_pixels,
131*d9f75844SAndroid Build Coastguard Worker                             int min_start_bitrate_bps,
132*d9f75844SAndroid Build Coastguard Worker                             int min_bitrate_bps,
133*d9f75844SAndroid Build Coastguard Worker                             int max_bitrate_bps)
134*d9f75844SAndroid Build Coastguard Worker         : frame_size_pixels(frame_size_pixels),
135*d9f75844SAndroid Build Coastguard Worker           min_start_bitrate_bps(min_start_bitrate_bps),
136*d9f75844SAndroid Build Coastguard Worker           min_bitrate_bps(min_bitrate_bps),
137*d9f75844SAndroid Build Coastguard Worker           max_bitrate_bps(max_bitrate_bps) {}
138*d9f75844SAndroid Build Coastguard Worker     // Size of video frame, in pixels, the bitrate thresholds are intended for.
139*d9f75844SAndroid Build Coastguard Worker     int frame_size_pixels = 0;
140*d9f75844SAndroid Build Coastguard Worker     // Recommended minimum bitrate to start encoding.
141*d9f75844SAndroid Build Coastguard Worker     int min_start_bitrate_bps = 0;
142*d9f75844SAndroid Build Coastguard Worker     // Recommended minimum bitrate.
143*d9f75844SAndroid Build Coastguard Worker     int min_bitrate_bps = 0;
144*d9f75844SAndroid Build Coastguard Worker     // Recommended maximum bitrate.
145*d9f75844SAndroid Build Coastguard Worker     int max_bitrate_bps = 0;
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker     bool operator==(const ResolutionBitrateLimits& rhs) const;
148*d9f75844SAndroid Build Coastguard Worker     bool operator!=(const ResolutionBitrateLimits& rhs) const {
149*d9f75844SAndroid Build Coastguard Worker       return !(*this == rhs);
150*d9f75844SAndroid Build Coastguard Worker     }
151*d9f75844SAndroid Build Coastguard Worker   };
152*d9f75844SAndroid Build Coastguard Worker 
153*d9f75844SAndroid Build Coastguard Worker   // Struct containing metadata about the encoder implementing this interface.
154*d9f75844SAndroid Build Coastguard Worker   struct RTC_EXPORT EncoderInfo {
155*d9f75844SAndroid Build Coastguard Worker     static constexpr uint8_t kMaxFramerateFraction =
156*d9f75844SAndroid Build Coastguard Worker         std::numeric_limits<uint8_t>::max();
157*d9f75844SAndroid Build Coastguard Worker 
158*d9f75844SAndroid Build Coastguard Worker     EncoderInfo();
159*d9f75844SAndroid Build Coastguard Worker     EncoderInfo(const EncoderInfo&);
160*d9f75844SAndroid Build Coastguard Worker 
161*d9f75844SAndroid Build Coastguard Worker     ~EncoderInfo();
162*d9f75844SAndroid Build Coastguard Worker 
163*d9f75844SAndroid Build Coastguard Worker     std::string ToString() const;
164*d9f75844SAndroid Build Coastguard Worker     bool operator==(const EncoderInfo& rhs) const;
165*d9f75844SAndroid Build Coastguard Worker     bool operator!=(const EncoderInfo& rhs) const { return !(*this == rhs); }
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker     // Any encoder implementation wishing to use the WebRTC provided
168*d9f75844SAndroid Build Coastguard Worker     // quality scaler must populate this field.
169*d9f75844SAndroid Build Coastguard Worker     ScalingSettings scaling_settings;
170*d9f75844SAndroid Build Coastguard Worker 
171*d9f75844SAndroid Build Coastguard Worker     // The width and height of the incoming video frames should be divisible
172*d9f75844SAndroid Build Coastguard Worker     // by `requested_resolution_alignment`. If they are not, the encoder may
173*d9f75844SAndroid Build Coastguard Worker     // drop the incoming frame.
174*d9f75844SAndroid Build Coastguard Worker     // For example: With I420, this value would be a multiple of 2.
175*d9f75844SAndroid Build Coastguard Worker     // Note that this field is unrelated to any horizontal or vertical stride
176*d9f75844SAndroid Build Coastguard Worker     // requirements the encoder has on the incoming video frame buffers.
177*d9f75844SAndroid Build Coastguard Worker     int requested_resolution_alignment;
178*d9f75844SAndroid Build Coastguard Worker 
179*d9f75844SAndroid Build Coastguard Worker     // Same as above but if true, each simulcast layer should also be divisible
180*d9f75844SAndroid Build Coastguard Worker     // by `requested_resolution_alignment`.
181*d9f75844SAndroid Build Coastguard Worker     // Note that scale factors `scale_resolution_down_by` may be adjusted so a
182*d9f75844SAndroid Build Coastguard Worker     // common multiple is not too large to avoid largely cropped frames and
183*d9f75844SAndroid Build Coastguard Worker     // possibly with an aspect ratio far from the original.
184*d9f75844SAndroid Build Coastguard Worker     // Warning: large values of scale_resolution_down_by could be changed
185*d9f75844SAndroid Build Coastguard Worker     // considerably, especially if `requested_resolution_alignment` is large.
186*d9f75844SAndroid Build Coastguard Worker     bool apply_alignment_to_all_simulcast_layers;
187*d9f75844SAndroid Build Coastguard Worker 
188*d9f75844SAndroid Build Coastguard Worker     // If true, encoder supports working with a native handle (e.g. texture
189*d9f75844SAndroid Build Coastguard Worker     // handle for hw codecs) rather than requiring a raw I420 buffer.
190*d9f75844SAndroid Build Coastguard Worker     bool supports_native_handle;
191*d9f75844SAndroid Build Coastguard Worker 
192*d9f75844SAndroid Build Coastguard Worker     // The name of this particular encoder implementation, e.g. "libvpx".
193*d9f75844SAndroid Build Coastguard Worker     std::string implementation_name;
194*d9f75844SAndroid Build Coastguard Worker 
195*d9f75844SAndroid Build Coastguard Worker     // If this field is true, the encoder rate controller must perform
196*d9f75844SAndroid Build Coastguard Worker     // well even in difficult situations, and produce close to the specified
197*d9f75844SAndroid Build Coastguard Worker     // target bitrate seen over a reasonable time window, drop frames if
198*d9f75844SAndroid Build Coastguard Worker     // necessary in order to keep the rate correct, and react quickly to
199*d9f75844SAndroid Build Coastguard Worker     // changing bitrate targets. If this method returns true, we disable the
200*d9f75844SAndroid Build Coastguard Worker     // frame dropper in the media optimization module and rely entirely on the
201*d9f75844SAndroid Build Coastguard Worker     // encoder to produce media at a bitrate that closely matches the target.
202*d9f75844SAndroid Build Coastguard Worker     // Any overshooting may result in delay buildup. If this method returns
203*d9f75844SAndroid Build Coastguard Worker     // false (default behavior), the media opt frame dropper will drop input
204*d9f75844SAndroid Build Coastguard Worker     // frames if it suspect encoder misbehavior. Misbehavior is common,
205*d9f75844SAndroid Build Coastguard Worker     // especially in hardware codecs. Disable media opt at your own risk.
206*d9f75844SAndroid Build Coastguard Worker     bool has_trusted_rate_controller;
207*d9f75844SAndroid Build Coastguard Worker 
208*d9f75844SAndroid Build Coastguard Worker     // If this field is true, the encoder uses hardware support and different
209*d9f75844SAndroid Build Coastguard Worker     // thresholds will be used in CPU adaptation.
210*d9f75844SAndroid Build Coastguard Worker     bool is_hardware_accelerated;
211*d9f75844SAndroid Build Coastguard Worker 
212*d9f75844SAndroid Build Coastguard Worker     // For each spatial layer (simulcast stream or SVC layer), represented as an
213*d9f75844SAndroid Build Coastguard Worker     // element in `fps_allocation` a vector indicates how many temporal layers
214*d9f75844SAndroid Build Coastguard Worker     // the encoder is using for that spatial layer.
215*d9f75844SAndroid Build Coastguard Worker     // For each spatial/temporal layer pair, the frame rate fraction is given as
216*d9f75844SAndroid Build Coastguard Worker     // an 8bit unsigned integer where 0 = 0% and 255 = 100%.
217*d9f75844SAndroid Build Coastguard Worker     //
218*d9f75844SAndroid Build Coastguard Worker     // If the vector is empty for a given spatial layer, it indicates that frame
219*d9f75844SAndroid Build Coastguard Worker     // rates are not defined and we can't count on any specific frame rate to be
220*d9f75844SAndroid Build Coastguard Worker     // generated. Likely this indicates Vp8TemporalLayersType::kBitrateDynamic.
221*d9f75844SAndroid Build Coastguard Worker     //
222*d9f75844SAndroid Build Coastguard Worker     // The encoder may update this on a per-frame basis in response to both
223*d9f75844SAndroid Build Coastguard Worker     // internal and external signals.
224*d9f75844SAndroid Build Coastguard Worker     //
225*d9f75844SAndroid Build Coastguard Worker     // Spatial layers are treated independently, but temporal layers are
226*d9f75844SAndroid Build Coastguard Worker     // cumulative. For instance, if:
227*d9f75844SAndroid Build Coastguard Worker     //   fps_allocation[0][0] = kFullFramerate / 2;
228*d9f75844SAndroid Build Coastguard Worker     //   fps_allocation[0][1] = kFullFramerate;
229*d9f75844SAndroid Build Coastguard Worker     // Then half of the frames are in the base layer and half is in TL1, but
230*d9f75844SAndroid Build Coastguard Worker     // since TL1 is assumed to depend on the base layer, the frame rate is
231*d9f75844SAndroid Build Coastguard Worker     // indicated as the full 100% for the top layer.
232*d9f75844SAndroid Build Coastguard Worker     //
233*d9f75844SAndroid Build Coastguard Worker     // Defaults to a single spatial layer containing a single temporal layer
234*d9f75844SAndroid Build Coastguard Worker     // with a 100% frame rate fraction.
235*d9f75844SAndroid Build Coastguard Worker     absl::InlinedVector<uint8_t, kMaxTemporalStreams>
236*d9f75844SAndroid Build Coastguard Worker         fps_allocation[kMaxSpatialLayers];
237*d9f75844SAndroid Build Coastguard Worker 
238*d9f75844SAndroid Build Coastguard Worker     // Recommended bitrate limits for different resolutions.
239*d9f75844SAndroid Build Coastguard Worker     std::vector<ResolutionBitrateLimits> resolution_bitrate_limits;
240*d9f75844SAndroid Build Coastguard Worker 
241*d9f75844SAndroid Build Coastguard Worker     // Obtains the limits from `resolution_bitrate_limits` that best matches the
242*d9f75844SAndroid Build Coastguard Worker     // `frame_size_pixels`.
243*d9f75844SAndroid Build Coastguard Worker     absl::optional<ResolutionBitrateLimits>
244*d9f75844SAndroid Build Coastguard Worker     GetEncoderBitrateLimitsForResolution(int frame_size_pixels) const;
245*d9f75844SAndroid Build Coastguard Worker 
246*d9f75844SAndroid Build Coastguard Worker     // If true, this encoder has internal support for generating simulcast
247*d9f75844SAndroid Build Coastguard Worker     // streams. Otherwise, an adapter class will be needed.
248*d9f75844SAndroid Build Coastguard Worker     // Even if true, the config provided to InitEncode() might not be supported,
249*d9f75844SAndroid Build Coastguard Worker     // in such case the encoder should return
250*d9f75844SAndroid Build Coastguard Worker     // WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED.
251*d9f75844SAndroid Build Coastguard Worker     bool supports_simulcast;
252*d9f75844SAndroid Build Coastguard Worker 
253*d9f75844SAndroid Build Coastguard Worker     // The list of pixel formats preferred by the encoder. It is assumed that if
254*d9f75844SAndroid Build Coastguard Worker     // the list is empty and supports_native_handle is false, then {I420} is the
255*d9f75844SAndroid Build Coastguard Worker     // preferred pixel format. The order of the formats does not matter.
256*d9f75844SAndroid Build Coastguard Worker     absl::InlinedVector<VideoFrameBuffer::Type, kMaxPreferredPixelFormats>
257*d9f75844SAndroid Build Coastguard Worker         preferred_pixel_formats;
258*d9f75844SAndroid Build Coastguard Worker 
259*d9f75844SAndroid Build Coastguard Worker     // Indicates whether or not QP value encoder writes into frame/slice/tile
260*d9f75844SAndroid Build Coastguard Worker     // header can be interpreted as average frame/slice/tile QP.
261*d9f75844SAndroid Build Coastguard Worker     absl::optional<bool> is_qp_trusted;
262*d9f75844SAndroid Build Coastguard Worker   };
263*d9f75844SAndroid Build Coastguard Worker 
264*d9f75844SAndroid Build Coastguard Worker   struct RTC_EXPORT RateControlParameters {
265*d9f75844SAndroid Build Coastguard Worker     RateControlParameters();
266*d9f75844SAndroid Build Coastguard Worker     RateControlParameters(const VideoBitrateAllocation& bitrate,
267*d9f75844SAndroid Build Coastguard Worker                           double framerate_fps);
268*d9f75844SAndroid Build Coastguard Worker     RateControlParameters(const VideoBitrateAllocation& bitrate,
269*d9f75844SAndroid Build Coastguard Worker                           double framerate_fps,
270*d9f75844SAndroid Build Coastguard Worker                           DataRate bandwidth_allocation);
271*d9f75844SAndroid Build Coastguard Worker     virtual ~RateControlParameters();
272*d9f75844SAndroid Build Coastguard Worker 
273*d9f75844SAndroid Build Coastguard Worker     // Target bitrate, per spatial/temporal layer.
274*d9f75844SAndroid Build Coastguard Worker     // A target bitrate of 0bps indicates a layer should not be encoded at all.
275*d9f75844SAndroid Build Coastguard Worker     VideoBitrateAllocation target_bitrate;
276*d9f75844SAndroid Build Coastguard Worker     // Adjusted target bitrate, per spatial/temporal layer. May be lower or
277*d9f75844SAndroid Build Coastguard Worker     // higher than the target depending on encoder behaviour.
278*d9f75844SAndroid Build Coastguard Worker     VideoBitrateAllocation bitrate;
279*d9f75844SAndroid Build Coastguard Worker     // Target framerate, in fps. A value <= 0.0 is invalid and should be
280*d9f75844SAndroid Build Coastguard Worker     // interpreted as framerate target not available. In this case the encoder
281*d9f75844SAndroid Build Coastguard Worker     // should fall back to the max framerate specified in `codec_settings` of
282*d9f75844SAndroid Build Coastguard Worker     // the last InitEncode() call.
283*d9f75844SAndroid Build Coastguard Worker     double framerate_fps;
284*d9f75844SAndroid Build Coastguard Worker     // The network bandwidth available for video. This is at least
285*d9f75844SAndroid Build Coastguard Worker     // `bitrate.get_sum_bps()`, but may be higher if the application is not
286*d9f75844SAndroid Build Coastguard Worker     // network constrained.
287*d9f75844SAndroid Build Coastguard Worker     DataRate bandwidth_allocation;
288*d9f75844SAndroid Build Coastguard Worker 
289*d9f75844SAndroid Build Coastguard Worker     bool operator==(const RateControlParameters& rhs) const;
290*d9f75844SAndroid Build Coastguard Worker     bool operator!=(const RateControlParameters& rhs) const;
291*d9f75844SAndroid Build Coastguard Worker   };
292*d9f75844SAndroid Build Coastguard Worker 
293*d9f75844SAndroid Build Coastguard Worker   struct LossNotification {
294*d9f75844SAndroid Build Coastguard Worker     // The timestamp of the last decodable frame *prior* to the last received.
295*d9f75844SAndroid Build Coastguard Worker     // (The last received - described below - might itself be decodable or not.)
296*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp_of_last_decodable;
297*d9f75844SAndroid Build Coastguard Worker     // The timestamp of the last received frame.
298*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp_of_last_received;
299*d9f75844SAndroid Build Coastguard Worker     // Describes whether the dependencies of the last received frame were
300*d9f75844SAndroid Build Coastguard Worker     // all decodable.
301*d9f75844SAndroid Build Coastguard Worker     // `false` if some dependencies were undecodable, `true` if all dependencies
302*d9f75844SAndroid Build Coastguard Worker     // were decodable, and `nullopt` if the dependencies are unknown.
303*d9f75844SAndroid Build Coastguard Worker     absl::optional<bool> dependencies_of_last_received_decodable;
304*d9f75844SAndroid Build Coastguard Worker     // Describes whether the received frame was decodable.
305*d9f75844SAndroid Build Coastguard Worker     // `false` if some dependency was undecodable or if some packet belonging
306*d9f75844SAndroid Build Coastguard Worker     // to the last received frame was missed.
307*d9f75844SAndroid Build Coastguard Worker     // `true` if all dependencies were decodable and all packets belonging
308*d9f75844SAndroid Build Coastguard Worker     // to the last received frame were received.
309*d9f75844SAndroid Build Coastguard Worker     // `nullopt` if no packet belonging to the last frame was missed, but the
310*d9f75844SAndroid Build Coastguard Worker     // last packet in the frame was not yet received.
311*d9f75844SAndroid Build Coastguard Worker     absl::optional<bool> last_received_decodable;
312*d9f75844SAndroid Build Coastguard Worker   };
313*d9f75844SAndroid Build Coastguard Worker 
314*d9f75844SAndroid Build Coastguard Worker   // Negotiated capabilities which the VideoEncoder may expect the other
315*d9f75844SAndroid Build Coastguard Worker   // side to use.
316*d9f75844SAndroid Build Coastguard Worker   struct Capabilities {
CapabilitiesCapabilities317*d9f75844SAndroid Build Coastguard Worker     explicit Capabilities(bool loss_notification)
318*d9f75844SAndroid Build Coastguard Worker         : loss_notification(loss_notification) {}
319*d9f75844SAndroid Build Coastguard Worker     bool loss_notification;
320*d9f75844SAndroid Build Coastguard Worker   };
321*d9f75844SAndroid Build Coastguard Worker 
322*d9f75844SAndroid Build Coastguard Worker   struct Settings {
SettingsSettings323*d9f75844SAndroid Build Coastguard Worker     Settings(const Capabilities& capabilities,
324*d9f75844SAndroid Build Coastguard Worker              int number_of_cores,
325*d9f75844SAndroid Build Coastguard Worker              size_t max_payload_size)
326*d9f75844SAndroid Build Coastguard Worker         : capabilities(capabilities),
327*d9f75844SAndroid Build Coastguard Worker           number_of_cores(number_of_cores),
328*d9f75844SAndroid Build Coastguard Worker           max_payload_size(max_payload_size) {}
329*d9f75844SAndroid Build Coastguard Worker 
330*d9f75844SAndroid Build Coastguard Worker     Capabilities capabilities;
331*d9f75844SAndroid Build Coastguard Worker     int number_of_cores;
332*d9f75844SAndroid Build Coastguard Worker     size_t max_payload_size;
333*d9f75844SAndroid Build Coastguard Worker   };
334*d9f75844SAndroid Build Coastguard Worker 
335*d9f75844SAndroid Build Coastguard Worker   static VideoCodecVP8 GetDefaultVp8Settings();
336*d9f75844SAndroid Build Coastguard Worker   static VideoCodecVP9 GetDefaultVp9Settings();
337*d9f75844SAndroid Build Coastguard Worker   static VideoCodecH264 GetDefaultH264Settings();
338*d9f75844SAndroid Build Coastguard Worker 
~VideoEncoder()339*d9f75844SAndroid Build Coastguard Worker   virtual ~VideoEncoder() {}
340*d9f75844SAndroid Build Coastguard Worker 
341*d9f75844SAndroid Build Coastguard Worker   // Set a FecControllerOverride, through which the encoder may override
342*d9f75844SAndroid Build Coastguard Worker   // decisions made by FecController.
343*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/10769): Update downstream, then make pure-virtual.
344*d9f75844SAndroid Build Coastguard Worker   virtual void SetFecControllerOverride(
345*d9f75844SAndroid Build Coastguard Worker       FecControllerOverride* fec_controller_override);
346*d9f75844SAndroid Build Coastguard Worker 
347*d9f75844SAndroid Build Coastguard Worker   // Initialize the encoder with the information from the codecSettings
348*d9f75844SAndroid Build Coastguard Worker   //
349*d9f75844SAndroid Build Coastguard Worker   // Input:
350*d9f75844SAndroid Build Coastguard Worker   //          - codec_settings    : Codec settings
351*d9f75844SAndroid Build Coastguard Worker   //          - settings          : Settings affecting the encoding itself.
352*d9f75844SAndroid Build Coastguard Worker   // Input for deprecated version:
353*d9f75844SAndroid Build Coastguard Worker   //          - number_of_cores   : Number of cores available for the encoder
354*d9f75844SAndroid Build Coastguard Worker   //          - max_payload_size  : The maximum size each payload is allowed
355*d9f75844SAndroid Build Coastguard Worker   //                                to have. Usually MTU - overhead.
356*d9f75844SAndroid Build Coastguard Worker   //
357*d9f75844SAndroid Build Coastguard Worker   // Return value                  : Set bit rate if OK
358*d9f75844SAndroid Build Coastguard Worker   //                                 <0 - Errors:
359*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_ERR_PARAMETER
360*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_ERR_SIZE
361*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_MEMORY
362*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_ERROR
363*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/10720): After updating downstream projects and posting
364*d9f75844SAndroid Build Coastguard Worker   // an announcement to discuss-webrtc, remove the three-parameters variant
365*d9f75844SAndroid Build Coastguard Worker   // and make the two-parameters variant pure-virtual.
366*d9f75844SAndroid Build Coastguard Worker   /* ABSL_DEPRECATED("bugs.webrtc.org/10720") */ virtual int32_t InitEncode(
367*d9f75844SAndroid Build Coastguard Worker       const VideoCodec* codec_settings,
368*d9f75844SAndroid Build Coastguard Worker       int32_t number_of_cores,
369*d9f75844SAndroid Build Coastguard Worker       size_t max_payload_size);
370*d9f75844SAndroid Build Coastguard Worker   virtual int InitEncode(const VideoCodec* codec_settings,
371*d9f75844SAndroid Build Coastguard Worker                          const VideoEncoder::Settings& settings);
372*d9f75844SAndroid Build Coastguard Worker 
373*d9f75844SAndroid Build Coastguard Worker   // Register an encode complete callback object.
374*d9f75844SAndroid Build Coastguard Worker   //
375*d9f75844SAndroid Build Coastguard Worker   // Input:
376*d9f75844SAndroid Build Coastguard Worker   //          - callback         : Callback object which handles encoded images.
377*d9f75844SAndroid Build Coastguard Worker   //
378*d9f75844SAndroid Build Coastguard Worker   // Return value                : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
379*d9f75844SAndroid Build Coastguard Worker   virtual int32_t RegisterEncodeCompleteCallback(
380*d9f75844SAndroid Build Coastguard Worker       EncodedImageCallback* callback) = 0;
381*d9f75844SAndroid Build Coastguard Worker 
382*d9f75844SAndroid Build Coastguard Worker   // Free encoder memory.
383*d9f75844SAndroid Build Coastguard Worker   // Return value                : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
384*d9f75844SAndroid Build Coastguard Worker   virtual int32_t Release() = 0;
385*d9f75844SAndroid Build Coastguard Worker 
386*d9f75844SAndroid Build Coastguard Worker   // Encode an image (as a part of a video stream). The encoded image
387*d9f75844SAndroid Build Coastguard Worker   // will be returned to the user through the encode complete callback.
388*d9f75844SAndroid Build Coastguard Worker   //
389*d9f75844SAndroid Build Coastguard Worker   // Input:
390*d9f75844SAndroid Build Coastguard Worker   //          - frame             : Image to be encoded
391*d9f75844SAndroid Build Coastguard Worker   //          - frame_types       : Frame type to be generated by the encoder.
392*d9f75844SAndroid Build Coastguard Worker   //
393*d9f75844SAndroid Build Coastguard Worker   // Return value                 : WEBRTC_VIDEO_CODEC_OK if OK
394*d9f75844SAndroid Build Coastguard Worker   //                                <0 - Errors:
395*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_ERR_PARAMETER
396*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_MEMORY
397*d9f75844SAndroid Build Coastguard Worker   //                                  WEBRTC_VIDEO_CODEC_ERROR
398*d9f75844SAndroid Build Coastguard Worker   virtual int32_t Encode(const VideoFrame& frame,
399*d9f75844SAndroid Build Coastguard Worker                          const std::vector<VideoFrameType>* frame_types) = 0;
400*d9f75844SAndroid Build Coastguard Worker 
401*d9f75844SAndroid Build Coastguard Worker   // Sets rate control parameters: bitrate, framerate, etc. These settings are
402*d9f75844SAndroid Build Coastguard Worker   // instantaneous (i.e. not moving averages) and should apply from now until
403*d9f75844SAndroid Build Coastguard Worker   // the next call to SetRates().
404*d9f75844SAndroid Build Coastguard Worker   virtual void SetRates(const RateControlParameters& parameters) = 0;
405*d9f75844SAndroid Build Coastguard Worker 
406*d9f75844SAndroid Build Coastguard Worker   // Inform the encoder when the packet loss rate changes.
407*d9f75844SAndroid Build Coastguard Worker   //
408*d9f75844SAndroid Build Coastguard Worker   // Input:   - packet_loss_rate  : The packet loss rate (0.0 to 1.0).
409*d9f75844SAndroid Build Coastguard Worker   virtual void OnPacketLossRateUpdate(float packet_loss_rate);
410*d9f75844SAndroid Build Coastguard Worker 
411*d9f75844SAndroid Build Coastguard Worker   // Inform the encoder when the round trip time changes.
412*d9f75844SAndroid Build Coastguard Worker   //
413*d9f75844SAndroid Build Coastguard Worker   // Input:   - rtt_ms            : The new RTT, in milliseconds.
414*d9f75844SAndroid Build Coastguard Worker   virtual void OnRttUpdate(int64_t rtt_ms);
415*d9f75844SAndroid Build Coastguard Worker 
416*d9f75844SAndroid Build Coastguard Worker   // Called when a loss notification is received.
417*d9f75844SAndroid Build Coastguard Worker   virtual void OnLossNotification(const LossNotification& loss_notification);
418*d9f75844SAndroid Build Coastguard Worker 
419*d9f75844SAndroid Build Coastguard Worker   // Returns meta-data about the encoder, such as implementation name.
420*d9f75844SAndroid Build Coastguard Worker   // The output of this method may change during runtime. For instance if a
421*d9f75844SAndroid Build Coastguard Worker   // hardware encoder fails, it may fall back to doing software encoding using
422*d9f75844SAndroid Build Coastguard Worker   // an implementation with different characteristics.
423*d9f75844SAndroid Build Coastguard Worker   virtual EncoderInfo GetEncoderInfo() const;
424*d9f75844SAndroid Build Coastguard Worker };
425*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
426*d9f75844SAndroid Build Coastguard Worker #endif  // API_VIDEO_CODECS_VIDEO_ENCODER_H_
427