blob: ed06675b65a4d5bd4235d1ba6efeb7320ffdf3d3 [file]
/*
* Copyright (c) 2026 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 PC_CONGESTION_CONTROL_FEEDBACK_BLOCK_H_
#define PC_CONGESTION_CONTROL_FEEDBACK_BLOCK_H_
#include <cstddef>
#include <cstdint>
#include "api/transport/ecn_marking.h"
#include "api/units/time_delta.h"
namespace webrtc {
// Feedback block inside CongestionControlFeedbackReport (based on RFC 8888):
//
// 0 1
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |R|ECN| ATO |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// ATO is the arrival time of the packet, as an offset before the report
// timestamp of the enclosing report. R=0 means the packet was not received,
// in which case the other 15 bits are zero and MUST be ignored.
//
// This is pure bit manipulation: byte order and placement in a report are the
// caller's concern.
struct CongestionControlFeedbackBlock {
static constexpr size_t kBytes = 2;
// Ticks per second for the 13-bit ATO field. RFC 8888 puts the field in units
// of 1/1024 seconds: a precision of ~977 us, and a range whose ceiling is
// 8189/1024 = ~8.0 s, above which a measurement is over-range.
//
// TODO(crbug.com/443019066): consider letting the application choose the
// value of `ato_ticks_per_second`. Both peers must "agree" on it before it
// can differ from the default. A higher value improves precision but reduces
// the largest offset ATO can represent; a lower value does the opposite.
static constexpr int kDefaultAtoTicksPerSecond = 1024;
// The largest encodable measurement; the two codes above it are reserved.
// It is a property of the 13-bit field, so it holds for any tick rate.
static constexpr uint16_t kMaxAtoTicks = 0x1FFD;
static CongestionControlFeedbackBlock Decode(
uint16_t block,
int ato_ticks_per_second = kDefaultAtoTicksPerSecond);
uint16_t Encode(int ato_ticks_per_second = kDefaultAtoTicksPerSecond) const;
bool operator==(const CongestionControlFeedbackBlock& other) const = default;
// Stored rather than derived from `arrival_time_offset`, because an
// over-range or unavailable measurement is still a delivered packet.
bool received = false;
EcnMarking ecn = EcnMarking::kNotEct;
// Ignored unless `received`. PlusInfinity encodes an over-range measurement
// and MinusInfinity an unavailable one; both survive a round trip.
TimeDelta arrival_time_offset = TimeDelta::Zero();
};
} // namespace webrtc
#endif // PC_CONGESTION_CONTROL_FEEDBACK_BLOCK_H_