In RtpSenderVideo::UpdateConditionalRetransmit use typed time and framerate instead of plain ints
Bug: webrtc:13757
Change-Id: If2df5418dacd2b95387fa74a9bc226426b207aee
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/313041
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40483}
diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn
index 96c43bd..4a627e1 100644
--- a/modules/rtp_rtcp/BUILD.gn
+++ b/modules/rtp_rtcp/BUILD.gn
@@ -288,6 +288,7 @@
"../../api/transport/rtp:dependency_descriptor",
"../../api/transport/rtp:rtp_source",
"../../api/units:data_rate",
+ "../../api/units:frequency",
"../../api/units:time_delta",
"../../api/units:timestamp",
"../../api/video:encoded_frame",
@@ -313,6 +314,7 @@
"../../rtc_base:copy_on_write_buffer",
"../../rtc_base:divide_round",
"../../rtc_base:event_tracer",
+ "../../rtc_base:frequency_tracker",
"../../rtc_base:gtest_prod",
"../../rtc_base:logging",
"../../rtc_base:macromagic",
@@ -321,7 +323,6 @@
"../../rtc_base:race_checker",
"../../rtc_base:random",
"../../rtc_base:rate_limiter",
- "../../rtc_base:rate_statistics",
"../../rtc_base:rtc_numerics",
"../../rtc_base:safe_conversions",
"../../rtc_base:safe_minmax",
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 41aff18..f29c5ea 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -24,6 +24,9 @@
#include "absl/strings/match.h"
#include "api/crypto/frame_encryptor_interface.h"
#include "api/transport/rtp/dependency_descriptor.h"
+#include "api/units/frequency.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/absolute_capture_time_sender.h"
@@ -45,7 +48,8 @@
namespace {
constexpr size_t kRedForFecHeaderLength = 1;
-constexpr int64_t kMaxUnretransmittableFrameIntervalMs = 33 * 4;
+constexpr TimeDelta kMaxUnretransmittableFrameInterval =
+ TimeDelta::Millis(33 * 4);
void BuildRedPayload(const RtpPacketToSend& media_packet,
RtpPacketToSend* red_packet) {
@@ -781,8 +785,7 @@
MutexLock lock(&stats_mutex_);
// Media packet storage.
if ((retransmission_settings & kConditionallyRetransmitHigherLayers) &&
- UpdateConditionalRetransmit(temporal_id,
- expected_retransmission_time.ms())) {
+ UpdateConditionalRetransmit(temporal_id, expected_retransmission_time)) {
retransmission_settings |= kRetransmitHigherLayers;
}
@@ -815,39 +818,37 @@
bool RTPSenderVideo::UpdateConditionalRetransmit(
uint8_t temporal_id,
- int64_t expected_retransmission_time_ms) {
- int64_t now_ms = clock_->TimeInMilliseconds();
+ TimeDelta expected_retransmission_time) {
+ Timestamp now = clock_->CurrentTime();
// Update stats for any temporal layer.
TemporalLayerStats* current_layer_stats =
&frame_stats_by_temporal_layer_[temporal_id];
- current_layer_stats->frame_rate_fp1000s.Update(1, now_ms);
- int64_t tl_frame_interval = now_ms - current_layer_stats->last_frame_time_ms;
- current_layer_stats->last_frame_time_ms = now_ms;
+ current_layer_stats->frame_rate.Update(now);
+ TimeDelta tl_frame_interval = now - current_layer_stats->last_frame_time;
+ current_layer_stats->last_frame_time = now;
// Conditional retransmit only applies to upper layers.
if (temporal_id != kNoTemporalIdx && temporal_id > 0) {
- if (tl_frame_interval >= kMaxUnretransmittableFrameIntervalMs) {
+ if (tl_frame_interval >= kMaxUnretransmittableFrameInterval) {
// Too long since a retransmittable frame in this layer, enable NACK
// protection.
return true;
} else {
// Estimate when the next frame of any lower layer will be sent.
- const int64_t kUndefined = std::numeric_limits<int64_t>::max();
- int64_t expected_next_frame_time = kUndefined;
+ Timestamp expected_next_frame_time = Timestamp::PlusInfinity();
for (int i = temporal_id - 1; i >= 0; --i) {
TemporalLayerStats* stats = &frame_stats_by_temporal_layer_[i];
- absl::optional<uint32_t> rate = stats->frame_rate_fp1000s.Rate(now_ms);
- if (rate) {
- int64_t tl_next = stats->last_frame_time_ms + 1000000 / *rate;
- if (tl_next - now_ms > -expected_retransmission_time_ms &&
+ absl::optional<Frequency> rate = stats->frame_rate.Rate(now);
+ if (rate > Frequency::Zero()) {
+ Timestamp tl_next = stats->last_frame_time + 1 / *rate;
+ if (tl_next - now > -expected_retransmission_time &&
tl_next < expected_next_frame_time) {
expected_next_frame_time = tl_next;
}
}
}
- if (expected_next_frame_time == kUndefined ||
- expected_next_frame_time - now_ms > expected_retransmission_time_ms) {
+ if (expected_next_frame_time - now > expected_retransmission_time) {
// The next frame in a lower layer is expected at a later time (or
// unable to tell due to lack of data) than a retransmission is
// estimated to be able to arrive, so allow this packet to be nacked.
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index a9edc2d..acf4d94 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -24,6 +24,8 @@
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/transport/rtp/dependency_descriptor.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "api/video/video_codec_type.h"
#include "api/video/video_frame_type.h"
#include "api/video/video_layers_allocation.h"
@@ -36,9 +38,9 @@
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "modules/rtp_rtcp/source/video_fec_generator.h"
#include "rtc_base/bitrate_tracker.h"
+#include "rtc_base/frequency_tracker.h"
#include "rtc_base/one_time_event.h"
#include "rtc_base/race_checker.h"
-#include "rtc_base/rate_statistics.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"
@@ -62,7 +64,7 @@
class RTPSenderVideo : public RTPVideoFrameSenderInterface {
public:
- static constexpr int64_t kTLRateWindowSizeMs = 2500;
+ static constexpr TimeDelta kTLRateWindowSize = TimeDelta::Millis(2'500);
struct Config {
Config() = default;
@@ -154,14 +156,8 @@
private:
struct TemporalLayerStats {
- TemporalLayerStats()
- : frame_rate_fp1000s(kTLRateWindowSizeMs, 1000 * 1000),
- last_frame_time_ms(0) {}
- // Frame rate, in frames per 1000 seconds. This essentially turns the fps
- // value into a fixed point value with three decimals. Improves precision at
- // low frame rates.
- RateStatistics frame_rate_fp1000s;
- int64_t last_frame_time_ms;
+ FrequencyTracker frame_rate{kTLRateWindowSize};
+ Timestamp last_frame_time = Timestamp::Zero();
};
enum class SendVideoLayersAllocation {
@@ -189,7 +185,7 @@
bool red_enabled() const { return red_payload_type_.has_value(); }
bool UpdateConditionalRetransmit(uint8_t temporal_id,
- int64_t expected_retransmission_time_ms)
+ TimeDelta expected_retransmission_time)
RTC_EXCLUSIVE_LOCKS_REQUIRED(stats_mutex_);
void MaybeUpdateCurrentPlayoutDelay(const RTPVideoHeader& header)
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
index 8844b62..7ce96e0 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
@@ -414,8 +414,7 @@
// Fill averaging window to prevent rounding errors.
constexpr int kNumRepetitions =
- (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameInterval.ms() / 2)) /
- kFrameInterval.ms();
+ RTPSenderVideo::kTLRateWindowSize / kFrameInterval;
constexpr int kPattern[] = {0, 2, 1, 2};
auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
@@ -466,8 +465,7 @@
// Fill averaging window to prevent rounding errors.
constexpr int kNumRepetitions =
- (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameInterval.ms() / 2)) /
- kFrameInterval.ms();
+ RTPSenderVideo::kTLRateWindowSize / kFrameInterval;
constexpr int kPattern[] = {0, 2, 2, 2};
auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {