12#ifndef ROC_RTCP_HEADERS_H_
13#define ROC_RTCP_HEADERS_H_
32template <
typename T> T
get_bit_field(T v0,
const size_t shift,
const size_t mask) {
44void set_bit_field(T& v0,
const T v1,
const size_t shift,
const size_t mask) {
45 v0 &= T(~(mask << shift));
46 v0 |= T((v1 & mask) << shift);
54 return (uint16_t)x / 4 - 1;
66inline size_t padding_len(
const size_t size,
const size_t min_padding) {
67 const size_t size_to_pad = size + min_padding;
68 return min_padding + (size_to_pad & 0x03 ? 4 - (size_to_pad & 0x03) : 0);
72template <
class Blk,
class Pkt>
76 const char* pkt_type) {
77 if (block_index >= num_blocks) {
78 roc_panic(
"%s: out of bounds: index=%lu size=%lu", pkt_type,
79 (
unsigned long)block_index, (
unsigned long)num_blocks);
81 return ((Blk*)(
const_cast<char*
>((
const char*)pkt) +
sizeof(*pkt)))[block_index];
85static const size_t MaxPacketBlocks = 31;
88static const size_t MaxTextLen = 255;
205 set_bit_field(count_, (uint8_t)v, Padding_shift, Padding_mask);
338 FractLost_shift = 24,
340 FractLost_mask = 0xFF,
347 CumLoss_mask = 0xFFFFFF
366 ReceptionReportBlock() {
372 ssrc_ = losses_ = last_seq_ = jitter_ = 0;
373 last_sr_.set_value(0);
374 delay_last_sr_.set_value(0);
391 const uint8_t fract_loss8 =
394 return float(fract_loss8) / float(1 << FractLoss_width);
407 uint32_t fract_loss8 = (uint32_t)(
fract_loss *
float(1 << FractLoss_width));
408 if (fract_loss8 > 0xFF) {
426 if (
cum_loss & (1 << (CumLoss_width - 1))) {
428 cum_loss |= ~(uint32_t)CumLoss_mask;
439 }
else if (
cum_loss < -0x7FFFFF - 1) {
472 return last_sr_.value();
478 last_sr_.set_value(x);
483 return delay_last_sr_.value();
532 ReceiverReportPacket() {
564 return header_.counter();
627 uint32_t rtp_timestamp_;
628 uint32_t packet_cnt_;
632 SenderReportPacket() {
640 ntp_timestamp_.set_value(0);
668 return ntp_timestamp_.value();
673 ntp_timestamp_.set_value(t);
708 return header_.counter();
827 return (
const uint8_t*)
this +
sizeof(*this);
833 return (uint8_t*)
this +
sizeof(*this);
968 return (
const uint8_t*)
this +
sizeof(*this);
974 return (uint8_t*)
this +
sizeof(*this);
1102 uint8_t block_type_;
1103 uint8_t type_specific_;
1113 block_type_ = type_specific_ = 0;
1125 block_type_ = (uint8_t)bt;
1130 return type_specific_;
1189 ntp_timestamp_.set_value(0);
1204 return ntp_timestamp_.value();
1209 ntp_timestamp_.set_value(t);
1242 last_rr_.set_value(0);
1243 delay_last_rr_.set_value(0);
1258 return last_rr_.value();
1264 last_rr_.set_value(x);
1269 return delay_last_rr_.value();
1329 return (header_.len_bytes() -
sizeof(header_)) /
sizeof(
XrDlrrSubblock);
1379 uint16_t first_seq_;
1380 uint32_t interval_first_seq_;
1381 uint32_t interval_last_seq_;
1386 XrMeasurementInfoBlock() {
1396 interval_first_seq_ = interval_last_seq_ = 0;
1397 interval_duration_.set_value(0);
1398 cum_duration_.set_value(0);
1454 return interval_duration_.value();
1460 interval_duration_.set_value(
ntp_clamp_32(x, MaxDelay));
1466 return cum_duration_.value();
1471 cum_duration_.set_value(t);
1518 MetricFlag_shift = 6,
1519 MetricFlag_mask = 0x03,
1531 XrDelayMetricsBlock() {
1539 mean_rtt_.set_value(MetricUnavail_32);
1540 min_rtt_.set_value(MetricUnavail_32);
1541 max_rtt_.set_value(MetricUnavail_32);
1542 e2e_latency_.set_value(MetricUnavail_64);
1558 MetricFlag_shift, MetricFlag_mask);
1563 uint8_t t = header_.type_specific();
1565 header_.set_type_specific(t);
1580 return mean_rtt_.value() != MetricUnavail_32;
1585 return mean_rtt_.value();
1591 mean_rtt_.set_value(
ntp_clamp_32(x, MetricUnavail_32 - 1));
1596 return min_rtt_.value() != MetricUnavail_32;
1601 return min_rtt_.value();
1607 min_rtt_.set_value(
ntp_clamp_32(x, MetricUnavail_32 - 1));
1612 return max_rtt_.value() != MetricUnavail_32;
1617 return max_rtt_.value();
1623 max_rtt_.set_value(
ntp_clamp_32(x, MetricUnavail_32 - 1));
1628 return e2e_latency_.value() != MetricUnavail_64;
1633 return e2e_latency_.value();
1638 e2e_latency_.set_value(
ntp_clamp_64(t, MetricUnavail_64 - 1));
1671 MetricFlag_shift = 6,
1672 MetricFlag_mask = 0x03,
1682 XrQueueMetricsBlock() {
1690 niq_latency_.set_value(MetricUnavail_32);
1691 niq_stalling_.set_value(MetricUnavail_32);
1707 MetricFlag_shift, MetricFlag_mask);
1712 uint8_t t = header_.type_specific();
1714 header_.set_type_specific(t);
1729 return niq_latency_.value() != MetricUnavail_32;
1734 return niq_latency_.value();
1739 niq_latency_.set_value(
ntp_clamp_32(t, MetricUnavail_32 - 1));
1744 return niq_stalling_.value() != MetricUnavail_32;
1749 return niq_stalling_.value();
1754 niq_stalling_.set_value(
ntp_clamp_32(t, MetricUnavail_32 - 1));
#define ROC_ATTR_PACKED_BEGIN
Pack structure fields. Place these before class or struct keyword.
#define ROC_ATTR_PACKED_END
Pack structure fields. Place these between '}' and ';'.
Endian conversion functions.
uint16_t hton16u(uint16_t v)
Host to network byte order (unsigned 16-bit).
uint16_t ntoh16u(uint16_t v)
Network to host byte order (unsigned 16-bit).
uint32_t hton32u(uint32_t v)
Host to network byte order (unsigned 32-bit).
uint32_t ntoh32u(uint32_t v)
Network to host byte order (unsigned 32-bit).
uint32_t ext_seqnum_t
Extended sequence number.
uint32_t stream_source_t
Packet stream identifier.
uint16_t seqnum_t
Packet sequence number.
uint32_t stream_timestamp_t
Packet stream timestamp.
uint64_t ntp_timestamp_t
NTP timestamp.
packet::ntp_timestamp_t ntp_clamp_32(packet::ntp_timestamp_t value, packet::ntp_timestamp_t max_value)
Clamp 64-bit NTP timestamp so that it fits into middle 32-bits. Value is rounded to the new resolutio...
packet::ntp_timestamp_t ntp_clamp_64(packet::ntp_timestamp_t value, packet::ntp_timestamp_t max_value)
Clamp 64-bit NTP timestamp so that it does not exceed maximum.
#define roc_panic_if_not(x)
Panic if condition is false.
#define roc_panic_if(x)
Panic if condition is true.
#define roc_panic(...)
Print error message and terminate program gracefully.
Utitilies for NTP timestamp.
RTCP-specific NTP helpers.
Commonly used types and functions.
Various units used in packets.