2013-01-29 12:09:21 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2012 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/audio_coding/neteq/delay_manager.h"
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2018-10-23 12:03:01 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
2019-07-05 19:08:33 +02:00
|
|
|
|
2018-10-23 12:03:01 +02:00
|
|
|
#include <algorithm>
|
2019-09-17 17:06:18 +02:00
|
|
|
#include <memory>
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2024-08-13 15:28:50 +02:00
|
|
|
#include "api/field_trials_view.h"
|
2024-10-07 13:02:08 +00:00
|
|
|
#include "api/neteq/tick_timer.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/reorder_optimizer.h"
|
2021-11-09 12:58:45 +01:00
|
|
|
#include "rtc_base/experiments/struct_parameters_parser.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/logging.h"
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2020-10-09 13:41:06 +02:00
|
|
|
namespace webrtc {
|
2018-10-04 11:31:03 +02:00
|
|
|
namespace {
|
|
|
|
|
|
2020-10-09 13:41:06 +02:00
|
|
|
constexpr int kStartDelayMs = 80;
|
2019-02-27 10:08:09 +01:00
|
|
|
|
2021-09-08 16:35:50 +02:00
|
|
|
std::unique_ptr<ReorderOptimizer> MaybeCreateReorderOptimizer(
|
|
|
|
|
const DelayManager::Config& config) {
|
|
|
|
|
if (!config.use_reorder_optimizer) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return std::make_unique<ReorderOptimizer>(
|
|
|
|
|
(1 << 15) * config.reorder_forget_factor, config.ms_per_loss_percent,
|
|
|
|
|
config.start_forget_weight);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-07 14:24:56 +02:00
|
|
|
} // namespace
|
2019-02-27 10:08:09 +01:00
|
|
|
|
2024-08-13 15:28:50 +02:00
|
|
|
DelayManager::Config::Config(const FieldTrialsView& field_trials) {
|
2021-11-09 12:58:45 +01:00
|
|
|
StructParametersParser::Create( //
|
|
|
|
|
"quantile", &quantile, //
|
|
|
|
|
"forget_factor", &forget_factor, //
|
|
|
|
|
"start_forget_weight", &start_forget_weight, //
|
|
|
|
|
"resample_interval_ms", &resample_interval_ms, //
|
|
|
|
|
"use_reorder_optimizer", &use_reorder_optimizer, //
|
|
|
|
|
"reorder_forget_factor", &reorder_forget_factor, //
|
|
|
|
|
"ms_per_loss_percent", &ms_per_loss_percent)
|
2024-08-13 15:28:50 +02:00
|
|
|
->Parse(field_trials.Lookup("WebRTC-Audio-NetEqDelayManagerConfig"));
|
2021-09-07 14:24:56 +02:00
|
|
|
}
|
2020-11-11 15:26:10 +01:00
|
|
|
|
2021-09-07 14:24:56 +02:00
|
|
|
void DelayManager::Config::Log() {
|
|
|
|
|
RTC_LOG(LS_INFO) << "Delay manager config:"
|
|
|
|
|
" quantile="
|
|
|
|
|
<< quantile << " forget_factor=" << forget_factor
|
|
|
|
|
<< " start_forget_weight=" << start_forget_weight.value_or(0)
|
|
|
|
|
<< " resample_interval_ms="
|
|
|
|
|
<< resample_interval_ms.value_or(0)
|
2021-09-08 16:35:50 +02:00
|
|
|
<< " use_reorder_optimizer=" << use_reorder_optimizer
|
|
|
|
|
<< " reorder_forget_factor=" << reorder_forget_factor
|
|
|
|
|
<< " ms_per_loss_percent=" << ms_per_loss_percent;
|
2021-09-07 14:24:56 +02:00
|
|
|
}
|
2019-02-27 10:08:09 +01:00
|
|
|
|
2021-09-07 14:24:56 +02:00
|
|
|
DelayManager::DelayManager(const Config& config, const TickTimer* tick_timer)
|
2024-10-07 13:02:08 +00:00
|
|
|
: underrun_optimizer_(tick_timer,
|
2021-09-07 14:24:56 +02:00
|
|
|
(1 << 30) * config.quantile,
|
|
|
|
|
(1 << 15) * config.forget_factor,
|
|
|
|
|
config.start_forget_weight,
|
|
|
|
|
config.resample_interval_ms),
|
2021-09-08 16:35:50 +02:00
|
|
|
reorder_optimizer_(MaybeCreateReorderOptimizer(config)),
|
2021-08-30 18:13:18 +02:00
|
|
|
target_level_ms_(kStartDelayMs) {
|
2013-01-29 12:09:21 +00:00
|
|
|
Reset();
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-21 15:42:31 +01:00
|
|
|
DelayManager::~DelayManager() {}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2022-05-25 21:06:14 +02:00
|
|
|
void DelayManager::Update(int arrival_delay_ms, bool reordered) {
|
2021-09-08 16:35:50 +02:00
|
|
|
if (!reorder_optimizer_ || !reordered) {
|
2022-05-25 21:06:14 +02:00
|
|
|
underrun_optimizer_.Update(arrival_delay_ms);
|
2021-09-08 16:35:50 +02:00
|
|
|
}
|
2021-09-07 14:24:56 +02:00
|
|
|
target_level_ms_ =
|
|
|
|
|
underrun_optimizer_.GetOptimalDelayMs().value_or(kStartDelayMs);
|
2021-09-08 16:35:50 +02:00
|
|
|
if (reorder_optimizer_) {
|
2022-05-25 21:06:14 +02:00
|
|
|
reorder_optimizer_->Update(arrival_delay_ms, reordered, target_level_ms_);
|
2021-09-08 16:35:50 +02:00
|
|
|
target_level_ms_ = std::max(
|
|
|
|
|
target_level_ms_, reorder_optimizer_->GetOptimalDelayMs().value_or(0));
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DelayManager::Reset() {
|
2021-09-07 14:24:56 +02:00
|
|
|
underrun_optimizer_.Reset();
|
2020-10-09 13:41:06 +02:00
|
|
|
target_level_ms_ = kStartDelayMs;
|
2021-09-08 16:35:50 +02:00
|
|
|
if (reorder_optimizer_) {
|
|
|
|
|
reorder_optimizer_->Reset();
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-09 13:41:06 +02:00
|
|
|
int DelayManager::TargetDelayMs() const {
|
|
|
|
|
return target_level_ms_;
|
Handle padded audio packets correctly
RTP packets can be padded with extra data at the end of the payload. The usable
payload length of the packet should then be reduced with the padding length,
since the padding must be discarded. This was not the case; instead, the entire
payload, including padding data, was forwarded to the audio channel and in the
end to the decoder.
A special case of padding is packets which are empty except for the padding.
That is, they carry no usable payload. These packets are sometimes used for
probing the network and were discarded in
RTPReceiverAudio::ParseAudioCodecSpecific. The result is that NetEq never sees
those empty packets, just the holes in the sequence number series; this can
throw off the target buffer calculations.
With this change, the empty (after removing the padding) packets are let through,
all the way down to NetEq, to a new method called NetEq::InsertEmptyPacket. This
method notifies the DelayManager that an empty packet was received.
BUG=webrtc:7610, webrtc:7625
Review-Url: https://codereview.webrtc.org/2870043003
Cr-Commit-Position: refs/heads/master@{#18083}
2017-05-10 07:38:01 -07:00
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
} // namespace webrtc
|