1663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org/* 2663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * 4663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * Use of this source code is governed by a BSD-style license 5663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * that can be found in the LICENSE file in the root of the source 6663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * tree. An additional intellectual property rights grant can be found 7663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * in the file PATENTS. All contributing project authors may 8663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org */ 10663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 11663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" 12663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 13663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 1499681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 15663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 167eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgusing webrtc::RTCPUtility::kBtDlrr; 177eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgusing webrtc::RTCPUtility::kBtReceiverReferenceTime; 187eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgusing webrtc::RTCPUtility::kBtVoipMetric; 197eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 20847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::PT_APP; 21b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::PT_BYE; 22847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::PT_IJ; 23b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::PT_PSFB; 24b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::PT_RR; 25b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::PT_RTPFB; 26847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::PT_SDES; 27b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::PT_SR; 28847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::PT_XR; 29b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 30847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketAPP; 31b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketBYE; 32847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBAPP; 33b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBFIR; 34b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBFIRItem; 35847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBPLI; 36847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBREMBItem; 37b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBRPSI; 38847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBSLI; 39847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketPSFBSLIItem; 40b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketReportBlockItem; 41b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRR; 42b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRTPFBNACK; 43b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem; 44847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN; 45847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem; 46847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR; 47847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem; 48b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketSR; 49847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem; 50847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem; 51847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketXR; 52847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgusing webrtc::RTCPUtility::RTCPPacketXRVOIPMetricItem; 53b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 54663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgnamespace webrtc { 55663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgnamespace rtcp { 56663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgnamespace { 57b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// Unused SSRC of media source, set to 0. 58b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgconst uint32_t kUnusedMediaSourceSsrc0 = 0; 59b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 60847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) { 61663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org buffer[(*offset)++] = value; 62663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 63847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid AssignUWord16(uint8_t* buffer, size_t* offset, uint16_t value) { 646aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord16ToBuffer(buffer + *offset, value); 65663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org *offset += 2; 66663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 67847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid AssignUWord24(uint8_t* buffer, size_t* offset, uint32_t value) { 686aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord24ToBuffer(buffer + *offset, value); 69663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org *offset += 3; 70663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 71847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) { 726aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + *offset, value); 73663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org *offset += 4; 74663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 75663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 767eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid ComputeMantissaAnd6bitBase2Exponent(uint32_t input_base10, 777eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t bits_mantissa, 787eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t* mantissa, 797eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* exp) { 807eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org // input_base10 = mantissa * 2^exp 817eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org assert(bits_mantissa <= 32); 827eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t mantissa_max = (1 << bits_mantissa) - 1; 837eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t exponent = 0; 847eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (uint32_t i = 0; i < 64; ++i) { 857eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (input_base10 <= (mantissa_max << i)) { 867eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org exponent = i; 877eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org break; 887eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 897eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 907eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org *exp = exponent; 917eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org *mantissa = (input_base10 >> exponent); 927eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 937eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 94847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgsize_t BlockToHeaderLength(size_t length_in_bytes) { 95b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org // Length in 32-bit words minus 1. 96b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(length_in_bytes > 0); 97b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(length_in_bytes % 4 == 0); 98b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org return (length_in_bytes / 4) - 1; 99b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 100b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 101663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. 102663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 103b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// RTP header format. 104b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 0 1 2 3 105b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 106b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 107b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// |V=2|P| RC/FMT | PT | length | 108b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 109b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 110b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateHeader(uint8_t count_or_format, // Depends on packet type. 111b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t packet_type, 112847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 113b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t* buffer, 114847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 115847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org assert(length <= 0xffff); 116b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org const uint8_t kVersion = 2; 117b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord8(buffer, pos, (kVersion << 6) + count_or_format); 118b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord8(buffer, pos, packet_type); 119b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord16(buffer, pos, length); 120b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 121b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 122b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// Sender report (SR) (RFC 3550). 123663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 124663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 125663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 126663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// |V=2|P| RC | PT=SR=200 | length | 127663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 128663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC of sender | 129663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 130663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | NTP timestamp, most significant word | 131663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 132663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | NTP timestamp, least significant word | 133663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 134663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | RTP timestamp | 135663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 136663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | sender's packet count | 137663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 138663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | sender's octet count | 139663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 140663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 141b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateSenderReport(const RTCPPacketSR& sr, 142847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 143663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org uint8_t* buffer, 144847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 145b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org CreateHeader(sr.NumberOfReportBlocks, PT_SR, length, buffer, pos); 146663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, sr.SenderSSRC); 147663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, sr.NTPMostSignificant); 148663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, sr.NTPLeastSignificant); 149663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, sr.RTPTimestamp); 150663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, sr.SenderPacketCount); 151663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, sr.SenderOctetCount); 152663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 153663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 154b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// Receiver report (RR), header (RFC 3550). 155663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 156663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 157663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 158663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// |V=2|P| RC | PT=RR=201 | length | 159663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 160663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC of packet sender | 161663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 162663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 163b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateReceiverReport(const RTCPPacketRR& rr, 164847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 165663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org uint8_t* buffer, 166847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 167b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org CreateHeader(rr.NumberOfReportBlocks, PT_RR, length, buffer, pos); 168663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, rr.SenderSSRC); 169663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 170663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 171663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// Report block (RFC 3550). 172663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 173663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 174663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 175663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC_1 (SSRC of first source) | 176663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 177663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | fraction lost | cumulative number of packets lost | 178663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 179663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | extended highest sequence number received | 180663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 181663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | interarrival jitter | 182663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 183663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | last SR (LSR) | 184663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 185663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | delay since last SR (DLSR) | 186663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 187663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 188847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid CreateReportBlocks(const std::vector<RTCPPacketReportBlockItem>& blocks, 189847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint8_t* buffer, 190847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 191847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org for (std::vector<RTCPPacketReportBlockItem>::const_iterator 192847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org it = blocks.begin(); it != blocks.end(); ++it) { 193847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, (*it).SSRC); 194847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, (*it).FractionLost); 195847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord24(buffer, pos, (*it).CumulativeNumOfPacketsLost); 196847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, (*it).ExtendedHighestSequenceNumber); 197847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, (*it).Jitter); 198847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, (*it).LastSR); 199847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, (*it).DelayLastSR); 200847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 201847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 202847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 203847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// Transmission Time Offsets in RTP Streams (RFC 5450). 204847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 205847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 206847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 207847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 208847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// hdr |V=2|P| RC | PT=IJ=195 | length | 209847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 210847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | inter-arrival jitter | 211847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 212847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// . . 213847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// . . 214847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// . . 215847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | inter-arrival jitter | 216847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 217847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 218847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid CreateIj(const std::vector<uint32_t>& ij_items, 219847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint8_t* buffer, 220847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 221847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length = ij_items.size(); 222847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateHeader(length, PT_IJ, length, buffer, pos); 223847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org for (std::vector<uint32_t>::const_iterator it = ij_items.begin(); 224847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org it != ij_items.end(); ++it) { 225847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, *it); 226847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 227847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 228847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 229847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// Source Description (SDES) (RFC 3550). 230847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 231847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 232847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 233847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 234847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// header |V=2|P| SC | PT=SDES=202 | length | 235847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 236847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// chunk | SSRC/CSRC_1 | 237847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 238847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | SDES items | 239847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | ... | 240847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 241847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// chunk | SSRC/CSRC_2 | 242847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 243847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | SDES items | 244847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | ... | 245847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 246847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 247847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// Canonical End-Point Identifier SDES Item (CNAME) 248847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 249847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 250847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 251847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 252847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | CNAME=1 | length | user and domain name ... 253847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 254847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 255847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid CreateSdes(const std::vector<Sdes::Chunk>& chunks, 256847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 257847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint8_t* buffer, 258847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 259847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateHeader(chunks.size(), PT_SDES, length, buffer, pos); 260847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org const uint8_t kSdesItemType = 1; 261847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin(); 262847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org it != chunks.end(); ++it) { 263847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, (*it).ssrc); 264847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, kSdesItemType); 265847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, (*it).name.length()); 266847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org memcpy(buffer + *pos, (*it).name.data(), (*it).name.length()); 267847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org *pos += (*it).name.length(); 268847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org memset(buffer + *pos, 0, (*it).null_octets); 269847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org *pos += (*it).null_octets; 270847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 271663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 272663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 273663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// Bye packet (BYE) (RFC 3550). 274663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 275663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 276663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 277663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// |V=2|P| SC | PT=BYE=203 | length | 278663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 279663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC/CSRC | 280663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 281663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// : ... : 282663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 283663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// (opt) | length | reason for leaving ... 284663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 285663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 286b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateBye(const RTCPPacketBYE& bye, 287663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org const std::vector<uint32_t>& csrcs, 288847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 289663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org uint8_t* buffer, 290847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 291b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org CreateHeader(length, PT_BYE, length, buffer, pos); 292663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, bye.SenderSSRC); 293663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org for (std::vector<uint32_t>::const_iterator it = csrcs.begin(); 294663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org it != csrcs.end(); ++it) { 295663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, *it); 296663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 297663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 298663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 299847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// Application-Defined packet (APP) (RFC 3550). 300847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 301847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 302847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 303847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 304847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// |V=2|P| subtype | PT=APP=204 | length | 305847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 306847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | SSRC/CSRC | 307847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 308847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | name (ASCII) | 309847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 310847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | application-dependent data ... 311847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 312847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 313847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid CreateApp(const RTCPPacketAPP& app, 314847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint32_t ssrc, 315847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 316847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint8_t* buffer, 317847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 318847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateHeader(app.SubType, PT_APP, length, buffer, pos); 319847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, ssrc); 320847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, app.Name); 321847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org memcpy(buffer + *pos, app.Data, app.Size); 322847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org *pos += app.Size; 323847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 324847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 325663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// RFC 4585: Feedback format. 326663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 327663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// Common packet format: 328663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 329663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 330663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 331663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 332663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// |V=2|P| FMT | PT | length | 333663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 334663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC of packet sender | 335663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 336663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC of media source | 337663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 338663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// : Feedback Control Information (FCI) : 339663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// : 340663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 341b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 342847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// Picture loss indication (PLI) (RFC 4585). 343847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 344847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// FCI: no feedback control information. 345847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 346847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid CreatePli(const RTCPPacketPSFBPLI& pli, 347847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 348847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint8_t* buffer, 349847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 350847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org const uint8_t kFmt = 1; 351847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 352847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, pli.SenderSSRC); 353847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, pli.MediaSSRC); 354847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 355847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 356847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// Slice loss indication (SLI) (RFC 4585). 357847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 358847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// FCI: 359847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 360847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 361847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 362847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 363847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// | First | Number | PictureID | 364847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 365847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 366847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid CreateSli(const RTCPPacketPSFBSLI& sli, 367847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org const RTCPPacketPSFBSLIItem& sli_item, 368847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 369847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org uint8_t* buffer, 370847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 371847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org const uint8_t kFmt = 2; 372847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 373847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, sli.SenderSSRC); 374847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord32(buffer, pos, sli.MediaSSRC); 375847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 376847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); 377847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + 378847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org ((sli_item.NumberOfMB >> 10) & 0x07)); 379847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); 380847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); 381847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 382847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 383b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// Generic NACK (RFC 4585). 384b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 385b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// FCI: 386b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 387b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 0 1 2 3 388b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 389b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 390b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// | PID | BLP | 391b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 392b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 393b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateNack(const RTCPPacketRTPFBNACK& nack, 394b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields, 395847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 396b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t* buffer, 397847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 398b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org const uint8_t kFmt = 1; 399b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); 400b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord32(buffer, pos, nack.SenderSSRC); 401b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord32(buffer, pos, nack.MediaSSRC); 402b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org for (std::vector<RTCPPacketRTPFBNACKItem>::const_iterator 403b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org it = nack_fields.begin(); it != nack_fields.end(); ++it) { 404b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord16(buffer, pos, (*it).PacketID); 405b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord16(buffer, pos, (*it).BitMask); 406b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 407b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 408b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 409b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// Reference picture selection indication (RPSI) (RFC 4585). 410b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 411b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// FCI: 412b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 413b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 0 1 2 3 414b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 415b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 416b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// | PB |0| Payload Type| Native RPSI bit string | 417b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 418b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// | defined per codec ... | Padding (0) | 419b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 420b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 421b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateRpsi(const RTCPPacketPSFBRPSI& rpsi, 422b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t padding_bytes, 423847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 424b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t* buffer, 425847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 426b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org // Native bit string should be a multiple of 8 bits. 427b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(rpsi.NumberOfValidBits % 8 == 0); 428b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org const uint8_t kFmt = 3; 429b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 430b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord32(buffer, pos, rpsi.SenderSSRC); 431b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord32(buffer, pos, rpsi.MediaSSRC); 432b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord8(buffer, pos, padding_bytes * 8); 433b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord8(buffer, pos, rpsi.PayloadType); 434b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org memcpy(buffer + *pos, rpsi.NativeBitString, rpsi.NumberOfValidBits / 8); 435b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org *pos += rpsi.NumberOfValidBits / 8; 436b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org memset(buffer + *pos, 0, padding_bytes); 437b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org *pos += padding_bytes; 438b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 439b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 440663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// Full intra request (FIR) (RFC 5104). 441663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 442663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// FCI: 443663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 444663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 445663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 446663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 447663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | SSRC | 448663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 449663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// | Seq nr. | Reserved | 450663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 451663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 452b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid CreateFir(const RTCPPacketPSFBFIR& fir, 453b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org const RTCPPacketPSFBFIRItem& fir_item, 454847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length, 455b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t* buffer, 456847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* pos) { 457663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org const uint8_t kFmt = 4; 458b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 459663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, fir.SenderSSRC); 460b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 461663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord32(buffer, pos, fir_item.SSRC); 462663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord8(buffer, pos, fir_item.CommandSequenceNumber); 463663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org AssignUWord24(buffer, pos, 0); 464663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 4657eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 4667eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateTmmbrItem(const RTCPPacketRTPFBTMMBRItem& tmmbr_item, 4677eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 4687eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 4697eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t bitrate_bps = tmmbr_item.MaxTotalMediaBitRate * 1000; 4707eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t mantissa = 0; 4717eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t exp = 0; 4727eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org ComputeMantissaAnd6bitBase2Exponent(bitrate_bps, 17, &mantissa, &exp); 4737eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 4747eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, tmmbr_item.SSRC); 4757eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 15) & 0x03)); 4767eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, mantissa >> 7); 4777eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (mantissa << 1) + 4787eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org ((tmmbr_item.MeasuredOverhead >> 8) & 0x01)); 4797eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, tmmbr_item.MeasuredOverhead); 4807eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 4817eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 4827eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104). 4837eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 4847eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// FCI: 4857eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 4867eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4877eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 4887eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4897eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC | 4907eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4917eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 4927eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4937eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 4947eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr, 4957eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const RTCPPacketRTPFBTMMBRItem& tmmbr_item, 4967eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t length, 4977eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 4987eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 4997eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const uint8_t kFmt = 3; 5007eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); 5017eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, tmmbr.SenderSSRC); 5027eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 5037eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateTmmbrItem(tmmbr_item, buffer, pos); 5047eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 5057eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5067eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). 5077eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 5087eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// FCI: 5097eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 5107eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 5117eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 5127eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5137eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC | 5147eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5157eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 5167eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5177eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5187eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn, 5197eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items, 5207eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t length, 5217eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 5227eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 5237eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const uint8_t kFmt = 4; 5247eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); 5257eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, tmmbn.SenderSSRC); 5267eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 5277eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (uint8_t i = 0; i < tmmbn_items.size(); ++i) { 5287eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateTmmbrItem(tmmbn_items[i], buffer, pos); 5297eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 5307eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 5317eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5327eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). 5337eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 5347eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 5357eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 5367eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5377eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// |V=2|P| FMT=15 | PT=206 | length | 5387eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5397eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC of packet sender | 5407eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5417eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC of media source | 5427eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5437eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | Unique identifier 'R' 'E' 'M' 'B' | 5447eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5457eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | Num SSRC | BR Exp | BR Mantissa | 5467eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5477eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC feedback | 5487eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5497eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | ... | 5507eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5517eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateRemb(const RTCPPacketPSFBAPP& remb, 5527eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const RTCPPacketPSFBREMBItem& remb_item, 5537eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t length, 5547eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 5557eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 5567eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t mantissa = 0; 5577eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t exp = 0; 5587eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org ComputeMantissaAnd6bitBase2Exponent(remb_item.BitRate, 18, &mantissa, &exp); 5597eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5607eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const uint8_t kFmt = 15; 5617eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 5627eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, remb.SenderSSRC); 5637eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 5647eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, 'R'); 5657eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, 'E'); 5667eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, 'M'); 5677eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, 'B'); 5687eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, remb_item.NumberOfSSRCs); 5697eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 16) & 0x03)); 5707eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, mantissa >> 8); 5717eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, mantissa); 5727eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (uint8_t i = 0; i < remb_item.NumberOfSSRCs; ++i) { 5737eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, remb_item.SSRCs[i]); 5747eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 5757eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 5767eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5777eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR). 5787eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 5797eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// Format for XR packets: 5807eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 5817eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 5827eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 5837eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5847eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// |V=2|P|reserved | PT=XR=207 | length | 5857eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5867eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC | 5877eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5887eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// : report blocks : 5897eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5907eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5917eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateXrHeader(const RTCPPacketXR& header, 5927eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t length, 5937eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 5947eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 5957eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateHeader(0U, PT_XR, length, buffer, pos); 5967eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, header.OriginatorSSRC); 5977eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 5987eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 5997eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateXrBlockHeader(uint8_t block_type, 6007eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint16_t block_length, 6017eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 6027eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 6037eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, block_type); 6047eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, 0); 6057eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, block_length); 6067eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 6077eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 6087eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// Receiver Reference Time Report Block (RFC 3611). 6097eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 6107eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 6117eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 6127eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6137eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | BT=4 | reserved | block length = 2 | 6147eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6157eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | NTP timestamp, most significant word | 6167eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6177eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | NTP timestamp, least significant word | 6187eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6197eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 6207eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateRrtr(const std::vector<RTCPPacketXRReceiverReferenceTimeItem>& rrtrs, 6217eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 6227eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 6237eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const uint16_t kBlockLength = 2; 6247eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (std::vector<RTCPPacketXRReceiverReferenceTimeItem>::const_iterator it = 6257eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org rrtrs.begin(); it != rrtrs.end(); ++it) { 6267eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateXrBlockHeader(kBtReceiverReferenceTime, kBlockLength, buffer, pos); 6277eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, (*it).NTPMostSignificant); 6287eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, (*it).NTPLeastSignificant); 6297eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 6307eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 6317eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 6327eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// DLRR Report Block (RFC 3611). 6337eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 6347eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 6357eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 6367eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6377eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | BT=5 | reserved | block length | 6387eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 6397eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC_1 (SSRC of first receiver) | sub- 6407eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 6417eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | last RR (LRR) | 1 6427eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6437eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | delay since last RR (DLRR) | 6447eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 6457eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC_2 (SSRC of second receiver) | sub- 6467eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 6477eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// : ... : 2 6487eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 6497eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateDlrr(const std::vector<Xr::DlrrBlock>& dlrrs, 6507eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 6517eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 6527eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (std::vector<Xr::DlrrBlock>::const_iterator it = dlrrs.begin(); 6537eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org it != dlrrs.end(); ++it) { 6547eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if ((*it).empty()) { 6557eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org continue; 6567eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 6577eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint16_t block_length = 3 * (*it).size(); 6587eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateXrBlockHeader(kBtDlrr, block_length, buffer, pos); 6597eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (Xr::DlrrBlock::const_iterator it_block = (*it).begin(); 6607eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org it_block != (*it).end(); ++it_block) { 6617eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, (*it_block).SSRC); 6627eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, (*it_block).LastRR); 6637eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, (*it_block).DelayLastRR); 6647eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 6657eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 6667eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 6677eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 6687eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// VoIP Metrics Report Block (RFC 3611). 6697eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 6707eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 6717eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 6727eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6737eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | BT=7 | reserved | block length = 8 | 6747eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6757eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | SSRC of source | 6767eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6777eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | loss rate | discard rate | burst density | gap density | 6787eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6797eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | burst duration | gap duration | 6807eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6817eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | round trip delay | end system delay | 6827eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6837eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | signal level | noise level | RERL | Gmin | 6847eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6857eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | R factor | ext. R factor | MOS-LQ | MOS-CQ | 6867eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6877eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | RX config | reserved | JB nominal | 6887eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6897eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// | JB maximum | JB abs max | 6907eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6917eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 6927eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid CreateVoipMetric(const std::vector<RTCPPacketXRVOIPMetricItem>& metrics, 6937eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint8_t* buffer, 6947eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t* pos) { 6957eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const uint16_t kBlockLength = 8; 6967eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (std::vector<RTCPPacketXRVOIPMetricItem>::const_iterator it = 6977eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org metrics.begin(); it != metrics.end(); ++it) { 6987eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateXrBlockHeader(kBtVoipMetric, kBlockLength, buffer, pos); 6997eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord32(buffer, pos, (*it).SSRC); 7007eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).lossRate); 7017eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).discardRate); 7027eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).burstDensity); 7037eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).gapDensity); 7047eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).burstDuration); 7057eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).gapDuration); 7067eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).roundTripDelay); 7077eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).endSystemDelay); 7087eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).signalLevel); 7097eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).noiseLevel); 7107eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).RERL); 7117eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).Gmin); 7127eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).Rfactor); 7137eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).extRfactor); 7147eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).MOSLQ); 7157eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).MOSCQ); 7167eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, (*it).RXconfig); 7177eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord8(buffer, pos, 0); 7187eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).JBnominal); 7197eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).JBmax); 7207eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org AssignUWord16(buffer, pos, (*it).JBabsMax); 7217eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 7227eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 723663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} // namespace 724663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 725663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid RtcpPacket::Append(RtcpPacket* packet) { 726663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org assert(packet); 727663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org appended_packets_.push_back(packet); 728663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 729663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 730663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgRawPacket RtcpPacket::Build() const { 731847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length = 0; 732663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org uint8_t packet[IP_PACKET_SIZE]; 733847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateAndAddAppended(packet, &length, IP_PACKET_SIZE); 734847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return RawPacket(packet, length); 735663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 736663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 737847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid RtcpPacket::Build(uint8_t* packet, 738847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* length, 739847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t max_length) const { 740847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org *length = 0; 741847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateAndAddAppended(packet, length, max_length); 742663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 743663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 744663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid RtcpPacket::CreateAndAddAppended(uint8_t* packet, 745847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* length, 746847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t max_length) const { 747847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org Create(packet, length, max_length); 748663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org for (std::vector<RtcpPacket*>::const_iterator it = appended_packets_.begin(); 749663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org it != appended_packets_.end(); ++it) { 750847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org (*it)->CreateAndAddAppended(packet, length, max_length); 751663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 752663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 753663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 754847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Empty::Create(uint8_t* packet, size_t* length, size_t max_length) const { 755663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 756663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 757663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid SenderReport::Create(uint8_t* packet, 758847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* length, 759847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t max_length) const { 760847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 76199681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 762663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 763663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 764847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateSenderReport(sr_, BlockToHeaderLength(BlockLength()), packet, length); 765847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateReportBlocks(report_blocks_, packet, length); 766663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 767663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 768663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid SenderReport::WithReportBlock(ReportBlock* block) { 769663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org assert(block); 770663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { 77199681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max report blocks reached."; 772663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 773663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 774847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org report_blocks_.push_back(block->report_block_); 775663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org sr_.NumberOfReportBlocks = report_blocks_.size(); 776663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 777663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 778663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid ReceiverReport::Create(uint8_t* packet, 779847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t* length, 780847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t max_length) const { 781847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 78299681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 783663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 784663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 785847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, length); 786847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateReportBlocks(report_blocks_, packet, length); 787663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 788663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 789663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid ReceiverReport::WithReportBlock(ReportBlock* block) { 790663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org assert(block); 791663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { 79299681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max report blocks reached."; 793663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 794663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 795847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org report_blocks_.push_back(block->report_block_); 796663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org rr_.NumberOfReportBlocks = report_blocks_.size(); 797663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 798663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 799847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Ij::Create(uint8_t* packet, size_t* length, size_t max_length) const { 800847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 801847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 802847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 803847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 804847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateIj(ij_items_, packet, length); 805847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 806847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 807847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Ij::WithJitterItem(uint32_t jitter) { 808847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (ij_items_.size() >= kMaxNumberOfIjItems) { 809847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; 810847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 811847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 812847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org ij_items_.push_back(jitter); 813847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 814847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 815847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Sdes::Create(uint8_t* packet, size_t* length, size_t max_length) const { 816847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org assert(!chunks_.empty()); 817847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 818847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 819847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 820847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 821847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, length); 822847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 823847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 824847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Sdes::WithCName(uint32_t ssrc, std::string cname) { 825847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org assert(cname.length() <= 0xff); 826847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (chunks_.size() >= kMaxNumberOfChunks) { 827847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max SDES chunks reached."; 828847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 829847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 830847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org // In each chunk, the list of items must be terminated by one or more null 831847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org // octets. The next chunk must start on a 32-bit boundary. 832847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org // CNAME (1 byte) | length (1 byte) | name | padding. 833847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org int null_octets = 4 - ((2 + cname.length()) % 4); 834847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org Chunk chunk; 835847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org chunk.ssrc = ssrc; 836847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org chunk.name = cname; 837847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org chunk.null_octets = null_octets; 838847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org chunks_.push_back(chunk); 839b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 840b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 841847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgsize_t Sdes::BlockLength() const { 842847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org // Header (4 bytes). 843847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org // Chunk: 844847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org // SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding. 845847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org size_t length = kHeaderLength; 846847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org for (std::vector<Chunk>::const_iterator it = chunks_.begin(); 847847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org it != chunks_.end(); ++it) { 848847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org length += 6 + (*it).name.length() + (*it).null_octets; 849847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 850847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org assert(length % 4 == 0); 851847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return length; 852847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 853847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 854847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Bye::Create(uint8_t* packet, size_t* length, size_t max_length) const { 855847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 85699681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 857663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 858663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 859847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, length); 860663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 861663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 862663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.orgvoid Bye::WithCsrc(uint32_t csrc) { 863663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org if (csrcs_.size() >= kMaxNumberOfCsrcs) { 86499681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max CSRC size reached."; 865663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 866663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 867663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org csrcs_.push_back(csrc); 868663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 869663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 870847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid App::Create(uint8_t* packet, size_t* length, size_t max_length) const { 871847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 872847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 873847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 874847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 875847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, length); 876847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 877847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 878847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Pli::Create(uint8_t* packet, size_t* length, size_t max_length) const { 879847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 880847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 881847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 882847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 883847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, length); 884847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 885847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 886847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Sli::Create(uint8_t* packet, size_t* length, size_t max_length) const { 887847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 888847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 889847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org return; 890847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org } 891847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet, 892847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org length); 893847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org} 894847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org 895847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Nack::Create(uint8_t* packet, size_t* length, size_t max_length) const { 896b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(!nack_fields_.empty()); 897847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 89899681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 899663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org return; 900663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org } 901847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateNack(nack_, nack_fields_, BlockToHeaderLength(BlockLength()), packet, 902847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org length); 903663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 904663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org 905b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid Nack::WithList(const uint16_t* nack_list, int length) { 906b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(nack_list); 907b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(nack_fields_.empty()); 908b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org int i = 0; 909b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org while (i < length) { 910b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint16_t pid = nack_list[i++]; 911b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org // Bitmask specifies losses in any of the 16 packets following the pid. 912b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint16_t bitmask = 0; 913b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org while (i < length) { 914b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; 915b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org if (shift >= 0 && shift <= 15) { 916b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org bitmask |= (1 << shift); 917b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org ++i; 918b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } else { 919b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org break; 920b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 921b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 922b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org RTCPUtility::RTCPPacketRTPFBNACKItem item; 923b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org item.PacketID = pid; 924b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org item.BitMask = bitmask; 925b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org nack_fields_.push_back(item); 926b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 927b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 928b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 929847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Rpsi::Create(uint8_t* packet, size_t* length, size_t max_length) const { 930b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org assert(rpsi_.NumberOfValidBits > 0); 931847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 932b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 933b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org return; 934b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 935847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(BlockLength()), packet, 936847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org length); 937b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 938b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 939b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.orgvoid Rpsi::WithPictureId(uint64_t picture_id) { 940b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org const uint32_t kPidBits = 7; 941bad8a13a7532047cb53c4969a07506252e3a2aa5fbarchard@google.com const uint64_t k7MsbZeroMask = 0x1ffffffffffffffULL; 942b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint8_t required_bytes = 0; 943b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org uint64_t shifted_pid = picture_id; 944b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org do { 945b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org ++required_bytes; 946b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org shifted_pid = (shifted_pid >> kPidBits) & k7MsbZeroMask; 947b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } while (shifted_pid > 0); 948b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 949b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org // Convert picture id to native bit string (natively defined by the video 950b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org // codec). 951b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org int pos = 0; 952b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org for (int i = required_bytes - 1; i > 0; i--) { 953b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org rpsi_.NativeBitString[pos++] = 954b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 0x80 | static_cast<uint8_t>(picture_id >> (i * kPidBits)); 955b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 956b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org rpsi_.NativeBitString[pos++] = static_cast<uint8_t>(picture_id & 0x7f); 957b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org rpsi_.NumberOfValidBits = pos * 8; 958b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 959b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org // Calculate padding bytes (to reach next 32-bit boundary, 1, 2 or 3 bytes). 960b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org padding_bytes_ = 4 - ((2 + required_bytes) % 4); 961b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org if (padding_bytes_ == 4) { 962b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org padding_bytes_ = 0; 963b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 964b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org} 965b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org 966847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.orgvoid Fir::Create(uint8_t* packet, size_t* length, size_t max_length) const { 967847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org if (*length + BlockLength() > max_length) { 968b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 969b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org return; 970b5b864863573bcf0a341e6462fe697450c64a873asapersson@webrtc.org } 971847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet, 972847dfa535730a30d57cf26d788d31070b70a02afasapersson@webrtc.org length); 973663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} 9747eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 9757eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Remb::Create(uint8_t* packet, size_t* length, size_t max_length) const { 9767eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (*length + BlockLength() > max_length) { 9777eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 9787eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 9797eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 9807eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateRemb(remb_, remb_item_, BlockToHeaderLength(BlockLength()), packet, 9817eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org length); 9827eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 9837eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 9847eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Remb::AppliesTo(uint32_t ssrc) { 9857eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) { 9867eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached."; 9877eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 9887eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 9897eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; 9907eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 9917eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 9927eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Tmmbr::Create(uint8_t* packet, size_t* length, size_t max_length) const { 9937eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (*length + BlockLength() > max_length) { 9947eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 9957eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 9967eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 9977eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateTmmbr(tmmbr_, tmmbr_item_, BlockToHeaderLength(BlockLength()), packet, 9987eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org length); 9997eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10007eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10017eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { 10027eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org assert(overhead <= 0x1ff); 10037eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { 10047eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max TMMBN size reached."; 10057eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10067eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10077eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org RTCPPacketRTPFBTMMBRItem tmmbn_item; 10087eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org tmmbn_item.SSRC = ssrc; 10097eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; 10107eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org tmmbn_item.MeasuredOverhead = overhead; 10117eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org tmmbn_items_.push_back(tmmbn_item); 10127eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10137eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10147eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Tmmbn::Create(uint8_t* packet, size_t* length, size_t max_length) const { 10157eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (*length + BlockLength() > max_length) { 10167eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 10177eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10187eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10197eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateTmmbn(tmmbn_, tmmbn_items_, BlockToHeaderLength(BlockLength()), packet, 10207eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org length); 10217eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10227eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10237eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Xr::Create(uint8_t* packet, size_t* length, size_t max_length) const { 10247eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (*length + BlockLength() > max_length) { 10257eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max packet size reached."; 10267eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10277eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10287eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateXrHeader(xr_header_, BlockToHeaderLength(BlockLength()), packet, 10297eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org length); 10307eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateRrtr(rrtr_blocks_, packet, length); 10317eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateDlrr(dlrr_blocks_, packet, length); 10327eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org CreateVoipMetric(voip_metric_blocks_, packet, length); 10337eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10347eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10357eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Xr::WithRrtr(Rrtr* rrtr) { 10367eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org assert(rrtr); 10377eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { 10387eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max RRTR blocks reached."; 10397eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10407eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10417eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org rrtr_blocks_.push_back(rrtr->rrtr_block_); 10427eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10437eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10447eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Xr::WithDlrr(Dlrr* dlrr) { 10457eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org assert(dlrr); 10467eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (dlrr_blocks_.size() >= kMaxNumberOfDlrrBlocks) { 10477eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max DLRR blocks reached."; 10487eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10497eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10507eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org dlrr_blocks_.push_back(dlrr->dlrr_block_); 10517eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10527eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10537eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Xr::WithVoipMetric(VoipMetric* voip_metric) { 10547eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org assert(voip_metric); 10557eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (voip_metric_blocks_.size() >= kMaxNumberOfVoipMetricBlocks) { 10567eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max Voip Metric blocks reached."; 10577eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10587eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10597eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org voip_metric_blocks_.push_back(voip_metric->metric_); 10607eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10617eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10627eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgsize_t Xr::DlrrLength() const { 10637eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const size_t kBlockHeaderLen = 4; 10647eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org const size_t kSubBlockLen = 12; 10657eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org size_t length = 0; 10667eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org for (std::vector<DlrrBlock>::const_iterator it = dlrr_blocks_.begin(); 10677eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org it != dlrr_blocks_.end(); ++it) { 10687eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (!(*it).empty()) { 10697eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org length += kBlockHeaderLen + kSubBlockLen * (*it).size(); 10707eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10717eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10727eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return length; 10737eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10747eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 10757eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.orgvoid Dlrr::WithDlrrItem(uint32_t ssrc, 10767eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t last_rr, 10777eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org uint32_t delay_last_rr) { 10787eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org if (dlrr_block_.size() >= kMaxNumberOfDlrrItems) { 10797eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org LOG(LS_WARNING) << "Max DLRR items reached."; 10807eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org return; 10817eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org } 10827eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org RTCPPacketXRDLRRReportBlockItem dlrr; 10837eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org dlrr.SSRC = ssrc; 10847eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org dlrr.LastRR = last_rr; 10857eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org dlrr.DelayLastRR = delay_last_rr; 10867eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org dlrr_block_.push_back(dlrr); 10877eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org} 10887eec1dd08bce4d7a30d090c67a240c274b95755casapersson@webrtc.org 1089663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} // namespace rtcp 1090663ba07859170b985f47fb4ce8fd9af947e440efasapersson@webrtc.org} // namespace webrtc 1091