Refactor PlayoutDelayOracle with separate update methods

There's now one const method PlayoutDelayToSend to produce the delay
values to insert into outgoing packets, and two update methods,
OnSentPacket, and OnReceivedAck, to observe outgoing packets and acks,
respectively.

Bug: webrtc:7135
Change-Id: I07498c30f0de87ae0113f7e2eb6357a091a1f0af
Reviewed-on: https://webrtc-review.googlesource.com/c/120603
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26474}
This commit is contained in:
Niels Möller
2019-01-30 16:56:10 +01:00
committed by Commit Bot
parent fa89d84698
commit 71f94c93a6
4 changed files with 124 additions and 98 deletions

View File

@ -8,57 +8,82 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <algorithm>
#include "modules/rtp_rtcp/source/playout_delay_oracle.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
namespace webrtc {
PlayoutDelayOracle::PlayoutDelayOracle()
: high_sequence_number_(0),
send_playout_delay_(false),
ssrc_(0),
playout_delay_{-1, -1} {}
PlayoutDelayOracle::PlayoutDelayOracle() = default;
PlayoutDelayOracle::~PlayoutDelayOracle() {}
PlayoutDelayOracle::~PlayoutDelayOracle() = default;
void PlayoutDelayOracle::UpdateRequest(uint32_t ssrc,
PlayoutDelay playout_delay,
uint16_t seq_num) {
absl::optional<PlayoutDelay> PlayoutDelayOracle::PlayoutDelayToSend(
PlayoutDelay requested_delay) const {
rtc::CritScope lock(&crit_sect_);
RTC_DCHECK_LE(playout_delay.min_ms, PlayoutDelayLimits::kMaxMs);
RTC_DCHECK_LE(playout_delay.max_ms, PlayoutDelayLimits::kMaxMs);
RTC_DCHECK_LE(playout_delay.min_ms, playout_delay.max_ms);
int64_t unwrapped_seq_num = unwrapper_.Unwrap(seq_num);
if (playout_delay.min_ms >= 0 &&
playout_delay.min_ms != playout_delay_.min_ms) {
send_playout_delay_ = true;
playout_delay_.min_ms = playout_delay.min_ms;
high_sequence_number_ = unwrapped_seq_num;
if (requested_delay.min_ms > PlayoutDelayLimits::kMaxMs ||
requested_delay.max_ms > PlayoutDelayLimits::kMaxMs) {
RTC_DLOG(LS_ERROR)
<< "Requested playout delay values out of range, ignored";
return absl::nullopt;
}
if (requested_delay.max_ms != -1 &&
requested_delay.min_ms > requested_delay.max_ms) {
RTC_DLOG(LS_ERROR) << "Requested playout delay values out of order";
return absl::nullopt;
}
if ((requested_delay.min_ms == -1 ||
requested_delay.min_ms == latest_delay_.min_ms) &&
(requested_delay.max_ms == -1 ||
requested_delay.max_ms == latest_delay_.max_ms)) {
// Unchanged.
return unacked_sequence_number_ ? absl::make_optional(latest_delay_)
: absl::nullopt;
}
if (requested_delay.min_ms == -1) {
RTC_DCHECK_GE(requested_delay.max_ms, 0);
requested_delay.min_ms =
std::min(latest_delay_.min_ms, requested_delay.max_ms);
}
if (requested_delay.max_ms == -1) {
requested_delay.max_ms =
std::max(latest_delay_.max_ms, requested_delay.min_ms);
}
return requested_delay;
}
void PlayoutDelayOracle::OnSentPacket(uint16_t sequence_number,
absl::optional<PlayoutDelay> delay) {
rtc::CritScope lock(&crit_sect_);
int64_t unwrapped_sequence_number = unwrapper_.Unwrap(sequence_number);
if (!delay) {
return;
}
if (playout_delay.max_ms >= 0 &&
playout_delay.max_ms != playout_delay_.max_ms) {
send_playout_delay_ = true;
playout_delay_.max_ms = playout_delay.max_ms;
high_sequence_number_ = unwrapped_seq_num;
RTC_DCHECK_LE(0, delay->min_ms);
RTC_DCHECK_LE(delay->max_ms, PlayoutDelayLimits::kMaxMs);
RTC_DCHECK_LE(delay->min_ms, delay->max_ms);
if (delay->min_ms != latest_delay_.min_ms ||
delay->max_ms != latest_delay_.max_ms) {
latest_delay_ = *delay;
unacked_sequence_number_ = unwrapped_sequence_number;
}
ssrc_ = ssrc;
}
// If an ACK is received on the packet containing the playout delay extension,
// we stop sending the extension on future packets.
void PlayoutDelayOracle::OnReceivedRtcpReportBlocks(
const ReportBlockList& report_blocks) {
void PlayoutDelayOracle::OnReceivedAck(
int64_t extended_highest_sequence_number) {
rtc::CritScope lock(&crit_sect_);
for (const RTCPReportBlock& report_block : report_blocks) {
if ((ssrc_ == report_block.source_ssrc) && send_playout_delay_ &&
(report_block.extended_highest_sequence_number >
high_sequence_number_)) {
send_playout_delay_ = false;
}
if (unacked_sequence_number_ &&
extended_highest_sequence_number > *unacked_sequence_number_) {
unacked_sequence_number_ = absl::nullopt;
}
}