/* * Copyright (c) 2025 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 API_VIDEO_CODECS_ENCODER_SPEED_CONTROLLER_H_ #define API_VIDEO_CODECS_ENCODER_SPEED_CONTROLLER_H_ #include #include #include #include #include "api/units/time_delta.h" namespace webrtc { // Utility class intended to help dynamically find the optimal speed settings to // use for a video encoder. An instance of this class is intended to handle a // single session at a single resolution. I.e. and new instance should be // created if the resolution is updated. That also provides the opportunity to // configure a new set of available speeds, more appropriate for the new // resolution. If spatial SVC and/or simulcast is used, the caller of this class // must make sure the frame interval is adjusted if the encodings of a temporal // unit is serialized. class EncoderSpeedController { public: // The `ReferenceClass` allows the controller to pick a separate speed level // based on the importance of the frame. Frames that act as references for // many subsequent frames typically warrant a higher effort level. enum class ReferenceClass : int { kKey = 0, // Key-frames, or long-term references. kMain, // "Normal" delta frames or a temporal base layer kIntermediate, // Reference for a short-live frame tree (e.g T1 in L1T3) kNoneReference // A frame not used as reference sub subsequent frames. }; struct Config { // Represents an assignable speed level, with specific speeds for one or // more temporal layers. struct SpeedLevel { // The actual speed levels (values of the integers below) are // implementation specific. It is up to the user to make mappings // between these and what the API surface of the encoder looks like, // if it is not using integers. // Array of speeds, indexed by ReferenceClass. std::array speeds; // Don't use this speed level if the average QP is lower than `min_qp`. std::optional min_qp; }; // Ordered vector of speed levels, start with the slowest speed (lower // effort) and the increasing the average speed for each entry. std::vector speed_levels; // An index into `speed_levels` at which the controller should start. int start_speed_index; }; // Input data to the controller about the frame that is about the be encoded. struct FrameEncodingInfo { // The reference class of the frame to be encoded. ReferenceClass reference_type; // True iff the frame is a repeat of the previous frame (e.g. the frames // used during quality convergence of a variable fps screenshare feed). bool is_repeat_frame; }; // Output from the controller, indicates which speed the encoder should be // configured with given the frame info that was submitted. struct EncodeSettings { // Speed the encoder should use for this frame. int speed; }; // Data the controller should be fed with after a frame has been encoded, // providing info about the resulting encoding. struct EncodeResults { // The speed setting used for this encoded frame. int speed; // The time it took to encode the frame. TimeDelta encode_time; // The _average_ frame QP of the encoded frame. int qp; // The frame encoding info - same as what was originally given as argument // to `GetEncodingSettings()`. FrameEncodingInfo frame_info; }; // Creates an instance of the speed controller. This should be called any // time the encoder has been recreated e.g. due to a resolution change. static std::unique_ptr Create( const Config& config, TimeDelta start_frame_interval); virtual ~EncoderSpeedController() = default; // Should be called any time the rate targets of the encoder changed. // The frame interval (1s/fps) effectively sets the time limit for an encoding // operation. virtual void SetFrameInterval(TimeDelta frame_interval) = 0; // Should be called before each frame to be encoded, and the encoder should // thereafter be configured with requested settings. virtual EncodeSettings GetEncodeSettings(FrameEncodingInfo frame_info) = 0; // Should be called after each frame has completed encoding. virtual void OnEncodedFrame(EncodeResults results) = 0; }; } // namespace webrtc #endif // API_VIDEO_CODECS_ENCODER_SPEED_CONTROLLER_H_