The frame cadence adapter previously resulted in unconditional frame repeating at max FPS. Change this to slow down to an idle rate (1 Hz) when quality convergence in all configured spatial layers has been achieved. go/rtc-0hz-present Bug: chromium:1255737 Change-Id: Ifa593dbf8a61aa29da20ac250da332734ae82791 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/241421 Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Markus Handell <handellm@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35547}
108 lines
4.2 KiB
C++
108 lines
4.2 KiB
C++
/*
|
|
* Copyright (c) 2021 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 VIDEO_FRAME_CADENCE_ADAPTER_H_
|
|
#define VIDEO_FRAME_CADENCE_ADAPTER_H_
|
|
|
|
#include <memory>
|
|
|
|
#include "api/task_queue/task_queue_base.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "api/video/video_frame.h"
|
|
#include "api/video/video_sink_interface.h"
|
|
#include "rtc_base/synchronization/mutex.h"
|
|
#include "rtc_base/thread_annotations.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// A sink adapter implementing mutations to the received frame cadence.
|
|
// With the exception of the constructor and the methods overridden in
|
|
// VideoSinkInterface, the rest of the interface to this class (including dtor)
|
|
// needs to happen on the queue passed in Create.
|
|
class FrameCadenceAdapterInterface
|
|
: public rtc::VideoSinkInterface<VideoFrame> {
|
|
public:
|
|
// Averaging window spanning 90 frames at default 30fps, matching old media
|
|
// optimization module defaults.
|
|
// TODO(crbug.com/1255737): Use TimeDelta.
|
|
static constexpr int64_t kFrameRateAveragingWindowSizeMs = (1000 / 30) * 90;
|
|
// In zero-hertz mode, the idle repeat rate is a compromise between
|
|
// RTP receiver keyframe-requesting timeout (3s), other backend limitations
|
|
// and some worst case RTT.
|
|
static constexpr TimeDelta kZeroHertzIdleRepeatRatePeriod =
|
|
TimeDelta::Millis(1000);
|
|
|
|
struct ZeroHertzModeParams {
|
|
// The number of simulcast layers used in this configuration.
|
|
int num_simulcast_layers = 0;
|
|
};
|
|
|
|
// Callback interface used to inform instance owners.
|
|
class Callback {
|
|
public:
|
|
virtual ~Callback() = default;
|
|
|
|
// Called when a frame arrives on the |queue| specified in Create.
|
|
//
|
|
// The |post_time| parameter indicates the current time sampled when
|
|
// FrameCadenceAdapterInterface::OnFrame was called.
|
|
//
|
|
// |frames_scheduled_for_processing| indicates how many frames that have
|
|
// been scheduled for processing. During sequential conditions where
|
|
// FrameCadenceAdapterInterface::OnFrame is invoked and subsequently ending
|
|
// up in this callback, this value will read 1. Otherwise if the
|
|
// |queue| gets stalled for some reason, the value will increase
|
|
// beyond 1.
|
|
virtual void OnFrame(Timestamp post_time,
|
|
int frames_scheduled_for_processing,
|
|
const VideoFrame& frame) = 0;
|
|
|
|
// Called when the source has discarded a frame.
|
|
virtual void OnDiscardedFrame() = 0;
|
|
};
|
|
|
|
// Factory function creating a production instance. Deletion of the returned
|
|
// instance needs to happen on the same sequence that Create() was called on.
|
|
// Frames arriving in FrameCadenceAdapterInterface::OnFrame are posted to
|
|
// Callback::OnFrame on the |queue|.
|
|
static std::unique_ptr<FrameCadenceAdapterInterface> Create(
|
|
Clock* clock,
|
|
TaskQueueBase* queue);
|
|
|
|
// Call before using the rest of the API.
|
|
virtual void Initialize(Callback* callback) = 0;
|
|
|
|
// Pass zero hertz parameters in |params| as a prerequisite to enable
|
|
// zero-hertz operation. If absl:::nullopt is passed, the cadence adapter will
|
|
// switch to passthrough mode.
|
|
virtual void SetZeroHertzModeEnabled(
|
|
absl::optional<ZeroHertzModeParams> params) = 0;
|
|
|
|
// Returns the input framerate. This is measured by RateStatistics when
|
|
// zero-hertz mode is off, and returns the max framerate in zero-hertz mode.
|
|
virtual absl::optional<uint32_t> GetInputFrameRateFps() = 0;
|
|
|
|
// Updates frame rate. This is done unconditionally irrespective of adapter
|
|
// mode.
|
|
virtual void UpdateFrameRate() = 0;
|
|
|
|
// Updates quality convergence status for an enabled spatial layer.
|
|
virtual void UpdateLayerQualityConvergence(int spatial_index,
|
|
bool converged) = 0;
|
|
|
|
// Updates spatial layer enabled status.
|
|
virtual void UpdateLayerStatus(int spatial_index, bool enabled) = 0;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // VIDEO_FRAME_CADENCE_ADAPTER_H_
|