Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(620)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtcp_packet.cc

Issue 1175263002: Add packetization and coding/decoding of feedback message format. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Make size constants unsigned Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtcp_packet.h ('k') | webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698