| /* |
| * 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 <array> |
| #include <memory> |
| #include <optional> |
| #include <vector> |
| |
| #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<int, 4> speeds; |
| |
| // Don't use this speed level if the average QP is lower than `min_qp`. |
| std::optional<int> 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<SpeedLevel> 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<EncoderSpeedController> 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_ |