| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 for (uint32_t i = 0; i < 64; ++i) { | 85 for (uint32_t i = 0; i < 64; ++i) { |
| 86 if (input_base10 <= (mantissa_max << i)) { | 86 if (input_base10 <= (mantissa_max << i)) { |
| 87 exponent = i; | 87 exponent = i; |
| 88 break; | 88 break; |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 *exp = exponent; | 91 *exp = exponent; |
| 92 *mantissa = (input_base10 >> exponent); | 92 *mantissa = (input_base10 >> exponent); |
| 93 } | 93 } |
| 94 | 94 |
| 95 size_t BlockToHeaderLength(size_t length_in_bytes) { | |
| 96 // Length in 32-bit words minus 1. | |
| 97 assert(length_in_bytes > 0); | |
| 98 assert(length_in_bytes % 4 == 0); | |
| 99 return (length_in_bytes / 4) - 1; | |
| 100 } | |
| 101 | |
| 102 // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. | |
| 103 // | |
| 104 // RTP header format. | |
| 105 // 0 1 2 3 | |
| 106 // 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 | |
| 107 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 108 // |V=2|P| RC/FMT | PT | length | | |
| 109 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 110 | |
| 111 void CreateHeader(uint8_t count_or_format, // Depends on packet type. | |
| 112 uint8_t packet_type, | |
| 113 size_t length, | |
| 114 uint8_t* buffer, | |
| 115 size_t* pos) { | |
| 116 assert(length <= 0xffff); | |
| 117 const uint8_t kVersion = 2; | |
| 118 AssignUWord8(buffer, pos, (kVersion << 6) + count_or_format); | |
| 119 AssignUWord8(buffer, pos, packet_type); | |
| 120 AssignUWord16(buffer, pos, length); | |
| 121 } | |
| 122 | |
| 123 // Sender report (SR) (RFC 3550). | 95 // Sender report (SR) (RFC 3550). |
| 124 // 0 1 2 3 | 96 // 0 1 2 3 |
| 125 // 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 | 97 // 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 |
| 126 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 98 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 127 // |V=2|P| RC | PT=SR=200 | length | | 99 // |V=2|P| RC | PT=SR=200 | length | |
| 128 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 100 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 129 // | SSRC of sender | | 101 // | SSRC of sender | |
| 130 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 102 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 131 // | NTP timestamp, most significant word | | 103 // | NTP timestamp, most significant word | |
| 132 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 104 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 133 // | NTP timestamp, least significant word | | 105 // | NTP timestamp, least significant word | |
| 134 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 106 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 135 // | RTP timestamp | | 107 // | RTP timestamp | |
| 136 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 108 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 137 // | sender's packet count | | 109 // | sender's packet count | |
| 138 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 110 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 139 // | sender's octet count | | 111 // | sender's octet count | |
| 140 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 112 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 141 | 113 |
| 142 void CreateSenderReport(const RTCPPacketSR& sr, | 114 void CreateSenderReport(const RTCPPacketSR& sr, |
| 143 size_t length, | |
| 144 uint8_t* buffer, | 115 uint8_t* buffer, |
| 145 size_t* pos) { | 116 size_t* pos) { |
| 146 CreateHeader(sr.NumberOfReportBlocks, PT_SR, length, buffer, pos); | |
| 147 AssignUWord32(buffer, pos, sr.SenderSSRC); | 117 AssignUWord32(buffer, pos, sr.SenderSSRC); |
| 148 AssignUWord32(buffer, pos, sr.NTPMostSignificant); | 118 AssignUWord32(buffer, pos, sr.NTPMostSignificant); |
| 149 AssignUWord32(buffer, pos, sr.NTPLeastSignificant); | 119 AssignUWord32(buffer, pos, sr.NTPLeastSignificant); |
| 150 AssignUWord32(buffer, pos, sr.RTPTimestamp); | 120 AssignUWord32(buffer, pos, sr.RTPTimestamp); |
| 151 AssignUWord32(buffer, pos, sr.SenderPacketCount); | 121 AssignUWord32(buffer, pos, sr.SenderPacketCount); |
| 152 AssignUWord32(buffer, pos, sr.SenderOctetCount); | 122 AssignUWord32(buffer, pos, sr.SenderOctetCount); |
| 153 } | 123 } |
| 154 | 124 |
| 155 // Receiver report (RR), header (RFC 3550). | 125 // Receiver report (RR), header (RFC 3550). |
| 156 // | 126 // |
| 157 // 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 | 127 // 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 |
| 158 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 128 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 159 // |V=2|P| RC | PT=RR=201 | length | | 129 // |V=2|P| RC | PT=RR=201 | length | |
| 160 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 130 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 161 // | SSRC of packet sender | | 131 // | SSRC of packet sender | |
| 162 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 132 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 163 | 133 |
| 164 void CreateReceiverReport(const RTCPPacketRR& rr, | 134 void CreateReceiverReport(const RTCPPacketRR& rr, |
| 165 size_t length, | |
| 166 uint8_t* buffer, | 135 uint8_t* buffer, |
| 167 size_t* pos) { | 136 size_t* pos) { |
| 168 CreateHeader(rr.NumberOfReportBlocks, PT_RR, length, buffer, pos); | |
| 169 AssignUWord32(buffer, pos, rr.SenderSSRC); | 137 AssignUWord32(buffer, pos, rr.SenderSSRC); |
| 170 } | 138 } |
| 171 | 139 |
| 172 // Report block (RFC 3550). | 140 // Report block (RFC 3550). |
| 173 // | 141 // |
| 174 // 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 | 142 // 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 |
| 175 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 143 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 176 // | SSRC_1 (SSRC of first source) | | 144 // | SSRC_1 (SSRC of first source) | |
| 177 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 145 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 178 // | fraction lost | cumulative number of packets lost | | 146 // | fraction lost | cumulative number of packets lost | |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 180 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 213 // . . | 181 // . . |
| 214 // . . | 182 // . . |
| 215 // . . | 183 // . . |
| 216 // | inter-arrival jitter | | 184 // | inter-arrival jitter | |
| 217 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 185 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 218 | 186 |
| 219 void CreateIj(const std::vector<uint32_t>& ij_items, | 187 void CreateIj(const std::vector<uint32_t>& ij_items, |
| 220 uint8_t* buffer, | 188 uint8_t* buffer, |
| 221 size_t* pos) { | 189 size_t* pos) { |
| 222 size_t length = ij_items.size(); | 190 for (uint32_t item : ij_items) |
| 223 CreateHeader(length, PT_IJ, length, buffer, pos); | 191 AssignUWord32(buffer, pos, item); |
| 224 for (std::vector<uint32_t>::const_iterator it = ij_items.begin(); | |
| 225 it != ij_items.end(); ++it) { | |
| 226 AssignUWord32(buffer, pos, *it); | |
| 227 } | |
| 228 } | 192 } |
| 229 | 193 |
| 230 // Source Description (SDES) (RFC 3550). | 194 // Source Description (SDES) (RFC 3550). |
| 231 // | 195 // |
| 232 // 0 1 2 3 | 196 // 0 1 2 3 |
| 233 // 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 | 197 // 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 |
| 234 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 198 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 235 // header |V=2|P| SC | PT=SDES=202 | length | | 199 // header |V=2|P| SC | PT=SDES=202 | length | |
| 236 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 200 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 237 // chunk | SSRC/CSRC_1 | | 201 // chunk | SSRC/CSRC_1 | |
| 238 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 202 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 239 // | SDES items | | 203 // | SDES items | |
| 240 // | ... | | 204 // | ... | |
| 241 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 205 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 242 // chunk | SSRC/CSRC_2 | | 206 // chunk | SSRC/CSRC_2 | |
| 243 // 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 207 // 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 244 // | SDES items | | 208 // | SDES items | |
| 245 // | ... | | 209 // | ... | |
| 246 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 210 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 247 // | 211 // |
| 248 // Canonical End-Point Identifier SDES Item (CNAME) | 212 // Canonical End-Point Identifier SDES Item (CNAME) |
| 249 // | 213 // |
| 250 // 0 1 2 3 | 214 // 0 1 2 3 |
| 251 // 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 | 215 // 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 |
| 252 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 216 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 253 // | CNAME=1 | length | user and domain name ... | 217 // | CNAME=1 | length | user and domain name ... |
| 254 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 218 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 255 | 219 |
| 256 void CreateSdes(const std::vector<Sdes::Chunk>& chunks, | 220 void CreateSdes(const std::vector<Sdes::Chunk>& chunks, |
| 257 size_t length, | |
| 258 uint8_t* buffer, | 221 uint8_t* buffer, |
| 259 size_t* pos) { | 222 size_t* pos) { |
| 260 CreateHeader(chunks.size(), PT_SDES, length, buffer, pos); | |
| 261 const uint8_t kSdesItemType = 1; | 223 const uint8_t kSdesItemType = 1; |
| 262 for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin(); | 224 for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin(); |
| 263 it != chunks.end(); ++it) { | 225 it != chunks.end(); ++it) { |
| 264 AssignUWord32(buffer, pos, (*it).ssrc); | 226 AssignUWord32(buffer, pos, (*it).ssrc); |
| 265 AssignUWord8(buffer, pos, kSdesItemType); | 227 AssignUWord8(buffer, pos, kSdesItemType); |
| 266 AssignUWord8(buffer, pos, (*it).name.length()); | 228 AssignUWord8(buffer, pos, (*it).name.length()); |
| 267 memcpy(buffer + *pos, (*it).name.data(), (*it).name.length()); | 229 memcpy(buffer + *pos, (*it).name.data(), (*it).name.length()); |
| 268 *pos += (*it).name.length(); | 230 *pos += (*it).name.length(); |
| 269 memset(buffer + *pos, 0, (*it).null_octets); | 231 memset(buffer + *pos, 0, (*it).null_octets); |
| 270 *pos += (*it).null_octets; | 232 *pos += (*it).null_octets; |
| 271 } | 233 } |
| 272 } | 234 } |
| 273 | 235 |
| 274 // Bye packet (BYE) (RFC 3550). | 236 // Bye packet (BYE) (RFC 3550). |
| 275 // | 237 // |
| 276 // 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 | 238 // 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 |
| 277 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 239 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 278 // |V=2|P| SC | PT=BYE=203 | length | | 240 // |V=2|P| SC | PT=BYE=203 | length | |
| 279 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 241 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 280 // | SSRC/CSRC | | 242 // | SSRC/CSRC | |
| 281 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 243 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 282 // : ... : | 244 // : ... : |
| 283 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 245 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 284 // (opt) | length | reason for leaving ... | 246 // (opt) | length | reason for leaving ... |
| 285 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 247 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 286 | 248 |
| 287 void CreateBye(const RTCPPacketBYE& bye, | 249 void CreateBye(const RTCPPacketBYE& bye, |
| 288 const std::vector<uint32_t>& csrcs, | 250 const std::vector<uint32_t>& csrcs, |
| 289 size_t length, | |
| 290 uint8_t* buffer, | 251 uint8_t* buffer, |
| 291 size_t* pos) { | 252 size_t* pos) { |
| 292 CreateHeader(length, PT_BYE, length, buffer, pos); | |
| 293 AssignUWord32(buffer, pos, bye.SenderSSRC); | 253 AssignUWord32(buffer, pos, bye.SenderSSRC); |
| 294 for (uint32_t csrc : csrcs) | 254 for (uint32_t csrc : csrcs) |
| 295 AssignUWord32(buffer, pos, csrc); | 255 AssignUWord32(buffer, pos, csrc); |
| 296 } | 256 } |
| 297 | 257 |
| 298 // Application-Defined packet (APP) (RFC 3550). | 258 // Application-Defined packet (APP) (RFC 3550). |
| 299 // | 259 // |
| 300 // 0 1 2 3 | 260 // 0 1 2 3 |
| 301 // 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 | 261 // 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 |
| 302 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 262 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 303 // |V=2|P| subtype | PT=APP=204 | length | | 263 // |V=2|P| subtype | PT=APP=204 | length | |
| 304 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 264 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 305 // | SSRC/CSRC | | 265 // | SSRC/CSRC | |
| 306 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 266 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 307 // | name (ASCII) | | 267 // | name (ASCII) | |
| 308 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 268 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 309 // | application-dependent data ... | 269 // | application-dependent data ... |
| 310 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 270 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 311 | 271 |
| 312 void CreateApp(const RTCPPacketAPP& app, | 272 void CreateApp(const RTCPPacketAPP& app, |
| 313 uint32_t ssrc, | 273 uint32_t ssrc, |
| 314 size_t length, | |
| 315 uint8_t* buffer, | 274 uint8_t* buffer, |
| 316 size_t* pos) { | 275 size_t* pos) { |
| 317 CreateHeader(app.SubType, PT_APP, length, buffer, pos); | |
| 318 AssignUWord32(buffer, pos, ssrc); | 276 AssignUWord32(buffer, pos, ssrc); |
| 319 AssignUWord32(buffer, pos, app.Name); | 277 AssignUWord32(buffer, pos, app.Name); |
| 320 memcpy(buffer + *pos, app.Data, app.Size); | 278 memcpy(buffer + *pos, app.Data, app.Size); |
| 321 *pos += app.Size; | 279 *pos += app.Size; |
| 322 } | 280 } |
| 323 | 281 |
| 324 // RFC 4585: Feedback format. | 282 // RFC 4585: Feedback format. |
| 325 // | 283 // |
| 326 // Common packet format: | 284 // Common packet format: |
| 327 // | 285 // |
| 328 // 0 1 2 3 | 286 // 0 1 2 3 |
| 329 // 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 | 287 // 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 |
| 330 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 288 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 331 // |V=2|P| FMT | PT | length | | 289 // |V=2|P| FMT | PT | length | |
| 332 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 290 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 333 // | SSRC of packet sender | | 291 // | SSRC of packet sender | |
| 334 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 292 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 335 // | SSRC of media source | | 293 // | SSRC of media source | |
| 336 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 294 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 337 // : Feedback Control Information (FCI) : | 295 // : Feedback Control Information (FCI) : |
| 338 // : | 296 // : |
| 339 // | 297 // |
| 340 | 298 |
| 341 // Picture loss indication (PLI) (RFC 4585). | 299 // Picture loss indication (PLI) (RFC 4585). |
| 342 // | 300 // |
| 343 // FCI: no feedback control information. | 301 // FCI: no feedback control information. |
| 344 | 302 |
| 345 void CreatePli(const RTCPPacketPSFBPLI& pli, | 303 void CreatePli(const RTCPPacketPSFBPLI& pli, |
| 346 size_t length, | |
| 347 uint8_t* buffer, | 304 uint8_t* buffer, |
| 348 size_t* pos) { | 305 size_t* pos) { |
| 349 const uint8_t kFmt = 1; | |
| 350 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); | |
| 351 AssignUWord32(buffer, pos, pli.SenderSSRC); | 306 AssignUWord32(buffer, pos, pli.SenderSSRC); |
| 352 AssignUWord32(buffer, pos, pli.MediaSSRC); | 307 AssignUWord32(buffer, pos, pli.MediaSSRC); |
| 353 } | 308 } |
| 354 | 309 |
| 355 // Slice loss indication (SLI) (RFC 4585). | 310 // Slice loss indication (SLI) (RFC 4585). |
| 356 // | 311 // |
| 357 // FCI: | 312 // FCI: |
| 358 // | 313 // |
| 359 // 0 1 2 3 | 314 // 0 1 2 3 |
| 360 // 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 | 315 // 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 |
| 361 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 316 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 362 // | First | Number | PictureID | | 317 // | First | Number | PictureID | |
| 363 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 318 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 364 | 319 |
| 365 void CreateSli(const RTCPPacketPSFBSLI& sli, | 320 void CreateSli(const RTCPPacketPSFBSLI& sli, |
| 366 const RTCPPacketPSFBSLIItem& sli_item, | 321 const RTCPPacketPSFBSLIItem& sli_item, |
| 367 size_t length, | |
| 368 uint8_t* buffer, | 322 uint8_t* buffer, |
| 369 size_t* pos) { | 323 size_t* pos) { |
| 370 const uint8_t kFmt = 2; | |
| 371 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); | |
| 372 AssignUWord32(buffer, pos, sli.SenderSSRC); | 324 AssignUWord32(buffer, pos, sli.SenderSSRC); |
| 373 AssignUWord32(buffer, pos, sli.MediaSSRC); | 325 AssignUWord32(buffer, pos, sli.MediaSSRC); |
| 374 | 326 |
| 375 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); | 327 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); |
| 376 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + | 328 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + |
| 377 ((sli_item.NumberOfMB >> 10) & 0x07)); | 329 ((sli_item.NumberOfMB >> 10) & 0x07)); |
| 378 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); | 330 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); |
| 379 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); | 331 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); |
| 380 } | 332 } |
| 381 | 333 |
| 382 // Generic NACK (RFC 4585). | 334 // Generic NACK (RFC 4585). |
| 383 // | 335 // |
| 384 // FCI: | 336 // FCI: |
| 385 // | 337 // |
| 386 // 0 1 2 3 | 338 // 0 1 2 3 |
| 387 // 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 | 339 // 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 |
| 388 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 340 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 389 // | PID | BLP | | 341 // | PID | BLP | |
| 390 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 342 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 391 | 343 |
| 392 void CreateNack(const RTCPPacketRTPFBNACK& nack, | 344 void CreateNack(const RTCPPacketRTPFBNACK& nack, |
| 393 const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields, | 345 const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields, |
| 394 size_t start_index, | 346 size_t start_index, |
| 395 size_t end_index, | 347 size_t end_index, |
| 396 size_t length, | |
| 397 uint8_t* buffer, | 348 uint8_t* buffer, |
| 398 size_t* pos) { | 349 size_t* pos) { |
| 399 const uint8_t kFmt = 1; | |
| 400 CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); | |
| 401 AssignUWord32(buffer, pos, nack.SenderSSRC); | 350 AssignUWord32(buffer, pos, nack.SenderSSRC); |
| 402 AssignUWord32(buffer, pos, nack.MediaSSRC); | 351 AssignUWord32(buffer, pos, nack.MediaSSRC); |
| 403 for (size_t i = start_index; i < end_index; ++i) { | 352 for (size_t i = start_index; i < end_index; ++i) { |
| 404 const RTCPPacketRTPFBNACKItem& nack_item = nack_fields[i]; | 353 const RTCPPacketRTPFBNACKItem& nack_item = nack_fields[i]; |
| 405 AssignUWord16(buffer, pos, nack_item.PacketID); | 354 AssignUWord16(buffer, pos, nack_item.PacketID); |
| 406 AssignUWord16(buffer, pos, nack_item.BitMask); | 355 AssignUWord16(buffer, pos, nack_item.BitMask); |
| 407 } | 356 } |
| 408 } | 357 } |
| 409 | 358 |
| 410 // Reference picture selection indication (RPSI) (RFC 4585). | 359 // Reference picture selection indication (RPSI) (RFC 4585). |
| 411 // | 360 // |
| 412 // FCI: | 361 // FCI: |
| 413 // | 362 // |
| 414 // 0 1 2 3 | 363 // 0 1 2 3 |
| 415 // 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 | 364 // 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 |
| 416 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 365 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 417 // | PB |0| Payload Type| Native RPSI bit string | | 366 // | PB |0| Payload Type| Native RPSI bit string | |
| 418 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 367 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 419 // | defined per codec ... | Padding (0) | | 368 // | defined per codec ... | Padding (0) | |
| 420 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 369 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 421 | 370 |
| 422 void CreateRpsi(const RTCPPacketPSFBRPSI& rpsi, | 371 void CreateRpsi(const RTCPPacketPSFBRPSI& rpsi, |
| 423 uint8_t padding_bytes, | 372 uint8_t padding_bytes, |
| 424 size_t length, | |
| 425 uint8_t* buffer, | 373 uint8_t* buffer, |
| 426 size_t* pos) { | 374 size_t* pos) { |
| 427 // Native bit string should be a multiple of 8 bits. | 375 // Native bit string should be a multiple of 8 bits. |
| 428 assert(rpsi.NumberOfValidBits % 8 == 0); | 376 assert(rpsi.NumberOfValidBits % 8 == 0); |
| 429 const uint8_t kFmt = 3; | |
| 430 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); | |
| 431 AssignUWord32(buffer, pos, rpsi.SenderSSRC); | 377 AssignUWord32(buffer, pos, rpsi.SenderSSRC); |
| 432 AssignUWord32(buffer, pos, rpsi.MediaSSRC); | 378 AssignUWord32(buffer, pos, rpsi.MediaSSRC); |
| 433 AssignUWord8(buffer, pos, padding_bytes * 8); | 379 AssignUWord8(buffer, pos, padding_bytes * 8); |
| 434 AssignUWord8(buffer, pos, rpsi.PayloadType); | 380 AssignUWord8(buffer, pos, rpsi.PayloadType); |
| 435 memcpy(buffer + *pos, rpsi.NativeBitString, rpsi.NumberOfValidBits / 8); | 381 memcpy(buffer + *pos, rpsi.NativeBitString, rpsi.NumberOfValidBits / 8); |
| 436 *pos += rpsi.NumberOfValidBits / 8; | 382 *pos += rpsi.NumberOfValidBits / 8; |
| 437 memset(buffer + *pos, 0, padding_bytes); | 383 memset(buffer + *pos, 0, padding_bytes); |
| 438 *pos += padding_bytes; | 384 *pos += padding_bytes; |
| 439 } | 385 } |
| 440 | 386 |
| 441 // Full intra request (FIR) (RFC 5104). | 387 // Full intra request (FIR) (RFC 5104). |
| 442 // | 388 // |
| 443 // FCI: | 389 // FCI: |
| 444 // | 390 // |
| 445 // 0 1 2 3 | 391 // 0 1 2 3 |
| 446 // 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 | 392 // 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 |
| 447 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 393 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 448 // | SSRC | | 394 // | SSRC | |
| 449 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 395 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 450 // | Seq nr. | Reserved | | 396 // | Seq nr. | Reserved | |
| 451 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 397 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 452 | 398 |
| 453 void CreateFir(const RTCPPacketPSFBFIR& fir, | 399 void CreateFir(const RTCPPacketPSFBFIR& fir, |
| 454 const RTCPPacketPSFBFIRItem& fir_item, | 400 const RTCPPacketPSFBFIRItem& fir_item, |
| 455 size_t length, | |
| 456 uint8_t* buffer, | 401 uint8_t* buffer, |
| 457 size_t* pos) { | 402 size_t* pos) { |
| 458 const uint8_t kFmt = 4; | |
| 459 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); | |
| 460 AssignUWord32(buffer, pos, fir.SenderSSRC); | 403 AssignUWord32(buffer, pos, fir.SenderSSRC); |
| 461 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); | 404 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); |
| 462 AssignUWord32(buffer, pos, fir_item.SSRC); | 405 AssignUWord32(buffer, pos, fir_item.SSRC); |
| 463 AssignUWord8(buffer, pos, fir_item.CommandSequenceNumber); | 406 AssignUWord8(buffer, pos, fir_item.CommandSequenceNumber); |
| 464 AssignUWord24(buffer, pos, 0); | 407 AssignUWord24(buffer, pos, 0); |
| 465 } | 408 } |
| 466 | 409 |
| 467 void CreateTmmbrItem(const RTCPPacketRTPFBTMMBRItem& tmmbr_item, | 410 void CreateTmmbrItem(const RTCPPacketRTPFBTMMBRItem& tmmbr_item, |
| 468 uint8_t* buffer, | 411 uint8_t* buffer, |
| 469 size_t* pos) { | 412 size_t* pos) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 487 // 0 1 2 3 | 430 // 0 1 2 3 |
| 488 // 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 | 431 // 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 |
| 489 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 432 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 490 // | SSRC | | 433 // | SSRC | |
| 491 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 434 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 492 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| | 435 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| |
| 493 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 436 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 494 | 437 |
| 495 void CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr, | 438 void CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr, |
| 496 const RTCPPacketRTPFBTMMBRItem& tmmbr_item, | 439 const RTCPPacketRTPFBTMMBRItem& tmmbr_item, |
| 497 size_t length, | |
| 498 uint8_t* buffer, | 440 uint8_t* buffer, |
| 499 size_t* pos) { | 441 size_t* pos) { |
| 500 const uint8_t kFmt = 3; | |
| 501 CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); | |
| 502 AssignUWord32(buffer, pos, tmmbr.SenderSSRC); | 442 AssignUWord32(buffer, pos, tmmbr.SenderSSRC); |
| 503 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); | 443 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); |
| 504 CreateTmmbrItem(tmmbr_item, buffer, pos); | 444 CreateTmmbrItem(tmmbr_item, buffer, pos); |
| 505 } | 445 } |
| 506 | 446 |
| 507 // Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). | 447 // Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). |
| 508 // | 448 // |
| 509 // FCI: | 449 // FCI: |
| 510 // | 450 // |
| 511 // 0 1 2 3 | 451 // 0 1 2 3 |
| 512 // 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 | 452 // 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 |
| 513 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 453 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 514 // | SSRC | | 454 // | SSRC | |
| 515 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 455 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 516 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| | 456 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| |
| 517 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 457 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 518 | 458 |
| 519 void CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn, | 459 void CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn, |
| 520 const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items, | 460 const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items, |
| 521 size_t length, | |
| 522 uint8_t* buffer, | 461 uint8_t* buffer, |
| 523 size_t* pos) { | 462 size_t* pos) { |
| 524 const uint8_t kFmt = 4; | |
| 525 CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); | |
| 526 AssignUWord32(buffer, pos, tmmbn.SenderSSRC); | 463 AssignUWord32(buffer, pos, tmmbn.SenderSSRC); |
| 527 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); | 464 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); |
| 528 for (uint8_t i = 0; i < tmmbn_items.size(); ++i) { | 465 for (uint8_t i = 0; i < tmmbn_items.size(); ++i) { |
| 529 CreateTmmbrItem(tmmbn_items[i], buffer, pos); | 466 CreateTmmbrItem(tmmbn_items[i], buffer, pos); |
| 530 } | 467 } |
| 531 } | 468 } |
| 532 | 469 |
| 533 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). | 470 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb). |
| 534 // | 471 // |
| 535 // 0 1 2 3 | 472 // 0 1 2 3 |
| 536 // 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 | 473 // 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 |
| 537 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 474 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 538 // |V=2|P| FMT=15 | PT=206 | length | | 475 // |V=2|P| FMT=15 | PT=206 | length | |
| 539 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 476 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 540 // | SSRC of packet sender | | 477 // | SSRC of packet sender | |
| 541 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 478 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 542 // | SSRC of media source | | 479 // | SSRC of media source | |
| 543 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 480 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 544 // | Unique identifier 'R' 'E' 'M' 'B' | | 481 // | Unique identifier 'R' 'E' 'M' 'B' | |
| 545 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 482 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 546 // | Num SSRC | BR Exp | BR Mantissa | | 483 // | Num SSRC | BR Exp | BR Mantissa | |
| 547 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 484 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 548 // | SSRC feedback | | 485 // | SSRC feedback | |
| 549 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 486 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 550 // | ... | | 487 // | ... | |
| 551 | 488 |
| 552 void CreateRemb(const RTCPPacketPSFBAPP& remb, | 489 void CreateRemb(const RTCPPacketPSFBAPP& remb, |
| 553 const RTCPPacketPSFBREMBItem& remb_item, | 490 const RTCPPacketPSFBREMBItem& remb_item, |
| 554 size_t length, | |
| 555 uint8_t* buffer, | 491 uint8_t* buffer, |
| 556 size_t* pos) { | 492 size_t* pos) { |
| 557 uint32_t mantissa = 0; | 493 uint32_t mantissa = 0; |
| 558 uint8_t exp = 0; | 494 uint8_t exp = 0; |
| 559 ComputeMantissaAnd6bitBase2Exponent(remb_item.BitRate, 18, &mantissa, &exp); | 495 ComputeMantissaAnd6bitBase2Exponent(remb_item.BitRate, 18, &mantissa, &exp); |
| 560 | 496 |
| 561 const uint8_t kFmt = 15; | |
| 562 CreateHeader(kFmt, PT_PSFB, length, buffer, pos); | |
| 563 AssignUWord32(buffer, pos, remb.SenderSSRC); | 497 AssignUWord32(buffer, pos, remb.SenderSSRC); |
| 564 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); | 498 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); |
| 565 AssignUWord8(buffer, pos, 'R'); | 499 AssignUWord8(buffer, pos, 'R'); |
| 566 AssignUWord8(buffer, pos, 'E'); | 500 AssignUWord8(buffer, pos, 'E'); |
| 567 AssignUWord8(buffer, pos, 'M'); | 501 AssignUWord8(buffer, pos, 'M'); |
| 568 AssignUWord8(buffer, pos, 'B'); | 502 AssignUWord8(buffer, pos, 'B'); |
| 569 AssignUWord8(buffer, pos, remb_item.NumberOfSSRCs); | 503 AssignUWord8(buffer, pos, remb_item.NumberOfSSRCs); |
| 570 AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 16) & 0x03)); | 504 AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 16) & 0x03)); |
| 571 AssignUWord8(buffer, pos, mantissa >> 8); | 505 AssignUWord8(buffer, pos, mantissa >> 8); |
| 572 AssignUWord8(buffer, pos, mantissa); | 506 AssignUWord8(buffer, pos, mantissa); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 583 // 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 | 517 // 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 |
| 584 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 518 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 585 // |V=2|P|reserved | PT=XR=207 | length | | 519 // |V=2|P|reserved | PT=XR=207 | length | |
| 586 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 520 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 587 // | SSRC | | 521 // | SSRC | |
| 588 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 522 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 589 // : report blocks : | 523 // : report blocks : |
| 590 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 524 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 591 | 525 |
| 592 void CreateXrHeader(const RTCPPacketXR& header, | 526 void CreateXrHeader(const RTCPPacketXR& header, |
| 593 size_t length, | |
| 594 uint8_t* buffer, | 527 uint8_t* buffer, |
| 595 size_t* pos) { | 528 size_t* pos) { |
| 596 CreateHeader(0U, PT_XR, length, buffer, pos); | |
| 597 AssignUWord32(buffer, pos, header.OriginatorSSRC); | 529 AssignUWord32(buffer, pos, header.OriginatorSSRC); |
| 598 } | 530 } |
| 599 | 531 |
| 600 void CreateXrBlockHeader(uint8_t block_type, | 532 void CreateXrBlockHeader(uint8_t block_type, |
| 601 uint16_t block_length, | 533 uint16_t block_length, |
| 602 uint8_t* buffer, | 534 uint8_t* buffer, |
| 603 size_t* pos) { | 535 size_t* pos) { |
| 604 AssignUWord8(buffer, pos, block_type); | 536 AssignUWord8(buffer, pos, block_type); |
| 605 AssignUWord8(buffer, pos, 0); | 537 AssignUWord8(buffer, pos, 0); |
| 606 AssignUWord16(buffer, pos, block_length); | 538 AssignUWord16(buffer, pos, block_length); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 bool RtcpPacket::OnBufferFull(uint8_t* packet, | 715 bool RtcpPacket::OnBufferFull(uint8_t* packet, |
| 784 size_t* index, | 716 size_t* index, |
| 785 RtcpPacket::PacketReadyCallback* callback) const { | 717 RtcpPacket::PacketReadyCallback* callback) const { |
| 786 if (*index == 0) | 718 if (*index == 0) |
| 787 return false; | 719 return false; |
| 788 callback->OnPacketReady(packet, *index); | 720 callback->OnPacketReady(packet, *index); |
| 789 *index = 0; | 721 *index = 0; |
| 790 return true; | 722 return true; |
| 791 } | 723 } |
| 792 | 724 |
| 725 size_t RtcpPacket::HeaderLength() const { |
| 726 size_t length_in_bytes = BlockLength(); |
| 727 // Length in 32-bit words minus 1. |
| 728 assert(length_in_bytes > 0); |
| 729 return ((length_in_bytes + 3) / 4) - 1; |
| 730 } |
| 731 |
| 732 // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. |
| 733 // |
| 734 // RTP header format. |
| 735 // 0 1 2 3 |
| 736 // 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 |
| 737 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 738 // |V=2|P| RC/FMT | PT | length | |
| 739 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 740 |
| 741 void RtcpPacket::CreateHeader( |
| 742 uint8_t count_or_format, // Depends on packet type. |
| 743 uint8_t packet_type, |
| 744 size_t length, |
| 745 uint8_t* buffer, |
| 746 size_t* pos) const { |
| 747 assert(length <= 0xffff); |
| 748 const uint8_t kVersion = 2; |
| 749 AssignUWord8(buffer, pos, (kVersion << 6) + count_or_format); |
| 750 AssignUWord8(buffer, pos, packet_type); |
| 751 AssignUWord16(buffer, pos, length); |
| 752 } |
| 753 |
| 793 bool Empty::Create(uint8_t* packet, | 754 bool Empty::Create(uint8_t* packet, |
| 794 size_t* index, | 755 size_t* index, |
| 795 size_t max_length, | 756 size_t max_length, |
| 796 RtcpPacket::PacketReadyCallback* callback) const { | 757 RtcpPacket::PacketReadyCallback* callback) const { |
| 797 return true; | 758 return true; |
| 798 } | 759 } |
| 799 | 760 |
| 761 size_t Empty::BlockLength() const { |
| 762 return 0; |
| 763 } |
| 764 |
| 800 bool SenderReport::Create(uint8_t* packet, | 765 bool SenderReport::Create(uint8_t* packet, |
| 801 size_t* index, | 766 size_t* index, |
| 802 size_t max_length, | 767 size_t max_length, |
| 803 RtcpPacket::PacketReadyCallback* callback) const { | 768 RtcpPacket::PacketReadyCallback* callback) const { |
| 804 while (*index + BlockLength() > max_length) { | 769 while (*index + BlockLength() > max_length) { |
| 805 if (!OnBufferFull(packet, index, callback)) | 770 if (!OnBufferFull(packet, index, callback)) |
| 806 return false; | 771 return false; |
| 807 } | 772 } |
| 808 CreateSenderReport(sr_, BlockToHeaderLength(BlockLength()), packet, index); | 773 CreateHeader(sr_.NumberOfReportBlocks, PT_SR, HeaderLength(), packet, index); |
| 774 CreateSenderReport(sr_, packet, index); |
| 809 CreateReportBlocks(report_blocks_, packet, index); | 775 CreateReportBlocks(report_blocks_, packet, index); |
| 810 return true; | 776 return true; |
| 811 } | 777 } |
| 812 | 778 |
| 813 bool SenderReport::WithReportBlock(ReportBlock* block) { | 779 bool SenderReport::WithReportBlock(ReportBlock* block) { |
| 814 assert(block); | 780 assert(block); |
| 815 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | 781 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { |
| 816 LOG(LS_WARNING) << "Max report blocks reached."; | 782 LOG(LS_WARNING) << "Max report blocks reached."; |
| 817 return false; | 783 return false; |
| 818 } | 784 } |
| 819 report_blocks_.push_back(block->report_block_); | 785 report_blocks_.push_back(block->report_block_); |
| 820 sr_.NumberOfReportBlocks = report_blocks_.size(); | 786 sr_.NumberOfReportBlocks = report_blocks_.size(); |
| 821 return true; | 787 return true; |
| 822 } | 788 } |
| 823 | 789 |
| 824 bool ReceiverReport::Create(uint8_t* packet, | 790 bool ReceiverReport::Create(uint8_t* packet, |
| 825 size_t* index, | 791 size_t* index, |
| 826 size_t max_length, | 792 size_t max_length, |
| 827 RtcpPacket::PacketReadyCallback* callback) const { | 793 RtcpPacket::PacketReadyCallback* callback) const { |
| 828 while (*index + BlockLength() > max_length) { | 794 while (*index + BlockLength() > max_length) { |
| 829 if (!OnBufferFull(packet, index, callback)) | 795 if (!OnBufferFull(packet, index, callback)) |
| 830 return false; | 796 return false; |
| 831 } | 797 } |
| 832 CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, index); | 798 CreateHeader(rr_.NumberOfReportBlocks, PT_RR, HeaderLength(), packet, index); |
| 799 CreateReceiverReport(rr_, packet, index); |
| 833 CreateReportBlocks(report_blocks_, packet, index); | 800 CreateReportBlocks(report_blocks_, packet, index); |
| 834 return true; | 801 return true; |
| 835 } | 802 } |
| 836 | 803 |
| 837 bool ReceiverReport::WithReportBlock(ReportBlock* block) { | 804 bool ReceiverReport::WithReportBlock(ReportBlock* block) { |
| 838 assert(block); | 805 assert(block); |
| 839 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | 806 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { |
| 840 LOG(LS_WARNING) << "Max report blocks reached."; | 807 LOG(LS_WARNING) << "Max report blocks reached."; |
| 841 return false; | 808 return false; |
| 842 } | 809 } |
| 843 report_blocks_.push_back(block->report_block_); | 810 report_blocks_.push_back(block->report_block_); |
| 844 rr_.NumberOfReportBlocks = report_blocks_.size(); | 811 rr_.NumberOfReportBlocks = report_blocks_.size(); |
| 845 return true; | 812 return true; |
| 846 } | 813 } |
| 847 | 814 |
| 848 bool Ij::Create(uint8_t* packet, | 815 bool Ij::Create(uint8_t* packet, |
| 849 size_t* index, | 816 size_t* index, |
| 850 size_t max_length, | 817 size_t max_length, |
| 851 RtcpPacket::PacketReadyCallback* callback) const { | 818 RtcpPacket::PacketReadyCallback* callback) const { |
| 852 while (*index + BlockLength() > max_length) { | 819 while (*index + BlockLength() > max_length) { |
| 853 if (!OnBufferFull(packet, index, callback)) | 820 if (!OnBufferFull(packet, index, callback)) |
| 854 return false; | 821 return false; |
| 855 } | 822 } |
| 823 size_t length = ij_items_.size(); |
| 824 CreateHeader(length, PT_IJ, length, packet, index); |
| 856 CreateIj(ij_items_, packet, index); | 825 CreateIj(ij_items_, packet, index); |
| 857 return true; | 826 return true; |
| 858 } | 827 } |
| 859 | 828 |
| 860 bool Ij::WithJitterItem(uint32_t jitter) { | 829 bool Ij::WithJitterItem(uint32_t jitter) { |
| 861 if (ij_items_.size() >= kMaxNumberOfIjItems) { | 830 if (ij_items_.size() >= kMaxNumberOfIjItems) { |
| 862 LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; | 831 LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; |
| 863 return false; | 832 return false; |
| 864 } | 833 } |
| 865 ij_items_.push_back(jitter); | 834 ij_items_.push_back(jitter); |
| 866 return true; | 835 return true; |
| 867 } | 836 } |
| 868 | 837 |
| 869 bool Sdes::Create(uint8_t* packet, | 838 bool Sdes::Create(uint8_t* packet, |
| 870 size_t* index, | 839 size_t* index, |
| 871 size_t max_length, | 840 size_t max_length, |
| 872 RtcpPacket::PacketReadyCallback* callback) const { | 841 RtcpPacket::PacketReadyCallback* callback) const { |
| 873 assert(!chunks_.empty()); | 842 assert(!chunks_.empty()); |
| 874 while (*index + BlockLength() > max_length) { | 843 while (*index + BlockLength() > max_length) { |
| 875 if (!OnBufferFull(packet, index, callback)) | 844 if (!OnBufferFull(packet, index, callback)) |
| 876 return false; | 845 return false; |
| 877 } | 846 } |
| 878 CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, index); | 847 CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index); |
| 848 CreateSdes(chunks_, packet, index); |
| 879 return true; | 849 return true; |
| 880 } | 850 } |
| 881 | 851 |
| 882 bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { | 852 bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { |
| 883 assert(cname.length() <= 0xff); | 853 assert(cname.length() <= 0xff); |
| 884 if (chunks_.size() >= kMaxNumberOfChunks) { | 854 if (chunks_.size() >= kMaxNumberOfChunks) { |
| 885 LOG(LS_WARNING) << "Max SDES chunks reached."; | 855 LOG(LS_WARNING) << "Max SDES chunks reached."; |
| 886 return false; | 856 return false; |
| 887 } | 857 } |
| 888 // In each chunk, the list of items must be terminated by one or more null | 858 // In each chunk, the list of items must be terminated by one or more null |
| (...skipping 20 matching lines...) Expand all Loading... |
| 909 } | 879 } |
| 910 | 880 |
| 911 bool Bye::Create(uint8_t* packet, | 881 bool Bye::Create(uint8_t* packet, |
| 912 size_t* index, | 882 size_t* index, |
| 913 size_t max_length, | 883 size_t max_length, |
| 914 RtcpPacket::PacketReadyCallback* callback) const { | 884 RtcpPacket::PacketReadyCallback* callback) const { |
| 915 while (*index + BlockLength() > max_length) { | 885 while (*index + BlockLength() > max_length) { |
| 916 if (!OnBufferFull(packet, index, callback)) | 886 if (!OnBufferFull(packet, index, callback)) |
| 917 return false; | 887 return false; |
| 918 } | 888 } |
| 919 CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, index); | 889 size_t length = HeaderLength(); |
| 890 CreateHeader(length, PT_BYE, length, packet, index); |
| 891 CreateBye(bye_, csrcs_, packet, index); |
| 920 return true; | 892 return true; |
| 921 } | 893 } |
| 922 | 894 |
| 923 bool Bye::WithCsrc(uint32_t csrc) { | 895 bool Bye::WithCsrc(uint32_t csrc) { |
| 924 if (csrcs_.size() >= kMaxNumberOfCsrcs) { | 896 if (csrcs_.size() >= kMaxNumberOfCsrcs) { |
| 925 LOG(LS_WARNING) << "Max CSRC size reached."; | 897 LOG(LS_WARNING) << "Max CSRC size reached."; |
| 926 return false; | 898 return false; |
| 927 } | 899 } |
| 928 csrcs_.push_back(csrc); | 900 csrcs_.push_back(csrc); |
| 929 return true; | 901 return true; |
| 930 } | 902 } |
| 931 | 903 |
| 932 bool App::Create(uint8_t* packet, | 904 bool App::Create(uint8_t* packet, |
| 933 size_t* index, | 905 size_t* index, |
| 934 size_t max_length, | 906 size_t max_length, |
| 935 RtcpPacket::PacketReadyCallback* callback) const { | 907 RtcpPacket::PacketReadyCallback* callback) const { |
| 936 while (*index + BlockLength() > max_length) { | 908 while (*index + BlockLength() > max_length) { |
| 937 if (!OnBufferFull(packet, index, callback)) | 909 if (!OnBufferFull(packet, index, callback)) |
| 938 return false; | 910 return false; |
| 939 } | 911 } |
| 940 CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, index); | 912 CreateHeader(app_.SubType, PT_APP, HeaderLength(), packet, index); |
| 913 CreateApp(app_, ssrc_, packet, index); |
| 941 return true; | 914 return true; |
| 942 } | 915 } |
| 943 | 916 |
| 944 bool Pli::Create(uint8_t* packet, | 917 bool Pli::Create(uint8_t* packet, |
| 945 size_t* index, | 918 size_t* index, |
| 946 size_t max_length, | 919 size_t max_length, |
| 947 RtcpPacket::PacketReadyCallback* callback) const { | 920 RtcpPacket::PacketReadyCallback* callback) const { |
| 948 while (*index + BlockLength() > max_length) { | 921 while (*index + BlockLength() > max_length) { |
| 949 if (!OnBufferFull(packet, index, callback)) | 922 if (!OnBufferFull(packet, index, callback)) |
| 950 return false; | 923 return false; |
| 951 } | 924 } |
| 952 CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, index); | 925 const uint8_t kFmt = 1; |
| 926 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 927 CreatePli(pli_, packet, index); |
| 953 return true; | 928 return true; |
| 954 } | 929 } |
| 955 | 930 |
| 956 bool Sli::Create(uint8_t* packet, | 931 bool Sli::Create(uint8_t* packet, |
| 957 size_t* index, | 932 size_t* index, |
| 958 size_t max_length, | 933 size_t max_length, |
| 959 RtcpPacket::PacketReadyCallback* callback) const { | 934 RtcpPacket::PacketReadyCallback* callback) const { |
| 960 while (*index + BlockLength() > max_length) { | 935 while (*index + BlockLength() > max_length) { |
| 961 if (!OnBufferFull(packet, index, callback)) | 936 if (!OnBufferFull(packet, index, callback)) |
| 962 return false; | 937 return false; |
| 963 } | 938 } |
| 964 CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet, index); | 939 const uint8_t kFmt = 2; |
| 940 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 941 CreateSli(sli_, sli_item_, packet, index); |
| 965 return true; | 942 return true; |
| 966 } | 943 } |
| 967 | 944 |
| 968 bool Nack::Create(uint8_t* packet, | 945 bool Nack::Create(uint8_t* packet, |
| 969 size_t* index, | 946 size_t* index, |
| 970 size_t max_length, | 947 size_t max_length, |
| 971 RtcpPacket::PacketReadyCallback* callback) const { | 948 RtcpPacket::PacketReadyCallback* callback) const { |
| 972 assert(!nack_fields_.empty()); | 949 assert(!nack_fields_.empty()); |
| 973 // If nack list can't fit in packet, try to fragment. | 950 // If nack list can't fit in packet, try to fragment. |
| 974 size_t nack_index = 0; | 951 size_t nack_index = 0; |
| 975 do { | 952 do { |
| 976 size_t bytes_left_in_buffer = max_length - *index; | 953 size_t bytes_left_in_buffer = max_length - *index; |
| 977 if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { | 954 if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { |
| 978 if (!OnBufferFull(packet, index, callback)) | 955 if (!OnBufferFull(packet, index, callback)) |
| 979 return false; | 956 return false; |
| 980 continue; | 957 continue; |
| 981 } | 958 } |
| 982 int64_t num_nack_fields = | 959 int64_t num_nack_fields = |
| 983 std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, | 960 std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, |
| 984 nack_fields_.size() - nack_index); | 961 nack_fields_.size() - nack_index); |
| 985 | 962 |
| 963 const uint8_t kFmt = 1; |
| 964 size_t size_bytes = (num_nack_fields * 4) + kCommonFbFmtLength; |
| 965 size_t header_length = ((size_bytes + 3) / 4) - 1; // As 32bit words - 1 |
| 966 CreateHeader(kFmt, PT_RTPFB, header_length, packet, index); |
| 986 CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, | 967 CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, |
| 987 BlockToHeaderLength((num_nack_fields * 4) + kCommonFbFmtLength), | |
| 988 packet, index); | 968 packet, index); |
| 989 | 969 |
| 990 nack_index += num_nack_fields; | 970 nack_index += num_nack_fields; |
| 991 } while (nack_index < nack_fields_.size()); | 971 } while (nack_index < nack_fields_.size()); |
| 992 | 972 |
| 993 return true; | 973 return true; |
| 994 } | 974 } |
| 995 | 975 |
| 976 size_t Nack::BlockLength() const { |
| 977 return (nack_fields_.size() * 4) + kCommonFbFmtLength; |
| 978 } |
| 979 |
| 996 void Nack::WithList(const uint16_t* nack_list, int length) { | 980 void Nack::WithList(const uint16_t* nack_list, int length) { |
| 997 assert(nack_list); | 981 assert(nack_list); |
| 998 assert(nack_fields_.empty()); | 982 assert(nack_fields_.empty()); |
| 999 int i = 0; | 983 int i = 0; |
| 1000 while (i < length) { | 984 while (i < length) { |
| 1001 uint16_t pid = nack_list[i++]; | 985 uint16_t pid = nack_list[i++]; |
| 1002 // Bitmask specifies losses in any of the 16 packets following the pid. | 986 // Bitmask specifies losses in any of the 16 packets following the pid. |
| 1003 uint16_t bitmask = 0; | 987 uint16_t bitmask = 0; |
| 1004 while (i < length) { | 988 while (i < length) { |
| 1005 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; | 989 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1019 | 1003 |
| 1020 bool Rpsi::Create(uint8_t* packet, | 1004 bool Rpsi::Create(uint8_t* packet, |
| 1021 size_t* index, | 1005 size_t* index, |
| 1022 size_t max_length, | 1006 size_t max_length, |
| 1023 RtcpPacket::PacketReadyCallback* callback) const { | 1007 RtcpPacket::PacketReadyCallback* callback) const { |
| 1024 assert(rpsi_.NumberOfValidBits > 0); | 1008 assert(rpsi_.NumberOfValidBits > 0); |
| 1025 while (*index + BlockLength() > max_length) { | 1009 while (*index + BlockLength() > max_length) { |
| 1026 if (!OnBufferFull(packet, index, callback)) | 1010 if (!OnBufferFull(packet, index, callback)) |
| 1027 return false; | 1011 return false; |
| 1028 } | 1012 } |
| 1029 CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(BlockLength()), packet, | 1013 const uint8_t kFmt = 3; |
| 1030 index); | 1014 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 1015 CreateRpsi(rpsi_, padding_bytes_, packet, index); |
| 1031 return true; | 1016 return true; |
| 1032 } | 1017 } |
| 1033 | 1018 |
| 1034 void Rpsi::WithPictureId(uint64_t picture_id) { | 1019 void Rpsi::WithPictureId(uint64_t picture_id) { |
| 1035 const uint32_t kPidBits = 7; | 1020 const uint32_t kPidBits = 7; |
| 1036 const uint64_t k7MsbZeroMask = 0x1ffffffffffffffULL; | 1021 const uint64_t k7MsbZeroMask = 0x1ffffffffffffffULL; |
| 1037 uint8_t required_bytes = 0; | 1022 uint8_t required_bytes = 0; |
| 1038 uint64_t shifted_pid = picture_id; | 1023 uint64_t shifted_pid = picture_id; |
| 1039 do { | 1024 do { |
| 1040 ++required_bytes; | 1025 ++required_bytes; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1059 } | 1044 } |
| 1060 | 1045 |
| 1061 bool Fir::Create(uint8_t* packet, | 1046 bool Fir::Create(uint8_t* packet, |
| 1062 size_t* index, | 1047 size_t* index, |
| 1063 size_t max_length, | 1048 size_t max_length, |
| 1064 RtcpPacket::PacketReadyCallback* callback) const { | 1049 RtcpPacket::PacketReadyCallback* callback) const { |
| 1065 while (*index + BlockLength() > max_length) { | 1050 while (*index + BlockLength() > max_length) { |
| 1066 if (!OnBufferFull(packet, index, callback)) | 1051 if (!OnBufferFull(packet, index, callback)) |
| 1067 return false; | 1052 return false; |
| 1068 } | 1053 } |
| 1069 CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet, index); | 1054 const uint8_t kFmt = 4; |
| 1055 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 1056 CreateFir(fir_, fir_item_, packet, index); |
| 1070 return true; | 1057 return true; |
| 1071 } | 1058 } |
| 1072 | 1059 |
| 1073 bool Remb::Create(uint8_t* packet, | 1060 bool Remb::Create(uint8_t* packet, |
| 1074 size_t* index, | 1061 size_t* index, |
| 1075 size_t max_length, | 1062 size_t max_length, |
| 1076 RtcpPacket::PacketReadyCallback* callback) const { | 1063 RtcpPacket::PacketReadyCallback* callback) const { |
| 1077 while (*index + BlockLength() > max_length) { | 1064 while (*index + BlockLength() > max_length) { |
| 1078 if (!OnBufferFull(packet, index, callback)) | 1065 if (!OnBufferFull(packet, index, callback)) |
| 1079 return false; | 1066 return false; |
| 1080 } | 1067 } |
| 1081 CreateRemb(remb_, remb_item_, BlockToHeaderLength(BlockLength()), packet, | 1068 const uint8_t kFmt = 15; |
| 1082 index); | 1069 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 1070 CreateRemb(remb_, remb_item_, packet, index); |
| 1083 return true; | 1071 return true; |
| 1084 } | 1072 } |
| 1085 | 1073 |
| 1086 void Remb::AppliesTo(uint32_t ssrc) { | 1074 void Remb::AppliesTo(uint32_t ssrc) { |
| 1087 if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) { | 1075 if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) { |
| 1088 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached."; | 1076 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached."; |
| 1089 return; | 1077 return; |
| 1090 } | 1078 } |
| 1091 remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; | 1079 remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; |
| 1092 } | 1080 } |
| 1093 | 1081 |
| 1094 bool Tmmbr::Create(uint8_t* packet, | 1082 bool Tmmbr::Create(uint8_t* packet, |
| 1095 size_t* index, | 1083 size_t* index, |
| 1096 size_t max_length, | 1084 size_t max_length, |
| 1097 RtcpPacket::PacketReadyCallback* callback) const { | 1085 RtcpPacket::PacketReadyCallback* callback) const { |
| 1098 while (*index + BlockLength() > max_length) { | 1086 while (*index + BlockLength() > max_length) { |
| 1099 if (!OnBufferFull(packet, index, callback)) | 1087 if (!OnBufferFull(packet, index, callback)) |
| 1100 return false; | 1088 return false; |
| 1101 } | 1089 } |
| 1102 CreateTmmbr(tmmbr_, tmmbr_item_, BlockToHeaderLength(BlockLength()), packet, | 1090 const uint8_t kFmt = 3; |
| 1103 index); | 1091 CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index); |
| 1092 CreateTmmbr(tmmbr_, tmmbr_item_, packet, index); |
| 1104 return true; | 1093 return true; |
| 1105 } | 1094 } |
| 1106 | 1095 |
| 1107 bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { | 1096 bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { |
| 1108 assert(overhead <= 0x1ff); | 1097 assert(overhead <= 0x1ff); |
| 1109 if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { | 1098 if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { |
| 1110 LOG(LS_WARNING) << "Max TMMBN size reached."; | 1099 LOG(LS_WARNING) << "Max TMMBN size reached."; |
| 1111 return false; | 1100 return false; |
| 1112 } | 1101 } |
| 1113 RTCPPacketRTPFBTMMBRItem tmmbn_item; | 1102 RTCPPacketRTPFBTMMBRItem tmmbn_item; |
| 1114 tmmbn_item.SSRC = ssrc; | 1103 tmmbn_item.SSRC = ssrc; |
| 1115 tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; | 1104 tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; |
| 1116 tmmbn_item.MeasuredOverhead = overhead; | 1105 tmmbn_item.MeasuredOverhead = overhead; |
| 1117 tmmbn_items_.push_back(tmmbn_item); | 1106 tmmbn_items_.push_back(tmmbn_item); |
| 1118 return true; | 1107 return true; |
| 1119 } | 1108 } |
| 1120 | 1109 |
| 1121 bool Tmmbn::Create(uint8_t* packet, | 1110 bool Tmmbn::Create(uint8_t* packet, |
| 1122 size_t* index, | 1111 size_t* index, |
| 1123 size_t max_length, | 1112 size_t max_length, |
| 1124 RtcpPacket::PacketReadyCallback* callback) const { | 1113 RtcpPacket::PacketReadyCallback* callback) const { |
| 1125 while (*index + BlockLength() > max_length) { | 1114 while (*index + BlockLength() > max_length) { |
| 1126 if (!OnBufferFull(packet, index, callback)) | 1115 if (!OnBufferFull(packet, index, callback)) |
| 1127 return false; | 1116 return false; |
| 1128 } | 1117 } |
| 1129 CreateTmmbn(tmmbn_, tmmbn_items_, BlockToHeaderLength(BlockLength()), packet, | 1118 const uint8_t kFmt = 4; |
| 1130 index); | 1119 CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index); |
| 1120 CreateTmmbn(tmmbn_, tmmbn_items_, packet, index); |
| 1131 return true; | 1121 return true; |
| 1132 } | 1122 } |
| 1133 | 1123 |
| 1134 bool Xr::Create(uint8_t* packet, | 1124 bool Xr::Create(uint8_t* packet, |
| 1135 size_t* index, | 1125 size_t* index, |
| 1136 size_t max_length, | 1126 size_t max_length, |
| 1137 RtcpPacket::PacketReadyCallback* callback) const { | 1127 RtcpPacket::PacketReadyCallback* callback) const { |
| 1138 while (*index + BlockLength() > max_length) { | 1128 while (*index + BlockLength() > max_length) { |
| 1139 if (!OnBufferFull(packet, index, callback)) | 1129 if (!OnBufferFull(packet, index, callback)) |
| 1140 return false; | 1130 return false; |
| 1141 } | 1131 } |
| 1142 CreateXrHeader(xr_header_, BlockToHeaderLength(BlockLength()), packet, index); | 1132 CreateHeader(0U, PT_XR, HeaderLength(), packet, index); |
| 1133 CreateXrHeader(xr_header_, packet, index); |
| 1143 CreateRrtr(rrtr_blocks_, packet, index); | 1134 CreateRrtr(rrtr_blocks_, packet, index); |
| 1144 CreateDlrr(dlrr_blocks_, packet, index); | 1135 CreateDlrr(dlrr_blocks_, packet, index); |
| 1145 CreateVoipMetric(voip_metric_blocks_, packet, index); | 1136 CreateVoipMetric(voip_metric_blocks_, packet, index); |
| 1146 return true; | 1137 return true; |
| 1147 } | 1138 } |
| 1148 | 1139 |
| 1149 bool Xr::WithRrtr(Rrtr* rrtr) { | 1140 bool Xr::WithRrtr(Rrtr* rrtr) { |
| 1150 assert(rrtr); | 1141 assert(rrtr); |
| 1151 if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { | 1142 if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { |
| 1152 LOG(LS_WARNING) << "Max RRTR blocks reached."; | 1143 LOG(LS_WARNING) << "Max RRTR blocks reached."; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 return length_; | 1222 return length_; |
| 1232 } | 1223 } |
| 1233 | 1224 |
| 1234 void RawPacket::SetLength(size_t length) { | 1225 void RawPacket::SetLength(size_t length) { |
| 1235 assert(length <= buffer_length_); | 1226 assert(length <= buffer_length_); |
| 1236 length_ = length; | 1227 length_ = length; |
| 1237 } | 1228 } |
| 1238 | 1229 |
| 1239 } // namespace rtcp | 1230 } // namespace rtcp |
| 1240 } // namespace webrtc | 1231 } // namespace webrtc |
| OLD | NEW |