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 |