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(const ReportBlock& block) { | 779 bool SenderReport::WithReportBlock(const ReportBlock& block) { |
814 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | 780 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { |
815 LOG(LS_WARNING) << "Max report blocks reached."; | 781 LOG(LS_WARNING) << "Max report blocks reached."; |
816 return false; | 782 return false; |
817 } | 783 } |
818 report_blocks_.push_back(block.report_block_); | 784 report_blocks_.push_back(block.report_block_); |
819 sr_.NumberOfReportBlocks = report_blocks_.size(); | 785 sr_.NumberOfReportBlocks = report_blocks_.size(); |
820 return true; | 786 return true; |
821 } | 787 } |
822 | 788 |
823 bool ReceiverReport::Create(uint8_t* packet, | 789 bool ReceiverReport::Create(uint8_t* packet, |
824 size_t* index, | 790 size_t* index, |
825 size_t max_length, | 791 size_t max_length, |
826 RtcpPacket::PacketReadyCallback* callback) const { | 792 RtcpPacket::PacketReadyCallback* callback) const { |
827 while (*index + BlockLength() > max_length) { | 793 while (*index + BlockLength() > max_length) { |
828 if (!OnBufferFull(packet, index, callback)) | 794 if (!OnBufferFull(packet, index, callback)) |
829 return false; | 795 return false; |
830 } | 796 } |
831 CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, index); | 797 CreateHeader(rr_.NumberOfReportBlocks, PT_RR, HeaderLength(), packet, index); |
| 798 CreateReceiverReport(rr_, packet, index); |
832 CreateReportBlocks(report_blocks_, packet, index); | 799 CreateReportBlocks(report_blocks_, packet, index); |
833 return true; | 800 return true; |
834 } | 801 } |
835 | 802 |
836 bool ReceiverReport::WithReportBlock(const ReportBlock& block) { | 803 bool ReceiverReport::WithReportBlock(const ReportBlock& block) { |
837 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | 804 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { |
838 LOG(LS_WARNING) << "Max report blocks reached."; | 805 LOG(LS_WARNING) << "Max report blocks reached."; |
839 return false; | 806 return false; |
840 } | 807 } |
841 report_blocks_.push_back(block.report_block_); | 808 report_blocks_.push_back(block.report_block_); |
842 rr_.NumberOfReportBlocks = report_blocks_.size(); | 809 rr_.NumberOfReportBlocks = report_blocks_.size(); |
843 return true; | 810 return true; |
844 } | 811 } |
845 | 812 |
846 bool Ij::Create(uint8_t* packet, | 813 bool Ij::Create(uint8_t* packet, |
847 size_t* index, | 814 size_t* index, |
848 size_t max_length, | 815 size_t max_length, |
849 RtcpPacket::PacketReadyCallback* callback) const { | 816 RtcpPacket::PacketReadyCallback* callback) const { |
850 while (*index + BlockLength() > max_length) { | 817 while (*index + BlockLength() > max_length) { |
851 if (!OnBufferFull(packet, index, callback)) | 818 if (!OnBufferFull(packet, index, callback)) |
852 return false; | 819 return false; |
853 } | 820 } |
| 821 size_t length = ij_items_.size(); |
| 822 CreateHeader(length, PT_IJ, length, packet, index); |
854 CreateIj(ij_items_, packet, index); | 823 CreateIj(ij_items_, packet, index); |
855 return true; | 824 return true; |
856 } | 825 } |
857 | 826 |
858 bool Ij::WithJitterItem(uint32_t jitter) { | 827 bool Ij::WithJitterItem(uint32_t jitter) { |
859 if (ij_items_.size() >= kMaxNumberOfIjItems) { | 828 if (ij_items_.size() >= kMaxNumberOfIjItems) { |
860 LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; | 829 LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; |
861 return false; | 830 return false; |
862 } | 831 } |
863 ij_items_.push_back(jitter); | 832 ij_items_.push_back(jitter); |
864 return true; | 833 return true; |
865 } | 834 } |
866 | 835 |
867 bool Sdes::Create(uint8_t* packet, | 836 bool Sdes::Create(uint8_t* packet, |
868 size_t* index, | 837 size_t* index, |
869 size_t max_length, | 838 size_t max_length, |
870 RtcpPacket::PacketReadyCallback* callback) const { | 839 RtcpPacket::PacketReadyCallback* callback) const { |
871 assert(!chunks_.empty()); | 840 assert(!chunks_.empty()); |
872 while (*index + BlockLength() > max_length) { | 841 while (*index + BlockLength() > max_length) { |
873 if (!OnBufferFull(packet, index, callback)) | 842 if (!OnBufferFull(packet, index, callback)) |
874 return false; | 843 return false; |
875 } | 844 } |
876 CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, index); | 845 CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index); |
| 846 CreateSdes(chunks_, packet, index); |
877 return true; | 847 return true; |
878 } | 848 } |
879 | 849 |
880 bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { | 850 bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { |
881 assert(cname.length() <= 0xff); | 851 assert(cname.length() <= 0xff); |
882 if (chunks_.size() >= kMaxNumberOfChunks) { | 852 if (chunks_.size() >= kMaxNumberOfChunks) { |
883 LOG(LS_WARNING) << "Max SDES chunks reached."; | 853 LOG(LS_WARNING) << "Max SDES chunks reached."; |
884 return false; | 854 return false; |
885 } | 855 } |
886 // In each chunk, the list of items must be terminated by one or more null | 856 // In each chunk, the list of items must be terminated by one or more null |
(...skipping 20 matching lines...) Expand all Loading... |
907 } | 877 } |
908 | 878 |
909 bool Bye::Create(uint8_t* packet, | 879 bool Bye::Create(uint8_t* packet, |
910 size_t* index, | 880 size_t* index, |
911 size_t max_length, | 881 size_t max_length, |
912 RtcpPacket::PacketReadyCallback* callback) const { | 882 RtcpPacket::PacketReadyCallback* callback) const { |
913 while (*index + BlockLength() > max_length) { | 883 while (*index + BlockLength() > max_length) { |
914 if (!OnBufferFull(packet, index, callback)) | 884 if (!OnBufferFull(packet, index, callback)) |
915 return false; | 885 return false; |
916 } | 886 } |
917 CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, index); | 887 size_t length = HeaderLength(); |
| 888 CreateHeader(length, PT_BYE, length, packet, index); |
| 889 CreateBye(bye_, csrcs_, packet, index); |
918 return true; | 890 return true; |
919 } | 891 } |
920 | 892 |
921 bool Bye::WithCsrc(uint32_t csrc) { | 893 bool Bye::WithCsrc(uint32_t csrc) { |
922 if (csrcs_.size() >= kMaxNumberOfCsrcs) { | 894 if (csrcs_.size() >= kMaxNumberOfCsrcs) { |
923 LOG(LS_WARNING) << "Max CSRC size reached."; | 895 LOG(LS_WARNING) << "Max CSRC size reached."; |
924 return false; | 896 return false; |
925 } | 897 } |
926 csrcs_.push_back(csrc); | 898 csrcs_.push_back(csrc); |
927 return true; | 899 return true; |
928 } | 900 } |
929 | 901 |
930 bool App::Create(uint8_t* packet, | 902 bool App::Create(uint8_t* packet, |
931 size_t* index, | 903 size_t* index, |
932 size_t max_length, | 904 size_t max_length, |
933 RtcpPacket::PacketReadyCallback* callback) const { | 905 RtcpPacket::PacketReadyCallback* callback) const { |
934 while (*index + BlockLength() > max_length) { | 906 while (*index + BlockLength() > max_length) { |
935 if (!OnBufferFull(packet, index, callback)) | 907 if (!OnBufferFull(packet, index, callback)) |
936 return false; | 908 return false; |
937 } | 909 } |
938 CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, index); | 910 CreateHeader(app_.SubType, PT_APP, HeaderLength(), packet, index); |
| 911 CreateApp(app_, ssrc_, packet, index); |
939 return true; | 912 return true; |
940 } | 913 } |
941 | 914 |
942 bool Pli::Create(uint8_t* packet, | 915 bool Pli::Create(uint8_t* packet, |
943 size_t* index, | 916 size_t* index, |
944 size_t max_length, | 917 size_t max_length, |
945 RtcpPacket::PacketReadyCallback* callback) const { | 918 RtcpPacket::PacketReadyCallback* callback) const { |
946 while (*index + BlockLength() > max_length) { | 919 while (*index + BlockLength() > max_length) { |
947 if (!OnBufferFull(packet, index, callback)) | 920 if (!OnBufferFull(packet, index, callback)) |
948 return false; | 921 return false; |
949 } | 922 } |
950 CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, index); | 923 const uint8_t kFmt = 1; |
| 924 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 925 CreatePli(pli_, packet, index); |
951 return true; | 926 return true; |
952 } | 927 } |
953 | 928 |
954 bool Sli::Create(uint8_t* packet, | 929 bool Sli::Create(uint8_t* packet, |
955 size_t* index, | 930 size_t* index, |
956 size_t max_length, | 931 size_t max_length, |
957 RtcpPacket::PacketReadyCallback* callback) const { | 932 RtcpPacket::PacketReadyCallback* callback) const { |
958 while (*index + BlockLength() > max_length) { | 933 while (*index + BlockLength() > max_length) { |
959 if (!OnBufferFull(packet, index, callback)) | 934 if (!OnBufferFull(packet, index, callback)) |
960 return false; | 935 return false; |
961 } | 936 } |
962 CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet, index); | 937 const uint8_t kFmt = 2; |
| 938 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 939 CreateSli(sli_, sli_item_, packet, index); |
963 return true; | 940 return true; |
964 } | 941 } |
965 | 942 |
966 bool Nack::Create(uint8_t* packet, | 943 bool Nack::Create(uint8_t* packet, |
967 size_t* index, | 944 size_t* index, |
968 size_t max_length, | 945 size_t max_length, |
969 RtcpPacket::PacketReadyCallback* callback) const { | 946 RtcpPacket::PacketReadyCallback* callback) const { |
970 assert(!nack_fields_.empty()); | 947 assert(!nack_fields_.empty()); |
971 // If nack list can't fit in packet, try to fragment. | 948 // If nack list can't fit in packet, try to fragment. |
972 size_t nack_index = 0; | 949 size_t nack_index = 0; |
973 do { | 950 do { |
974 size_t bytes_left_in_buffer = max_length - *index; | 951 size_t bytes_left_in_buffer = max_length - *index; |
975 if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { | 952 if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { |
976 if (!OnBufferFull(packet, index, callback)) | 953 if (!OnBufferFull(packet, index, callback)) |
977 return false; | 954 return false; |
978 continue; | 955 continue; |
979 } | 956 } |
980 int64_t num_nack_fields = | 957 int64_t num_nack_fields = |
981 std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, | 958 std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, |
982 nack_fields_.size() - nack_index); | 959 nack_fields_.size() - nack_index); |
983 | 960 |
| 961 const uint8_t kFmt = 1; |
| 962 size_t size_bytes = (num_nack_fields * 4) + kCommonFbFmtLength; |
| 963 size_t header_length = ((size_bytes + 3) / 4) - 1; // As 32bit words - 1 |
| 964 CreateHeader(kFmt, PT_RTPFB, header_length, packet, index); |
984 CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, | 965 CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, |
985 BlockToHeaderLength((num_nack_fields * 4) + kCommonFbFmtLength), | |
986 packet, index); | 966 packet, index); |
987 | 967 |
988 nack_index += num_nack_fields; | 968 nack_index += num_nack_fields; |
989 } while (nack_index < nack_fields_.size()); | 969 } while (nack_index < nack_fields_.size()); |
990 | 970 |
991 return true; | 971 return true; |
992 } | 972 } |
993 | 973 |
| 974 size_t Nack::BlockLength() const { |
| 975 return (nack_fields_.size() * 4) + kCommonFbFmtLength; |
| 976 } |
| 977 |
994 void Nack::WithList(const uint16_t* nack_list, int length) { | 978 void Nack::WithList(const uint16_t* nack_list, int length) { |
995 assert(nack_list); | 979 assert(nack_list); |
996 assert(nack_fields_.empty()); | 980 assert(nack_fields_.empty()); |
997 int i = 0; | 981 int i = 0; |
998 while (i < length) { | 982 while (i < length) { |
999 uint16_t pid = nack_list[i++]; | 983 uint16_t pid = nack_list[i++]; |
1000 // Bitmask specifies losses in any of the 16 packets following the pid. | 984 // Bitmask specifies losses in any of the 16 packets following the pid. |
1001 uint16_t bitmask = 0; | 985 uint16_t bitmask = 0; |
1002 while (i < length) { | 986 while (i < length) { |
1003 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; | 987 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; |
(...skipping 13 matching lines...) Expand all Loading... |
1017 | 1001 |
1018 bool Rpsi::Create(uint8_t* packet, | 1002 bool Rpsi::Create(uint8_t* packet, |
1019 size_t* index, | 1003 size_t* index, |
1020 size_t max_length, | 1004 size_t max_length, |
1021 RtcpPacket::PacketReadyCallback* callback) const { | 1005 RtcpPacket::PacketReadyCallback* callback) const { |
1022 assert(rpsi_.NumberOfValidBits > 0); | 1006 assert(rpsi_.NumberOfValidBits > 0); |
1023 while (*index + BlockLength() > max_length) { | 1007 while (*index + BlockLength() > max_length) { |
1024 if (!OnBufferFull(packet, index, callback)) | 1008 if (!OnBufferFull(packet, index, callback)) |
1025 return false; | 1009 return false; |
1026 } | 1010 } |
1027 CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(BlockLength()), packet, | 1011 const uint8_t kFmt = 3; |
1028 index); | 1012 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 1013 CreateRpsi(rpsi_, padding_bytes_, packet, index); |
1029 return true; | 1014 return true; |
1030 } | 1015 } |
1031 | 1016 |
1032 void Rpsi::WithPictureId(uint64_t picture_id) { | 1017 void Rpsi::WithPictureId(uint64_t picture_id) { |
1033 const uint32_t kPidBits = 7; | 1018 const uint32_t kPidBits = 7; |
1034 const uint64_t k7MsbZeroMask = 0x1ffffffffffffffULL; | 1019 const uint64_t k7MsbZeroMask = 0x1ffffffffffffffULL; |
1035 uint8_t required_bytes = 0; | 1020 uint8_t required_bytes = 0; |
1036 uint64_t shifted_pid = picture_id; | 1021 uint64_t shifted_pid = picture_id; |
1037 do { | 1022 do { |
1038 ++required_bytes; | 1023 ++required_bytes; |
(...skipping 18 matching lines...) Expand all Loading... |
1057 } | 1042 } |
1058 | 1043 |
1059 bool Fir::Create(uint8_t* packet, | 1044 bool Fir::Create(uint8_t* packet, |
1060 size_t* index, | 1045 size_t* index, |
1061 size_t max_length, | 1046 size_t max_length, |
1062 RtcpPacket::PacketReadyCallback* callback) const { | 1047 RtcpPacket::PacketReadyCallback* callback) const { |
1063 while (*index + BlockLength() > max_length) { | 1048 while (*index + BlockLength() > max_length) { |
1064 if (!OnBufferFull(packet, index, callback)) | 1049 if (!OnBufferFull(packet, index, callback)) |
1065 return false; | 1050 return false; |
1066 } | 1051 } |
1067 CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet, index); | 1052 const uint8_t kFmt = 4; |
| 1053 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 1054 CreateFir(fir_, fir_item_, packet, index); |
1068 return true; | 1055 return true; |
1069 } | 1056 } |
1070 | 1057 |
1071 bool Remb::Create(uint8_t* packet, | 1058 bool Remb::Create(uint8_t* packet, |
1072 size_t* index, | 1059 size_t* index, |
1073 size_t max_length, | 1060 size_t max_length, |
1074 RtcpPacket::PacketReadyCallback* callback) const { | 1061 RtcpPacket::PacketReadyCallback* callback) const { |
1075 while (*index + BlockLength() > max_length) { | 1062 while (*index + BlockLength() > max_length) { |
1076 if (!OnBufferFull(packet, index, callback)) | 1063 if (!OnBufferFull(packet, index, callback)) |
1077 return false; | 1064 return false; |
1078 } | 1065 } |
1079 CreateRemb(remb_, remb_item_, BlockToHeaderLength(BlockLength()), packet, | 1066 const uint8_t kFmt = 15; |
1080 index); | 1067 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
| 1068 CreateRemb(remb_, remb_item_, packet, index); |
1081 return true; | 1069 return true; |
1082 } | 1070 } |
1083 | 1071 |
1084 void Remb::AppliesTo(uint32_t ssrc) { | 1072 void Remb::AppliesTo(uint32_t ssrc) { |
1085 if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) { | 1073 if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) { |
1086 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached."; | 1074 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached."; |
1087 return; | 1075 return; |
1088 } | 1076 } |
1089 remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; | 1077 remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; |
1090 } | 1078 } |
1091 | 1079 |
1092 bool Tmmbr::Create(uint8_t* packet, | 1080 bool Tmmbr::Create(uint8_t* packet, |
1093 size_t* index, | 1081 size_t* index, |
1094 size_t max_length, | 1082 size_t max_length, |
1095 RtcpPacket::PacketReadyCallback* callback) const { | 1083 RtcpPacket::PacketReadyCallback* callback) const { |
1096 while (*index + BlockLength() > max_length) { | 1084 while (*index + BlockLength() > max_length) { |
1097 if (!OnBufferFull(packet, index, callback)) | 1085 if (!OnBufferFull(packet, index, callback)) |
1098 return false; | 1086 return false; |
1099 } | 1087 } |
1100 CreateTmmbr(tmmbr_, tmmbr_item_, BlockToHeaderLength(BlockLength()), packet, | 1088 const uint8_t kFmt = 3; |
1101 index); | 1089 CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index); |
| 1090 CreateTmmbr(tmmbr_, tmmbr_item_, packet, index); |
1102 return true; | 1091 return true; |
1103 } | 1092 } |
1104 | 1093 |
1105 bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { | 1094 bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { |
1106 assert(overhead <= 0x1ff); | 1095 assert(overhead <= 0x1ff); |
1107 if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { | 1096 if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { |
1108 LOG(LS_WARNING) << "Max TMMBN size reached."; | 1097 LOG(LS_WARNING) << "Max TMMBN size reached."; |
1109 return false; | 1098 return false; |
1110 } | 1099 } |
1111 RTCPPacketRTPFBTMMBRItem tmmbn_item; | 1100 RTCPPacketRTPFBTMMBRItem tmmbn_item; |
1112 tmmbn_item.SSRC = ssrc; | 1101 tmmbn_item.SSRC = ssrc; |
1113 tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; | 1102 tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; |
1114 tmmbn_item.MeasuredOverhead = overhead; | 1103 tmmbn_item.MeasuredOverhead = overhead; |
1115 tmmbn_items_.push_back(tmmbn_item); | 1104 tmmbn_items_.push_back(tmmbn_item); |
1116 return true; | 1105 return true; |
1117 } | 1106 } |
1118 | 1107 |
1119 bool Tmmbn::Create(uint8_t* packet, | 1108 bool Tmmbn::Create(uint8_t* packet, |
1120 size_t* index, | 1109 size_t* index, |
1121 size_t max_length, | 1110 size_t max_length, |
1122 RtcpPacket::PacketReadyCallback* callback) const { | 1111 RtcpPacket::PacketReadyCallback* callback) const { |
1123 while (*index + BlockLength() > max_length) { | 1112 while (*index + BlockLength() > max_length) { |
1124 if (!OnBufferFull(packet, index, callback)) | 1113 if (!OnBufferFull(packet, index, callback)) |
1125 return false; | 1114 return false; |
1126 } | 1115 } |
1127 CreateTmmbn(tmmbn_, tmmbn_items_, BlockToHeaderLength(BlockLength()), packet, | 1116 const uint8_t kFmt = 4; |
1128 index); | 1117 CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index); |
| 1118 CreateTmmbn(tmmbn_, tmmbn_items_, packet, index); |
1129 return true; | 1119 return true; |
1130 } | 1120 } |
1131 | 1121 |
1132 bool Xr::Create(uint8_t* packet, | 1122 bool Xr::Create(uint8_t* packet, |
1133 size_t* index, | 1123 size_t* index, |
1134 size_t max_length, | 1124 size_t max_length, |
1135 RtcpPacket::PacketReadyCallback* callback) const { | 1125 RtcpPacket::PacketReadyCallback* callback) const { |
1136 while (*index + BlockLength() > max_length) { | 1126 while (*index + BlockLength() > max_length) { |
1137 if (!OnBufferFull(packet, index, callback)) | 1127 if (!OnBufferFull(packet, index, callback)) |
1138 return false; | 1128 return false; |
1139 } | 1129 } |
1140 CreateXrHeader(xr_header_, BlockToHeaderLength(BlockLength()), packet, index); | 1130 CreateHeader(0U, PT_XR, HeaderLength(), packet, index); |
| 1131 CreateXrHeader(xr_header_, packet, index); |
1141 CreateRrtr(rrtr_blocks_, packet, index); | 1132 CreateRrtr(rrtr_blocks_, packet, index); |
1142 CreateDlrr(dlrr_blocks_, packet, index); | 1133 CreateDlrr(dlrr_blocks_, packet, index); |
1143 CreateVoipMetric(voip_metric_blocks_, packet, index); | 1134 CreateVoipMetric(voip_metric_blocks_, packet, index); |
1144 return true; | 1135 return true; |
1145 } | 1136 } |
1146 | 1137 |
1147 bool Xr::WithRrtr(Rrtr* rrtr) { | 1138 bool Xr::WithRrtr(Rrtr* rrtr) { |
1148 assert(rrtr); | 1139 assert(rrtr); |
1149 if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { | 1140 if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { |
1150 LOG(LS_WARNING) << "Max RRTR blocks reached."; | 1141 LOG(LS_WARNING) << "Max RRTR blocks reached."; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 return length_; | 1220 return length_; |
1230 } | 1221 } |
1231 | 1222 |
1232 void RawPacket::SetLength(size_t length) { | 1223 void RawPacket::SetLength(size_t length) { |
1233 assert(length <= buffer_length_); | 1224 assert(length <= buffer_length_); |
1234 length_ = length; | 1225 length_ = length; |
1235 } | 1226 } |
1236 | 1227 |
1237 } // namespace rtcp | 1228 } // namespace rtcp |
1238 } // namespace webrtc | 1229 } // namespace webrtc |
OLD | NEW |