[SlackedPacer] Add experiment arm for high precision if long queue time.
This CL adds flag "max_queue_time", e.g: WebRTC-SlackedTaskQueuePacedSender/Enabled:true,max_queue_time:75ms If the PacingController's ExpectedQueueTime() is greater than or equal to "max_queue_time" then we will use high precision delayed tasks to ensure a smoother (less bursty) pacing of packets. This should only get triggered in ultra high definition scenarios or temporarily during key frames being sent. I have confirmed manually that with the flag set to 75 ms I get low precision when not sending key frames and temporarily get high precision for 5-15 delayed tasks during the sending of a key frame. Bug: webrtc:13957 Change-Id: I3c8aeba5fe18812ed0187610cd3f92a375bc6f18 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/258623 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36538}
This commit is contained in:
parent
4d12174ca5
commit
a768f5256a
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_units.h"
|
||||||
#include "rtc_base/trace_event.h"
|
#include "rtc_base/trace_event.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -28,6 +30,15 @@ constexpr const char* kSlackedTaskQueuePacedSenderFieldTrial =
|
|||||||
|
|
||||||
const int TaskQueuePacedSender::kNoPacketHoldback = -1;
|
const int TaskQueuePacedSender::kNoPacketHoldback = -1;
|
||||||
|
|
||||||
|
TaskQueuePacedSender::SlackedPacerFlags::SlackedPacerFlags(
|
||||||
|
const FieldTrialsView& field_trials)
|
||||||
|
: allow_low_precision("Enabled"),
|
||||||
|
max_low_precision_expected_queue_time("max_queue_time") {
|
||||||
|
ParseFieldTrial(
|
||||||
|
{&allow_low_precision, &max_low_precision_expected_queue_time},
|
||||||
|
field_trials.Lookup(kSlackedTaskQueuePacedSenderFieldTrial));
|
||||||
|
}
|
||||||
|
|
||||||
TaskQueuePacedSender::TaskQueuePacedSender(
|
TaskQueuePacedSender::TaskQueuePacedSender(
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
PacingController::PacketSender* packet_sender,
|
PacingController::PacketSender* packet_sender,
|
||||||
@ -36,13 +47,13 @@ TaskQueuePacedSender::TaskQueuePacedSender(
|
|||||||
TimeDelta max_hold_back_window,
|
TimeDelta max_hold_back_window,
|
||||||
int max_hold_back_window_in_packets)
|
int max_hold_back_window_in_packets)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
allow_low_precision_(
|
slacked_pacer_flags_(field_trials),
|
||||||
field_trials.IsEnabled(kSlackedTaskQueuePacedSenderFieldTrial)),
|
max_hold_back_window_(slacked_pacer_flags_.allow_low_precision
|
||||||
max_hold_back_window_(allow_low_precision_
|
|
||||||
? PacingController::kMinSleepTime
|
? PacingController::kMinSleepTime
|
||||||
: max_hold_back_window),
|
: max_hold_back_window),
|
||||||
max_hold_back_window_in_packets_(
|
max_hold_back_window_in_packets_(slacked_pacer_flags_.allow_low_precision
|
||||||
allow_low_precision_ ? 0 : max_hold_back_window_in_packets),
|
? 0
|
||||||
|
: max_hold_back_window_in_packets),
|
||||||
pacing_controller_(clock,
|
pacing_controller_(clock,
|
||||||
packet_sender,
|
packet_sender,
|
||||||
field_trials,
|
field_trials,
|
||||||
@ -279,9 +290,19 @@ void TaskQueuePacedSender::MaybeProcessPackets(
|
|||||||
next_process_time_ > next_send_time) {
|
next_process_time_ > next_send_time) {
|
||||||
// Prefer low precision if allowed and not probing.
|
// Prefer low precision if allowed and not probing.
|
||||||
TaskQueueBase::DelayPrecision precision =
|
TaskQueueBase::DelayPrecision precision =
|
||||||
allow_low_precision_ && !pacing_controller_.IsProbing()
|
slacked_pacer_flags_.allow_low_precision &&
|
||||||
|
!pacing_controller_.IsProbing()
|
||||||
? TaskQueueBase::DelayPrecision::kLow
|
? TaskQueueBase::DelayPrecision::kLow
|
||||||
: TaskQueueBase::DelayPrecision::kHigh;
|
: TaskQueueBase::DelayPrecision::kHigh;
|
||||||
|
// Optionally disable low precision if the expected queue time is greater
|
||||||
|
// than `max_low_precision_expected_queue_time`.
|
||||||
|
if (precision == TaskQueueBase::DelayPrecision::kLow &&
|
||||||
|
slacked_pacer_flags_.max_low_precision_expected_queue_time &&
|
||||||
|
pacing_controller_.ExpectedQueueTime() >=
|
||||||
|
slacked_pacer_flags_.max_low_precision_expected_queue_time
|
||||||
|
.Value()) {
|
||||||
|
precision = TaskQueueBase::DelayPrecision::kHigh;
|
||||||
|
}
|
||||||
|
|
||||||
task_queue_.PostDelayedTaskWithPrecision(
|
task_queue_.PostDelayedTaskWithPrecision(
|
||||||
precision,
|
precision,
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "modules/pacing/pacing_controller.h"
|
#include "modules/pacing/pacing_controller.h"
|
||||||
#include "modules/pacing/rtp_packet_pacer.h"
|
#include "modules/pacing/rtp_packet_pacer.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
|
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/numerics/exp_filter.h"
|
#include "rtc_base/numerics/exp_filter.h"
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
#include "rtc_base/thread_annotations.h"
|
#include "rtc_base/thread_annotations.h"
|
||||||
@ -129,16 +130,24 @@ class TaskQueuePacedSender : public RtpPacketPacer, public RtpPacketSender {
|
|||||||
Stats GetStats() const;
|
Stats GetStats() const;
|
||||||
|
|
||||||
Clock* const clock_;
|
Clock* const clock_;
|
||||||
// If `kSlackedTaskQueuePacedSenderFieldTrial` is enabled, delayed tasks
|
struct SlackedPacerFlags {
|
||||||
// invoking MaybeProcessPackets() are scheduled using low precision instead of
|
// Parses `kSlackedTaskQueuePacedSenderFieldTrial`. Example:
|
||||||
// high precision, resulting in less idle wake ups and packets being sent in
|
// --force-fieldtrials=WebRTC-SlackedTaskQueuePacedSender/Enabled,max_queue_time:75ms/
|
||||||
// bursts if the `task_queue_` implementation supports slack.
|
explicit SlackedPacerFlags(const FieldTrialsView& field_trials);
|
||||||
//
|
// When "Enabled", delayed tasks invoking MaybeProcessPackets() are
|
||||||
// When probing, high precision is used regardless of `allow_low_precision_`
|
// scheduled using low precision instead of high precision, resulting in
|
||||||
// to ensure good bandwidth estimation.
|
// less idle wake ups and packets being sent in bursts if the `task_queue_`
|
||||||
const bool allow_low_precision_;
|
// implementation supports slack. When probing, high precision is used
|
||||||
|
// regardless to ensure good bandwidth estimation.
|
||||||
|
FieldTrialFlag allow_low_precision;
|
||||||
|
// Controlled via the "max_queue_time" experiment arm. If set, uses high
|
||||||
|
// precision scheduling of MaybeProcessPackets() whenever the expected queue
|
||||||
|
// time is greater than or equal to this value.
|
||||||
|
FieldTrialOptional<TimeDelta> max_low_precision_expected_queue_time;
|
||||||
|
};
|
||||||
|
const SlackedPacerFlags slacked_pacer_flags_;
|
||||||
// The holdback window prevents too frequent delayed MaybeProcessPackets()
|
// The holdback window prevents too frequent delayed MaybeProcessPackets()
|
||||||
// calls. These are only applicable if `allow_low_precision_` is false.
|
// calls. These are only applicable if `allow_low_precision` is false.
|
||||||
const TimeDelta max_hold_back_window_;
|
const TimeDelta max_hold_back_window_;
|
||||||
const int max_hold_back_window_in_packets_;
|
const int max_hold_back_window_in_packets_;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user