1 /* 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" 12 13 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 14 #include "webrtc/system_wrappers/interface/logging.h" 15 16 using webrtc::RTCPUtility::kBtDlrr; 17 using webrtc::RTCPUtility::kBtReceiverReferenceTime; 18 using webrtc::RTCPUtility::kBtVoipMetric; 19 20 using webrtc::RTCPUtility::PT_APP; 21 using webrtc::RTCPUtility::PT_BYE; 22 using webrtc::RTCPUtility::PT_IJ; 23 using webrtc::RTCPUtility::PT_PSFB; 24 using webrtc::RTCPUtility::PT_RR; 25 using webrtc::RTCPUtility::PT_RTPFB; 26 using webrtc::RTCPUtility::PT_SDES; 27 using webrtc::RTCPUtility::PT_SR; 28 using webrtc::RTCPUtility::PT_XR; 29 30 using webrtc::RTCPUtility::RTCPPacketAPP; 31 using webrtc::RTCPUtility::RTCPPacketBYE; 32 using webrtc::RTCPUtility::RTCPPacketPSFBAPP; 33 using webrtc::RTCPUtility::RTCPPacketPSFBFIR; 34 using webrtc::RTCPUtility::RTCPPacketPSFBFIRItem; 35 using webrtc::RTCPUtility::RTCPPacketPSFBPLI; 36 using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem; 37 using webrtc::RTCPUtility::RTCPPacketPSFBRPSI; 38 using webrtc::RTCPUtility::RTCPPacketPSFBSLI; 39 using webrtc::RTCPUtility::RTCPPacketPSFBSLIItem; 40 using webrtc::RTCPUtility::RTCPPacketReportBlockItem; 41 using webrtc::RTCPUtility::RTCPPacketRR; 42 using webrtc::RTCPUtility::RTCPPacketRTPFBNACK; 43 using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem; 44 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN; 45 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem; 46 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR; 47 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem; 48 using webrtc::RTCPUtility::RTCPPacketSR; 49 using webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem; 50 using webrtc::RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem; 51 using webrtc::RTCPUtility::RTCPPacketXR; 52 using webrtc::RTCPUtility::RTCPPacketXRVOIPMetricItem; 53 54 namespace webrtc { 55 namespace rtcp { 56 namespace { 57 // Unused SSRC of media source, set to 0. 58 const uint32_t kUnusedMediaSourceSsrc0 = 0; 59 60 void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) { 61 buffer[(*offset)++] = value; 62 } 63 void AssignUWord16(uint8_t* buffer, size_t* offset, uint16_t value) { 64 RtpUtility::AssignUWord16ToBuffer(buffer + *offset, value); 65 *offset += 2; 66 } 67 void AssignUWord24(uint8_t* buffer, size_t* offset, uint32_t value) { 68 RtpUtility::AssignUWord24ToBuffer(buffer + *offset, value); 69 *offset += 3; 70 } 71 void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) { 72 RtpUtility::AssignUWord32ToBuffer(buffer + *offset, value); 73 *offset += 4; 74 } 75 76 void ComputeMantissaAnd6bitBase2Exponent(uint32_t input_base10, 77 uint8_t bits_mantissa, 78 uint32_t* mantissa, 79 uint8_t* exp) { 80 // input_base10 = mantissa * 2^exp 81 assert(bits_mantissa <= 32); 82 uint32_t mantissa_max = (1 << bits_mantissa) - 1; 83 uint8_t exponent = 0; 84 for (uint32_t i = 0; i < 64; ++i) { 85 if (input_base10 <= (mantissa_max << i)) { 86 exponent = i; 87 break; 88 } 89 } 90 *exp = exponent; 91 *mantissa = (input_base10 >> exponent); 92 } 93 94 size_t BlockToHeaderLength(size_t length_in_bytes) { 95 // Length in 32-bit words minus 1. 96 assert(length_in_bytes > 0); 97 assert(length_in_bytes % 4 == 0); 98 return (length_in_bytes / 4) - 1; 99 } 100 101 // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. 102 // 103 // RTP header format. 104 // 0 1 2 3 105 // 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 106 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 107 // |V=2|P| RC/FMT | PT | length | 108 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 109 110 void CreateHeader(uint8_t count_or_format, // Depends on packet type. 111 uint8_t packet_type, 112 size_t length, 113 uint8_t* buffer, 114 size_t* pos) { 115 assert(length <= 0xffff); 116 const uint8_t kVersion = 2; 117 AssignUWord8(buffer, pos, (kVersion << 6) + count_or_format); 118 AssignUWord8(buffer, pos, packet_type); 119 AssignUWord16(buffer, pos, length); 120 } 121 122 // Sender report (SR) (RFC 3550). 123 // 0 1 2 3 124 // 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 125 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 126 // |V=2|P| RC | PT=SR=200 | length | 127 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 128 // | SSRC of sender | 129 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 130 // | NTP timestamp, most significant word | 131 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 132 // | NTP timestamp, least significant word | 133 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 134 // | RTP timestamp | 135 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 136 // | sender's packet count | 137 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 138 // | sender's octet count | 139 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 140 141 void CreateSenderReport(const RTCPPacketSR& sr, 142 size_t length, 143 uint8_t* buffer, 144 size_t* pos) { 145 CreateHeader(sr.NumberOfReportBlocks, PT_SR, length, buffer, pos); 146 AssignUWord32(buffer, pos, sr.SenderSSRC); 147 AssignUWord32(buffer, pos, sr.NTPMostSignificant); 148 AssignUWord32(buffer, pos, sr.NTPLeastSignificant); 149 AssignUWord32(buffer, pos, sr.RTPTimestamp); 150 AssignUWord32(buffer, pos, sr.SenderPacketCount); 151 AssignUWord32(buffer, pos, sr.SenderOctetCount); 152 } 153 154 // Receiver report (RR), header (RFC 3550). 155 // 156 // 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 157 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 158 // |V=2|P| RC | PT=RR=201 | length | 159 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 160 // | SSRC of packet sender | 161 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 162 163 void CreateReceiverReport(const RTCPPacketRR& rr, 164 size_t length, 165 uint8_t* buffer, 166 size_t* pos) { 167 CreateHeader(rr.NumberOfReportBlocks, PT_RR, length, buffer, pos); 168 AssignUWord32(buffer, pos, rr.SenderSSRC); 169 } 170 171 // Report block (RFC 3550). 172 // 173 // 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 174 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 175 // | SSRC_1 (SSRC of first source) | 176 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 177 // | fraction lost | cumulative number of packets lost | 178 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 179 // | extended highest sequence number received | 180 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 181 // | interarrival jitter | 182 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 183 // | last SR (LSR) | 184 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 185 // | delay since last SR (DLSR) | 186 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 187 188 void CreateReportBlocks(const std::vector<RTCPPacketReportBlockItem>& blocks, 189 uint8_t* buffer, 190 size_t* pos) { 191 for (std::vector<RTCPPacketReportBlockItem>::const_iterator 192 it = blocks.begin(); it != blocks.end(); ++it) { 193 AssignUWord32(buffer, pos, (*it).SSRC); 194 AssignUWord8(buffer, pos, (*it).FractionLost); 195 AssignUWord24(buffer, pos, (*it).CumulativeNumOfPacketsLost); 196 AssignUWord32(buffer, pos, (*it).ExtendedHighestSequenceNumber); 197 AssignUWord32(buffer, pos, (*it).Jitter); 198 AssignUWord32(buffer, pos, (*it).LastSR); 199 AssignUWord32(buffer, pos, (*it).DelayLastSR); 200 } 201 } 202 203 // Transmission Time Offsets in RTP Streams (RFC 5450). 204 // 205 // 0 1 2 3 206 // 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 207 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 208 // hdr |V=2|P| RC | PT=IJ=195 | length | 209 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 210 // | inter-arrival jitter | 211 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 212 // . . 213 // . . 214 // . . 215 // | inter-arrival jitter | 216 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 217 218 void CreateIj(const std::vector<uint32_t>& ij_items, 219 uint8_t* buffer, 220 size_t* pos) { 221 size_t length = ij_items.size(); 222 CreateHeader(length, PT_IJ, length, buffer, pos); 223 for (std::vector<uint32_t>::const_iterator it = ij_items.begin(); 224 it != ij_items.end(); ++it) { 225 AssignUWord32(buffer, pos, *it); 226 } 227 } 228 229 // Source Description (SDES) (RFC 3550). 230 // 231 // 0 1 2 3 232 // 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 233 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 234 // header |V=2|P| SC | PT=SDES=202 | length | 235 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 236 // chunk | SSRC/CSRC_1 | 237 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 238 // | SDES items | 239 // | ... | 240 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 241 // chunk | SSRC/CSRC_2 | 242 // 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 243 // | SDES items | 244 // | ... | 245 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 246 // 247 // Canonical End-Point Identifier SDES Item (CNAME) 248 // 249 // 0 1 2 3 250 // 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 251 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 252 // | CNAME=1 | length | user and domain name ... 253 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 254 255 void CreateSdes(const std::vector<Sdes::Chunk>& chunks, 256 size_t length, 257 uint8_t* buffer, 258 size_t* pos) { 259 CreateHeader(chunks.size(), PT_SDES, length, buffer, pos); 260 const uint8_t kSdesItemType = 1; 261 for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin(); 262 it != chunks.end(); ++it) { 263 AssignUWord32(buffer, pos, (*it).ssrc); 264 AssignUWord8(buffer, pos, kSdesItemType); 265 AssignUWord8(buffer, pos, (*it).name.length()); 266 memcpy(buffer + *pos, (*it).name.data(), (*it).name.length()); 267 *pos += (*it).name.length(); 268 memset(buffer + *pos, 0, (*it).null_octets); 269 *pos += (*it).null_octets; 270 } 271 } 272 273 // Bye packet (BYE) (RFC 3550). 274 // 275 // 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 276 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 277 // |V=2|P| SC | PT=BYE=203 | length | 278 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 279 // | SSRC/CSRC | 280 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 281 // : ... : 282 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 283 // (opt) | length | reason for leaving ... 284 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 285 286 void CreateBye(const RTCPPacketBYE& bye, 287 const std::vector<uint32_t>& csrcs, 288 size_t length, 289 uint8_t* buffer, 290 size_t* pos) { 291 CreateHeader(length, PT_BYE, length, buffer, pos); 292 AssignUWord32(buffer, pos, bye.SenderSSRC); 293 for (std::vector<uint32_t>::const_iterator it = csrcs.begin(); 294 it != csrcs.end(); ++it) { 295 AssignUWord32(buffer, pos, *it); 296 } 297 } 298 299 // Application-Defined packet (APP) (RFC 3550). 300 // 301 // 0 1 2 3 302 // 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 303 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 304 // |V=2|P| subtype | PT=APP=204 | length | 305 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 306 // | SSRC/CSRC | 307 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 308 // | name (ASCII) | 309 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 310 // | application-dependent data ... 311 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 312 313 void CreateApp(const RTCPPacketAPP& app, 314 uint32_t ssrc, 315 size_t length, 316 uint8_t* buffer, 317 size_t* pos) { 318 CreateHeader(app.SubType, PT_APP, length, buffer, pos); 319 AssignUWord32(buffer, pos, ssrc); 320 AssignUWord32(buffer, pos, app.Name); 321 memcpy(buffer + *pos, app.Data, app.Size); 322 *pos += app.Size; 323 } 324 325 // RFC 4585: Feedback format. 326 // 327 // Common packet format: 328 // 329 // 0 1 2 3 330 // 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 331 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 332 // |V=2|P| FMT | PT | length | 333 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 334 // | SSRC of packet sender | 335 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 336 // | SSRC of media source | 337 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 338 // : Feedback Control Information (FCI) : 339 // : 340 // 341 342 // Picture loss indication (PLI) (RFC 4585). 343 // 344 // FCI: no feedback control information. 345 346 void CreatePli(const RTCPPacketPSFBPLI& pli, 347 size_t length, 348 uint8_t* buffer, 349 size_t* pos) { 350 const uint8_t kFmt = 1; 351 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 352 AssignUWord32(buffer, pos, pli.SenderSSRC); 353 AssignUWord32(buffer, pos, pli.MediaSSRC); 354 } 355 356 // Slice loss indication (SLI) (RFC 4585). 357 // 358 // FCI: 359 // 360 // 0 1 2 3 361 // 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 362 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 363 // | First | Number | PictureID | 364 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 365 366 void CreateSli(const RTCPPacketPSFBSLI& sli, 367 const RTCPPacketPSFBSLIItem& sli_item, 368 size_t length, 369 uint8_t* buffer, 370 size_t* pos) { 371 const uint8_t kFmt = 2; 372 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 373 AssignUWord32(buffer, pos, sli.SenderSSRC); 374 AssignUWord32(buffer, pos, sli.MediaSSRC); 375 376 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); 377 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + 378 ((sli_item.NumberOfMB >> 10) & 0x07)); 379 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); 380 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); 381 } 382 383 // Generic NACK (RFC 4585). 384 // 385 // FCI: 386 // 387 // 0 1 2 3 388 // 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 389 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 390 // | PID | BLP | 391 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 392 393 void CreateNack(const RTCPPacketRTPFBNACK& nack, 394 const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields, 395 size_t length, 396 uint8_t* buffer, 397 size_t* pos) { 398 const uint8_t kFmt = 1; 399 CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); 400 AssignUWord32(buffer, pos, nack.SenderSSRC); 401 AssignUWord32(buffer, pos, nack.MediaSSRC); 402 for (std::vector<RTCPPacketRTPFBNACKItem>::const_iterator 403 it = nack_fields.begin(); it != nack_fields.end(); ++it) { 404 AssignUWord16(buffer, pos, (*it).PacketID); 405 AssignUWord16(buffer, pos, (*it).BitMask); 406 } 407 } 408 409 // Reference picture selection indication (RPSI) (RFC 4585). 410 // 411 // FCI: 412 // 413 // 0 1 2 3 414 // 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 415 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 416 // | PB |0| Payload Type| Native RPSI bit string | 417 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 418 // | defined per codec ... | Padding (0) | 419 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 420 421 void CreateRpsi(const RTCPPacketPSFBRPSI& rpsi, 422 uint8_t padding_bytes, 423 size_t length, 424 uint8_t* buffer, 425 size_t* pos) { 426 // Native bit string should be a multiple of 8 bits. 427 assert(rpsi.NumberOfValidBits % 8 == 0); 428 const uint8_t kFmt = 3; 429 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 430 AssignUWord32(buffer, pos, rpsi.SenderSSRC); 431 AssignUWord32(buffer, pos, rpsi.MediaSSRC); 432 AssignUWord8(buffer, pos, padding_bytes * 8); 433 AssignUWord8(buffer, pos, rpsi.PayloadType); 434 memcpy(buffer + *pos, rpsi.NativeBitString, rpsi.NumberOfValidBits / 8); 435 *pos += rpsi.NumberOfValidBits / 8; 436 memset(buffer + *pos, 0, padding_bytes); 437 *pos += padding_bytes; 438 } 439 440 // Full intra request (FIR) (RFC 5104). 441 // 442 // FCI: 443 // 444 // 0 1 2 3 445 // 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 446 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 447 // | SSRC | 448 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 449 // | Seq nr. | Reserved | 450 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 451 452 void CreateFir(const RTCPPacketPSFBFIR& fir, 453 const RTCPPacketPSFBFIRItem& fir_item, 454 size_t length, 455 uint8_t* buffer, 456 size_t* pos) { 457 const uint8_t kFmt = 4; 458 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 459 AssignUWord32(buffer, pos, fir.SenderSSRC); 460 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 461 AssignUWord32(buffer, pos, fir_item.SSRC); 462 AssignUWord8(buffer, pos, fir_item.CommandSequenceNumber); 463 AssignUWord24(buffer, pos, 0); 464 } 465 466 void CreateTmmbrItem(const RTCPPacketRTPFBTMMBRItem& tmmbr_item, 467 uint8_t* buffer, 468 size_t* pos) { 469 uint32_t bitrate_bps = tmmbr_item.MaxTotalMediaBitRate * 1000; 470 uint32_t mantissa = 0; 471 uint8_t exp = 0; 472 ComputeMantissaAnd6bitBase2Exponent(bitrate_bps, 17, &mantissa, &exp); 473 474 AssignUWord32(buffer, pos, tmmbr_item.SSRC); 475 AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 15) & 0x03)); 476 AssignUWord8(buffer, pos, mantissa >> 7); 477 AssignUWord8(buffer, pos, (mantissa << 1) + 478 ((tmmbr_item.MeasuredOverhead >> 8) & 0x01)); 479 AssignUWord8(buffer, pos, tmmbr_item.MeasuredOverhead); 480 } 481 482 // Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104). 483 // 484 // FCI: 485 // 486 // 0 1 2 3 487 // 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 488 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 489 // | SSRC | 490 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 491 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 492 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 493 494 void CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr, 495 const RTCPPacketRTPFBTMMBRItem& tmmbr_item, 496 size_t length, 497 uint8_t* buffer, 498 size_t* pos) { 499 const uint8_t kFmt = 3; 500 CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); 501 AssignUWord32(buffer, pos, tmmbr.SenderSSRC); 502 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 503 CreateTmmbrItem(tmmbr_item, buffer, pos); 504 } 505 506 // Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). 507 // 508 // FCI: 509 // 510 // 0 1 2 3 511 // 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 512 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 513 // | SSRC | 514 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 515 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 516 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 517 518 void CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn, 519 const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items, 520 size_t length, 521 uint8_t* buffer, 522 size_t* pos) { 523 const uint8_t kFmt = 4; 524 CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); 525 AssignUWord32(buffer, pos, tmmbn.SenderSSRC); 526 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 527 for (uint8_t i = 0; i < tmmbn_items.size(); ++i) { 528 CreateTmmbrItem(tmmbn_items[i], buffer, pos); 529 } 530 } 531 532 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). 533 // 534 // 0 1 2 3 535 // 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 536 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 537 // |V=2|P| FMT=15 | PT=206 | length | 538 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 539 // | SSRC of packet sender | 540 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 541 // | SSRC of media source | 542 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 543 // | Unique identifier 'R' 'E' 'M' 'B' | 544 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 545 // | Num SSRC | BR Exp | BR Mantissa | 546 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 547 // | SSRC feedback | 548 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 549 // | ... | 550 551 void CreateRemb(const RTCPPacketPSFBAPP& remb, 552 const RTCPPacketPSFBREMBItem& remb_item, 553 size_t length, 554 uint8_t* buffer, 555 size_t* pos) { 556 uint32_t mantissa = 0; 557 uint8_t exp = 0; 558 ComputeMantissaAnd6bitBase2Exponent(remb_item.BitRate, 18, &mantissa, &exp); 559 560 const uint8_t kFmt = 15; 561 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); 562 AssignUWord32(buffer, pos, remb.SenderSSRC); 563 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); 564 AssignUWord8(buffer, pos, 'R'); 565 AssignUWord8(buffer, pos, 'E'); 566 AssignUWord8(buffer, pos, 'M'); 567 AssignUWord8(buffer, pos, 'B'); 568 AssignUWord8(buffer, pos, remb_item.NumberOfSSRCs); 569 AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 16) & 0x03)); 570 AssignUWord8(buffer, pos, mantissa >> 8); 571 AssignUWord8(buffer, pos, mantissa); 572 for (uint8_t i = 0; i < remb_item.NumberOfSSRCs; ++i) { 573 AssignUWord32(buffer, pos, remb_item.SSRCs[i]); 574 } 575 } 576 577 // From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR). 578 // 579 // Format for XR packets: 580 // 581 // 0 1 2 3 582 // 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 583 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 584 // |V=2|P|reserved | PT=XR=207 | length | 585 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 586 // | SSRC | 587 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 588 // : report blocks : 589 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 590 591 void CreateXrHeader(const RTCPPacketXR& header, 592 size_t length, 593 uint8_t* buffer, 594 size_t* pos) { 595 CreateHeader(0U, PT_XR, length, buffer, pos); 596 AssignUWord32(buffer, pos, header.OriginatorSSRC); 597 } 598 599 void CreateXrBlockHeader(uint8_t block_type, 600 uint16_t block_length, 601 uint8_t* buffer, 602 size_t* pos) { 603 AssignUWord8(buffer, pos, block_type); 604 AssignUWord8(buffer, pos, 0); 605 AssignUWord16(buffer, pos, block_length); 606 } 607 608 // Receiver Reference Time Report Block (RFC 3611). 609 // 610 // 0 1 2 3 611 // 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 612 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 613 // | BT=4 | reserved | block length = 2 | 614 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 615 // | NTP timestamp, most significant word | 616 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 617 // | NTP timestamp, least significant word | 618 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 619 620 void CreateRrtr(const std::vector<RTCPPacketXRReceiverReferenceTimeItem>& rrtrs, 621 uint8_t* buffer, 622 size_t* pos) { 623 const uint16_t kBlockLength = 2; 624 for (std::vector<RTCPPacketXRReceiverReferenceTimeItem>::const_iterator it = 625 rrtrs.begin(); it != rrtrs.end(); ++it) { 626 CreateXrBlockHeader(kBtReceiverReferenceTime, kBlockLength, buffer, pos); 627 AssignUWord32(buffer, pos, (*it).NTPMostSignificant); 628 AssignUWord32(buffer, pos, (*it).NTPLeastSignificant); 629 } 630 } 631 632 // DLRR Report Block (RFC 3611). 633 // 634 // 0 1 2 3 635 // 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 636 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 637 // | BT=5 | reserved | block length | 638 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 639 // | SSRC_1 (SSRC of first receiver) | sub- 640 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 641 // | last RR (LRR) | 1 642 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 643 // | delay since last RR (DLRR) | 644 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 645 // | SSRC_2 (SSRC of second receiver) | sub- 646 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 647 // : ... : 2 648 649 void CreateDlrr(const std::vector<Xr::DlrrBlock>& dlrrs, 650 uint8_t* buffer, 651 size_t* pos) { 652 for (std::vector<Xr::DlrrBlock>::const_iterator it = dlrrs.begin(); 653 it != dlrrs.end(); ++it) { 654 if ((*it).empty()) { 655 continue; 656 } 657 uint16_t block_length = 3 * (*it).size(); 658 CreateXrBlockHeader(kBtDlrr, block_length, buffer, pos); 659 for (Xr::DlrrBlock::const_iterator it_block = (*it).begin(); 660 it_block != (*it).end(); ++it_block) { 661 AssignUWord32(buffer, pos, (*it_block).SSRC); 662 AssignUWord32(buffer, pos, (*it_block).LastRR); 663 AssignUWord32(buffer, pos, (*it_block).DelayLastRR); 664 } 665 } 666 } 667 668 // VoIP Metrics Report Block (RFC 3611). 669 // 670 // 0 1 2 3 671 // 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 672 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 673 // | BT=7 | reserved | block length = 8 | 674 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 675 // | SSRC of source | 676 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 677 // | loss rate | discard rate | burst density | gap density | 678 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 679 // | burst duration | gap duration | 680 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 681 // | round trip delay | end system delay | 682 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 683 // | signal level | noise level | RERL | Gmin | 684 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 685 // | R factor | ext. R factor | MOS-LQ | MOS-CQ | 686 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 687 // | RX config | reserved | JB nominal | 688 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 689 // | JB maximum | JB abs max | 690 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 691 692 void CreateVoipMetric(const std::vector<RTCPPacketXRVOIPMetricItem>& metrics, 693 uint8_t* buffer, 694 size_t* pos) { 695 const uint16_t kBlockLength = 8; 696 for (std::vector<RTCPPacketXRVOIPMetricItem>::const_iterator it = 697 metrics.begin(); it != metrics.end(); ++it) { 698 CreateXrBlockHeader(kBtVoipMetric, kBlockLength, buffer, pos); 699 AssignUWord32(buffer, pos, (*it).SSRC); 700 AssignUWord8(buffer, pos, (*it).lossRate); 701 AssignUWord8(buffer, pos, (*it).discardRate); 702 AssignUWord8(buffer, pos, (*it).burstDensity); 703 AssignUWord8(buffer, pos, (*it).gapDensity); 704 AssignUWord16(buffer, pos, (*it).burstDuration); 705 AssignUWord16(buffer, pos, (*it).gapDuration); 706 AssignUWord16(buffer, pos, (*it).roundTripDelay); 707 AssignUWord16(buffer, pos, (*it).endSystemDelay); 708 AssignUWord8(buffer, pos, (*it).signalLevel); 709 AssignUWord8(buffer, pos, (*it).noiseLevel); 710 AssignUWord8(buffer, pos, (*it).RERL); 711 AssignUWord8(buffer, pos, (*it).Gmin); 712 AssignUWord8(buffer, pos, (*it).Rfactor); 713 AssignUWord8(buffer, pos, (*it).extRfactor); 714 AssignUWord8(buffer, pos, (*it).MOSLQ); 715 AssignUWord8(buffer, pos, (*it).MOSCQ); 716 AssignUWord8(buffer, pos, (*it).RXconfig); 717 AssignUWord8(buffer, pos, 0); 718 AssignUWord16(buffer, pos, (*it).JBnominal); 719 AssignUWord16(buffer, pos, (*it).JBmax); 720 AssignUWord16(buffer, pos, (*it).JBabsMax); 721 } 722 } 723 } // namespace 724 725 void RtcpPacket::Append(RtcpPacket* packet) { 726 assert(packet); 727 appended_packets_.push_back(packet); 728 } 729 730 RawPacket RtcpPacket::Build() const { 731 size_t length = 0; 732 uint8_t packet[IP_PACKET_SIZE]; 733 CreateAndAddAppended(packet, &length, IP_PACKET_SIZE); 734 return RawPacket(packet, length); 735 } 736 737 void RtcpPacket::Build(uint8_t* packet, 738 size_t* length, 739 size_t max_length) const { 740 *length = 0; 741 CreateAndAddAppended(packet, length, max_length); 742 } 743 744 void RtcpPacket::CreateAndAddAppended(uint8_t* packet, 745 size_t* length, 746 size_t max_length) const { 747 Create(packet, length, max_length); 748 for (std::vector<RtcpPacket*>::const_iterator it = appended_packets_.begin(); 749 it != appended_packets_.end(); ++it) { 750 (*it)->CreateAndAddAppended(packet, length, max_length); 751 } 752 } 753 754 void Empty::Create(uint8_t* packet, size_t* length, size_t max_length) const { 755 } 756 757 void SenderReport::Create(uint8_t* packet, 758 size_t* length, 759 size_t max_length) const { 760 if (*length + BlockLength() > max_length) { 761 LOG(LS_WARNING) << "Max packet size reached."; 762 return; 763 } 764 CreateSenderReport(sr_, BlockToHeaderLength(BlockLength()), packet, length); 765 CreateReportBlocks(report_blocks_, packet, length); 766 } 767 768 void SenderReport::WithReportBlock(ReportBlock* block) { 769 assert(block); 770 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { 771 LOG(LS_WARNING) << "Max report blocks reached."; 772 return; 773 } 774 report_blocks_.push_back(block->report_block_); 775 sr_.NumberOfReportBlocks = report_blocks_.size(); 776 } 777 778 void ReceiverReport::Create(uint8_t* packet, 779 size_t* length, 780 size_t max_length) const { 781 if (*length + BlockLength() > max_length) { 782 LOG(LS_WARNING) << "Max packet size reached."; 783 return; 784 } 785 CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, length); 786 CreateReportBlocks(report_blocks_, packet, length); 787 } 788 789 void ReceiverReport::WithReportBlock(ReportBlock* block) { 790 assert(block); 791 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { 792 LOG(LS_WARNING) << "Max report blocks reached."; 793 return; 794 } 795 report_blocks_.push_back(block->report_block_); 796 rr_.NumberOfReportBlocks = report_blocks_.size(); 797 } 798 799 void Ij::Create(uint8_t* packet, size_t* length, size_t max_length) const { 800 if (*length + BlockLength() > max_length) { 801 LOG(LS_WARNING) << "Max packet size reached."; 802 return; 803 } 804 CreateIj(ij_items_, packet, length); 805 } 806 807 void Ij::WithJitterItem(uint32_t jitter) { 808 if (ij_items_.size() >= kMaxNumberOfIjItems) { 809 LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; 810 return; 811 } 812 ij_items_.push_back(jitter); 813 } 814 815 void Sdes::Create(uint8_t* packet, size_t* length, size_t max_length) const { 816 assert(!chunks_.empty()); 817 if (*length + BlockLength() > max_length) { 818 LOG(LS_WARNING) << "Max packet size reached."; 819 return; 820 } 821 CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, length); 822 } 823 824 void Sdes::WithCName(uint32_t ssrc, std::string cname) { 825 assert(cname.length() <= 0xff); 826 if (chunks_.size() >= kMaxNumberOfChunks) { 827 LOG(LS_WARNING) << "Max SDES chunks reached."; 828 return; 829 } 830 // In each chunk, the list of items must be terminated by one or more null 831 // octets. The next chunk must start on a 32-bit boundary. 832 // CNAME (1 byte) | length (1 byte) | name | padding. 833 int null_octets = 4 - ((2 + cname.length()) % 4); 834 Chunk chunk; 835 chunk.ssrc = ssrc; 836 chunk.name = cname; 837 chunk.null_octets = null_octets; 838 chunks_.push_back(chunk); 839 } 840 841 size_t Sdes::BlockLength() const { 842 // Header (4 bytes). 843 // Chunk: 844 // SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding. 845 size_t length = kHeaderLength; 846 for (std::vector<Chunk>::const_iterator it = chunks_.begin(); 847 it != chunks_.end(); ++it) { 848 length += 6 + (*it).name.length() + (*it).null_octets; 849 } 850 assert(length % 4 == 0); 851 return length; 852 } 853 854 void Bye::Create(uint8_t* packet, size_t* length, size_t max_length) const { 855 if (*length + BlockLength() > max_length) { 856 LOG(LS_WARNING) << "Max packet size reached."; 857 return; 858 } 859 CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, length); 860 } 861 862 void Bye::WithCsrc(uint32_t csrc) { 863 if (csrcs_.size() >= kMaxNumberOfCsrcs) { 864 LOG(LS_WARNING) << "Max CSRC size reached."; 865 return; 866 } 867 csrcs_.push_back(csrc); 868 } 869 870 void App::Create(uint8_t* packet, size_t* length, size_t max_length) const { 871 if (*length + BlockLength() > max_length) { 872 LOG(LS_WARNING) << "Max packet size reached."; 873 return; 874 } 875 CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, length); 876 } 877 878 void Pli::Create(uint8_t* packet, size_t* length, size_t max_length) const { 879 if (*length + BlockLength() > max_length) { 880 LOG(LS_WARNING) << "Max packet size reached."; 881 return; 882 } 883 CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, length); 884 } 885 886 void Sli::Create(uint8_t* packet, size_t* length, size_t max_length) const { 887 if (*length + BlockLength() > max_length) { 888 LOG(LS_WARNING) << "Max packet size reached."; 889 return; 890 } 891 CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet, 892 length); 893 } 894 895 void Nack::Create(uint8_t* packet, size_t* length, size_t max_length) const { 896 assert(!nack_fields_.empty()); 897 if (*length + BlockLength() > max_length) { 898 LOG(LS_WARNING) << "Max packet size reached."; 899 return; 900 } 901 CreateNack(nack_, nack_fields_, BlockToHeaderLength(BlockLength()), packet, 902 length); 903 } 904 905 void Nack::WithList(const uint16_t* nack_list, int length) { 906 assert(nack_list); 907 assert(nack_fields_.empty()); 908 int i = 0; 909 while (i < length) { 910 uint16_t pid = nack_list[i++]; 911 // Bitmask specifies losses in any of the 16 packets following the pid. 912 uint16_t bitmask = 0; 913 while (i < length) { 914 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; 915 if (shift >= 0 && shift <= 15) { 916 bitmask |= (1 << shift); 917 ++i; 918 } else { 919 break; 920 } 921 } 922 RTCPUtility::RTCPPacketRTPFBNACKItem item; 923 item.PacketID = pid; 924 item.BitMask = bitmask; 925 nack_fields_.push_back(item); 926 } 927 } 928 929 void Rpsi::Create(uint8_t* packet, size_t* length, size_t max_length) const { 930 assert(rpsi_.NumberOfValidBits > 0); 931 if (*length + BlockLength() > max_length) { 932 LOG(LS_WARNING) << "Max packet size reached."; 933 return; 934 } 935 CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(BlockLength()), packet, 936 length); 937 } 938 939 void Rpsi::WithPictureId(uint64_t picture_id) { 940 const uint32_t kPidBits = 7; 941 const uint64_t k7MsbZeroMask = 0x1ffffffffffffffULL; 942 uint8_t required_bytes = 0; 943 uint64_t shifted_pid = picture_id; 944 do { 945 ++required_bytes; 946 shifted_pid = (shifted_pid >> kPidBits) & k7MsbZeroMask; 947 } while (shifted_pid > 0); 948 949 // Convert picture id to native bit string (natively defined by the video 950 // codec). 951 int pos = 0; 952 for (int i = required_bytes - 1; i > 0; i--) { 953 rpsi_.NativeBitString[pos++] = 954 0x80 | static_cast<uint8_t>(picture_id >> (i * kPidBits)); 955 } 956 rpsi_.NativeBitString[pos++] = static_cast<uint8_t>(picture_id & 0x7f); 957 rpsi_.NumberOfValidBits = pos * 8; 958 959 // Calculate padding bytes (to reach next 32-bit boundary, 1, 2 or 3 bytes). 960 padding_bytes_ = 4 - ((2 + required_bytes) % 4); 961 if (padding_bytes_ == 4) { 962 padding_bytes_ = 0; 963 } 964 } 965 966 void Fir::Create(uint8_t* packet, size_t* length, size_t max_length) const { 967 if (*length + BlockLength() > max_length) { 968 LOG(LS_WARNING) << "Max packet size reached."; 969 return; 970 } 971 CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet, 972 length); 973 } 974 975 void Remb::Create(uint8_t* packet, size_t* length, size_t max_length) const { 976 if (*length + BlockLength() > max_length) { 977 LOG(LS_WARNING) << "Max packet size reached."; 978 return; 979 } 980 CreateRemb(remb_, remb_item_, BlockToHeaderLength(BlockLength()), packet, 981 length); 982 } 983 984 void Remb::AppliesTo(uint32_t ssrc) { 985 if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) { 986 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached."; 987 return; 988 } 989 remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; 990 } 991 992 void Tmmbr::Create(uint8_t* packet, size_t* length, size_t max_length) const { 993 if (*length + BlockLength() > max_length) { 994 LOG(LS_WARNING) << "Max packet size reached."; 995 return; 996 } 997 CreateTmmbr(tmmbr_, tmmbr_item_, BlockToHeaderLength(BlockLength()), packet, 998 length); 999 } 1000 1001 void Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { 1002 assert(overhead <= 0x1ff); 1003 if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { 1004 LOG(LS_WARNING) << "Max TMMBN size reached."; 1005 return; 1006 } 1007 RTCPPacketRTPFBTMMBRItem tmmbn_item; 1008 tmmbn_item.SSRC = ssrc; 1009 tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; 1010 tmmbn_item.MeasuredOverhead = overhead; 1011 tmmbn_items_.push_back(tmmbn_item); 1012 } 1013 1014 void Tmmbn::Create(uint8_t* packet, size_t* length, size_t max_length) const { 1015 if (*length + BlockLength() > max_length) { 1016 LOG(LS_WARNING) << "Max packet size reached."; 1017 return; 1018 } 1019 CreateTmmbn(tmmbn_, tmmbn_items_, BlockToHeaderLength(BlockLength()), packet, 1020 length); 1021 } 1022 1023 void Xr::Create(uint8_t* packet, size_t* length, size_t max_length) const { 1024 if (*length + BlockLength() > max_length) { 1025 LOG(LS_WARNING) << "Max packet size reached."; 1026 return; 1027 } 1028 CreateXrHeader(xr_header_, BlockToHeaderLength(BlockLength()), packet, 1029 length); 1030 CreateRrtr(rrtr_blocks_, packet, length); 1031 CreateDlrr(dlrr_blocks_, packet, length); 1032 CreateVoipMetric(voip_metric_blocks_, packet, length); 1033 } 1034 1035 void Xr::WithRrtr(Rrtr* rrtr) { 1036 assert(rrtr); 1037 if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { 1038 LOG(LS_WARNING) << "Max RRTR blocks reached."; 1039 return; 1040 } 1041 rrtr_blocks_.push_back(rrtr->rrtr_block_); 1042 } 1043 1044 void Xr::WithDlrr(Dlrr* dlrr) { 1045 assert(dlrr); 1046 if (dlrr_blocks_.size() >= kMaxNumberOfDlrrBlocks) { 1047 LOG(LS_WARNING) << "Max DLRR blocks reached."; 1048 return; 1049 } 1050 dlrr_blocks_.push_back(dlrr->dlrr_block_); 1051 } 1052 1053 void Xr::WithVoipMetric(VoipMetric* voip_metric) { 1054 assert(voip_metric); 1055 if (voip_metric_blocks_.size() >= kMaxNumberOfVoipMetricBlocks) { 1056 LOG(LS_WARNING) << "Max Voip Metric blocks reached."; 1057 return; 1058 } 1059 voip_metric_blocks_.push_back(voip_metric->metric_); 1060 } 1061 1062 size_t Xr::DlrrLength() const { 1063 const size_t kBlockHeaderLen = 4; 1064 const size_t kSubBlockLen = 12; 1065 size_t length = 0; 1066 for (std::vector<DlrrBlock>::const_iterator it = dlrr_blocks_.begin(); 1067 it != dlrr_blocks_.end(); ++it) { 1068 if (!(*it).empty()) { 1069 length += kBlockHeaderLen + kSubBlockLen * (*it).size(); 1070 } 1071 } 1072 return length; 1073 } 1074 1075 void Dlrr::WithDlrrItem(uint32_t ssrc, 1076 uint32_t last_rr, 1077 uint32_t delay_last_rr) { 1078 if (dlrr_block_.size() >= kMaxNumberOfDlrrItems) { 1079 LOG(LS_WARNING) << "Max DLRR items reached."; 1080 return; 1081 } 1082 RTCPPacketXRDLRRReportBlockItem dlrr; 1083 dlrr.SSRC = ssrc; 1084 dlrr.LastRR = last_rr; 1085 dlrr.DelayLastRR = delay_last_rr; 1086 dlrr_block_.push_back(dlrr); 1087 } 1088 1089 } // namespace rtcp 1090 } // namespace webrtc 1091