blob: 87ceaef31aaf3f700e59bed6ccef77b4478abc90 [file] [log] [blame] [edit]
/*
* 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_