blob: 94e861b9426e09c2e9287217b3592188cb6350bd [file] [log] [blame]
/*
* 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 MODULES_VIDEO_CODING_UTILITY_ENCODER_SPEED_CONTROLLER_IMPL_H_
#define MODULES_VIDEO_CODING_UTILITY_ENCODER_SPEED_CONTROLLER_IMPL_H_
#include <memory>
#include <optional>
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video_codecs/encoder_speed_controller.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.
class EncoderSpeedControllerImpl : public webrtc::EncoderSpeedController {
public:
// 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<webrtc::EncoderSpeedController> Create(
const Config& config,
TimeDelta start_frame_interval);
// 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.
void SetFrameInterval(TimeDelta frame_interval) override;
// Should be called before each frame to be encoded, and the encoder should
// thereafter be configured with requested settings.
EncodeSettings GetEncodeSettings(FrameEncodingInfo frame_info) override;
// Should be called after each frame has completed encoding. If a baseline
// comparison speed was set in the `EncodeSettings`, the `baseline_results`
// parameter should be set with the results corresponding to those settings.
void OnEncodedFrame(EncodeResults results,
std::optional<EncodeResults> baseline_results) override;
const Config& config() const { return config_; }
private:
EncoderSpeedControllerImpl(const Config& config,
TimeDelta start_frame_interval);
bool ShouldIncreaseSpeed() const;
bool ShouldDecreaseSpeedDisregardingPsnr() const;
bool PsnrProbeRequiredForNextSlowerSpeed() const;
bool ShouldRecheckPsnrGain(Timestamp current_time) const;
void ResetStats();
void IncreaseSpeed();
void DecreaseSpeed();
const Config config_;
TimeDelta frame_interval_;
int current_speed_index_;
// The number of frames recorded since last clearing the stats.
int num_samples_;
// Exponentially filtered measreuements of encode times and average frame qp.
double slow_filtered_encode_time_ms_;
double fast_filtered_encode_time_ms_;
double filtered_qp_;
// Timestamp of last request for a PSNR measurement, either due to periodic
// sampling or requested for speed index change. Negative infinity if not set.
Timestamp last_psnr_probe_;
// Timestamp and speed level index of the last PSNR probing request for the
// current layer. Note that we only track comparative PSNR gain checks here
// (i.e. an alternate speed was given), single frame PSNR sampling does not
// affect this value.
struct PsnrGainCheck {
int speed_level;
Timestamp timestamp;
};
std::optional<PsnrGainCheck> last_psnr_gain_check_;
};
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_UTILITY_ENCODER_SPEED_CONTROLLER_IMPL_H_