OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/net/rtcp/rtcp_receiver.h" | 5 #include "media/cast/net/rtcp/rtcp_receiver.h" |
6 | 6 |
7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/cast/net/cast_transport_defines.h" | 9 #include "media/cast/net/cast_transport_defines.h" |
10 #include "media/cast/net/rtcp/rtcp_utility.h" | 10 #include "media/cast/net/rtcp/rtcp_utility.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 while (field_type != kRtcpNotValidCode) { | 88 while (field_type != kRtcpNotValidCode) { |
89 // Each "case" is responsible for iterate the parser to the next top | 89 // Each "case" is responsible for iterate the parser to the next top |
90 // level packet. | 90 // level packet. |
91 switch (field_type) { | 91 switch (field_type) { |
92 case kRtcpSrCode: | 92 case kRtcpSrCode: |
93 HandleSenderReport(rtcp_parser); | 93 HandleSenderReport(rtcp_parser); |
94 break; | 94 break; |
95 case kRtcpRrCode: | 95 case kRtcpRrCode: |
96 HandleReceiverReport(rtcp_parser); | 96 HandleReceiverReport(rtcp_parser); |
97 break; | 97 break; |
98 case kRtcpSdesCode: | |
99 HandleSDES(rtcp_parser); | |
100 break; | |
101 case kRtcpByeCode: | |
102 HandleBYE(rtcp_parser); | |
103 break; | |
104 case kRtcpXrCode: | 98 case kRtcpXrCode: |
105 HandleXr(rtcp_parser); | 99 HandleXr(rtcp_parser); |
106 break; | 100 break; |
107 case kRtcpGenericRtpFeedbackNackCode: | |
108 HandleNACK(rtcp_parser); | |
109 break; | |
110 case kRtcpPayloadSpecificPliCode: | |
111 HandlePLI(rtcp_parser); | |
112 break; | |
113 case kRtcpPayloadSpecificRpsiCode: | |
114 HandleRpsi(rtcp_parser); | |
115 break; | |
116 case kRtcpPayloadSpecificFirCode: | |
117 HandleFIR(rtcp_parser); | |
118 break; | |
119 case kRtcpPayloadSpecificAppCode: | 101 case kRtcpPayloadSpecificAppCode: |
120 HandlePayloadSpecificApp(rtcp_parser); | 102 HandlePayloadSpecificApp(rtcp_parser); |
121 break; | 103 break; |
122 case kRtcpApplicationSpecificCastReceiverLogCode: | 104 case kRtcpApplicationSpecificCastReceiverLogCode: |
123 HandleApplicationSpecificCastReceiverLog(rtcp_parser); | 105 HandleApplicationSpecificCastReceiverLog(rtcp_parser); |
124 break; | 106 break; |
125 case kRtcpPayloadSpecificRembCode: | |
126 case kRtcpPayloadSpecificRembItemCode: | |
127 case kRtcpPayloadSpecificCastCode: | 107 case kRtcpPayloadSpecificCastCode: |
128 case kRtcpPayloadSpecificCastNackItemCode: | 108 case kRtcpPayloadSpecificCastNackItemCode: |
129 case kRtcpApplicationSpecificCastReceiverLogFrameCode: | 109 case kRtcpApplicationSpecificCastReceiverLogFrameCode: |
130 case kRtcpApplicationSpecificCastReceiverLogEventCode: | 110 case kRtcpApplicationSpecificCastReceiverLogEventCode: |
131 case kRtcpNotValidCode: | 111 case kRtcpNotValidCode: |
132 case kRtcpReportBlockItemCode: | 112 case kRtcpReportBlockItemCode: |
133 case kRtcpSdesChunkCode: | |
134 case kRtcpGenericRtpFeedbackSrReqCode: | |
135 case kRtcpGenericRtpFeedbackNackItemCode: | |
136 case kRtcpPayloadSpecificFirItemCode: | |
137 case kRtcpXrRrtrCode: | 113 case kRtcpXrRrtrCode: |
138 case kRtcpXrDlrrCode: | 114 case kRtcpXrDlrrCode: |
139 case kRtcpXrUnknownItemCode: | 115 case kRtcpXrUnknownItemCode: |
140 rtcp_parser->Iterate(); | 116 rtcp_parser->Iterate(); |
141 NOTREACHED() << "Invalid state"; | 117 NOTREACHED() << "Invalid state"; |
142 break; | 118 break; |
143 } | 119 } |
144 field_type = rtcp_parser->FieldType(); | 120 field_type = rtcp_parser->FieldType(); |
145 } | 121 } |
146 } | 122 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 report_block.cumulative_lost = rb.cumulative_number_of_packets_lost; | 196 report_block.cumulative_lost = rb.cumulative_number_of_packets_lost; |
221 report_block.extended_high_sequence_number = | 197 report_block.extended_high_sequence_number = |
222 rb.extended_highest_sequence_number; | 198 rb.extended_highest_sequence_number; |
223 report_block.jitter = rb.jitter; | 199 report_block.jitter = rb.jitter; |
224 report_block.last_sr = rb.last_sender_report; | 200 report_block.last_sr = rb.last_sender_report; |
225 report_block.delay_since_last_sr = rb.delay_last_sender_report; | 201 report_block.delay_since_last_sr = rb.delay_last_sender_report; |
226 handler_->OnReceivedDelaySinceLastReport( | 202 handler_->OnReceivedDelaySinceLastReport( |
227 rb.last_sender_report, rb.delay_last_sender_report); | 203 rb.last_sender_report, rb.delay_last_sender_report); |
228 } | 204 } |
229 | 205 |
230 void RtcpReceiver::HandleSDES(RtcpParser* rtcp_parser) { | |
231 RtcpFieldTypes field_type = rtcp_parser->Iterate(); | |
232 while (field_type == kRtcpSdesChunkCode) { | |
233 HandleSDESChunk(rtcp_parser); | |
234 field_type = rtcp_parser->Iterate(); | |
235 } | |
236 } | |
237 | |
238 void RtcpReceiver::HandleSDESChunk(RtcpParser* rtcp_parser) { | |
239 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
240 VLOG(2) << "Cast RTCP received SDES with cname " << rtcp_field.c_name.name; | |
241 } | |
242 | |
243 void RtcpReceiver::HandleXr(RtcpParser* rtcp_parser) { | 206 void RtcpReceiver::HandleXr(RtcpParser* rtcp_parser) { |
244 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType(); | 207 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType(); |
245 const RtcpField& rtcp_field = rtcp_parser->Field(); | 208 const RtcpField& rtcp_field = rtcp_parser->Field(); |
246 | 209 |
247 DCHECK(rtcp_field_type == kRtcpXrCode) << "Invalid state"; | 210 DCHECK(rtcp_field_type == kRtcpXrCode) << "Invalid state"; |
248 | 211 |
249 uint32 remote_ssrc = rtcp_field.extended_report.sender_ssrc; | 212 uint32 remote_ssrc = rtcp_field.extended_report.sender_ssrc; |
250 rtcp_field_type = rtcp_parser->Iterate(); | 213 rtcp_field_type = rtcp_parser->Iterate(); |
251 | 214 |
252 while (rtcp_field_type == kRtcpXrDlrrCode || | 215 while (rtcp_field_type == kRtcpXrDlrrCode || |
(...skipping 25 matching lines...) Expand all Loading... |
278 const RtcpField& rtcp_field = rtcp_parser->Field(); | 241 const RtcpField& rtcp_field = rtcp_parser->Field(); |
279 if (remote_ssrc_ != rtcp_field.dlrr.receivers_ssrc) { | 242 if (remote_ssrc_ != rtcp_field.dlrr.receivers_ssrc) { |
280 // Not to us. | 243 // Not to us. |
281 return; | 244 return; |
282 } | 245 } |
283 handler_->OnReceivedDelaySinceLastReport( | 246 handler_->OnReceivedDelaySinceLastReport( |
284 rtcp_field.dlrr.last_receiver_report, | 247 rtcp_field.dlrr.last_receiver_report, |
285 rtcp_field.dlrr.delay_last_receiver_report); | 248 rtcp_field.dlrr.delay_last_receiver_report); |
286 } | 249 } |
287 | 250 |
288 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) { | |
289 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
290 if (ssrc_ != rtcp_field.nack.media_ssrc) { | |
291 RtcpFieldTypes field_type; | |
292 // Message not to us. Iterate until we have passed this message. | |
293 do { | |
294 field_type = rtcp_parser->Iterate(); | |
295 } while (field_type == kRtcpGenericRtpFeedbackNackItemCode); | |
296 return; | |
297 } | |
298 std::list<uint16> nackSequenceNumbers; | |
299 | |
300 RtcpFieldTypes field_type = rtcp_parser->Iterate(); | |
301 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) { | |
302 HandleNACKItem(&rtcp_field, &nackSequenceNumbers); | |
303 field_type = rtcp_parser->Iterate(); | |
304 } | |
305 } | |
306 | |
307 void RtcpReceiver::HandleNACKItem(const RtcpField* rtcp_field, | |
308 std::list<uint16>* nack_sequence_numbers) { | |
309 nack_sequence_numbers->push_back(rtcp_field->nack_item.packet_id); | |
310 | |
311 uint16 bitmask = rtcp_field->nack_item.bitmask; | |
312 if (bitmask) { | |
313 for (int i = 1; i <= 16; ++i) { | |
314 if (bitmask & 1) { | |
315 nack_sequence_numbers->push_back(rtcp_field->nack_item.packet_id + i); | |
316 } | |
317 bitmask = bitmask >> 1; | |
318 } | |
319 } | |
320 } | |
321 | |
322 void RtcpReceiver::HandleBYE(RtcpParser* rtcp_parser) { | |
323 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
324 uint32 remote_ssrc = rtcp_field.bye.sender_ssrc; | |
325 if (remote_ssrc_ == remote_ssrc) { | |
326 VLOG(2) << "Cast RTCP received BYE from SSRC " << remote_ssrc; | |
327 } | |
328 rtcp_parser->Iterate(); | |
329 } | |
330 | |
331 void RtcpReceiver::HandlePLI(RtcpParser* rtcp_parser) { | |
332 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
333 if (ssrc_ == rtcp_field.pli.media_ssrc) { | |
334 // Received a signal that we need to send a new key frame. | |
335 VLOG(2) << "Cast RTCP received PLI on our SSRC " << ssrc_; | |
336 } | |
337 rtcp_parser->Iterate(); | |
338 } | |
339 | |
340 void RtcpReceiver::HandleRpsi(RtcpParser* rtcp_parser) { | |
341 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
342 if (rtcp_parser->Iterate() != kRtcpPayloadSpecificRpsiCode) { | |
343 return; | |
344 } | |
345 if (rtcp_field.rpsi.number_of_valid_bits % 8 != 0) { | |
346 // Continue | |
347 return; | |
348 } | |
349 uint64 rpsi_picture_id = 0; | |
350 | |
351 // Convert native_bit_string to rpsi_picture_id | |
352 uint8 bytes = rtcp_field.rpsi.number_of_valid_bits / 8; | |
353 for (uint8 n = 0; n < (bytes - 1); ++n) { | |
354 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[n] & 0x7f); | |
355 rpsi_picture_id <<= 7; // Prepare next. | |
356 } | |
357 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f); | |
358 | |
359 VLOG(2) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id; | |
360 } | |
361 | |
362 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) { | 251 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) { |
363 const RtcpField& rtcp_field = rtcp_parser->Field(); | 252 const RtcpField& rtcp_field = rtcp_parser->Field(); |
364 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc; | 253 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc; |
365 if (remote_ssrc_ != remote_ssrc) { | 254 if (remote_ssrc_ != remote_ssrc) { |
366 // Message not to us. Iterate until we have passed this message. | 255 // Message not to us. Iterate until we have passed this message. |
367 RtcpFieldTypes field_type; | 256 RtcpFieldTypes field_type; |
368 do { | 257 do { |
369 field_type = rtcp_parser->Iterate(); | 258 field_type = rtcp_parser->Iterate(); |
370 } while (field_type == kRtcpPayloadSpecificRembCode || | 259 } while (field_type == kRtcpPayloadSpecificCastCode || |
371 field_type == kRtcpPayloadSpecificRembItemCode || | |
372 field_type == kRtcpPayloadSpecificCastCode || | |
373 field_type == kRtcpPayloadSpecificCastNackItemCode); | 260 field_type == kRtcpPayloadSpecificCastNackItemCode); |
374 return; | 261 return; |
375 } | 262 } |
376 | 263 |
377 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); | 264 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); |
378 switch (packet_type) { | 265 switch (packet_type) { |
379 case kRtcpPayloadSpecificRembCode: | |
380 packet_type = rtcp_parser->Iterate(); | |
381 if (packet_type == kRtcpPayloadSpecificRembItemCode) { | |
382 HandlePayloadSpecificRembItem(rtcp_parser); | |
383 rtcp_parser->Iterate(); | |
384 } | |
385 break; | |
386 case kRtcpPayloadSpecificCastCode: | 266 case kRtcpPayloadSpecificCastCode: |
387 packet_type = rtcp_parser->Iterate(); | 267 packet_type = rtcp_parser->Iterate(); |
388 if (packet_type == kRtcpPayloadSpecificCastCode) { | 268 if (packet_type == kRtcpPayloadSpecificCastCode) { |
389 HandlePayloadSpecificCastItem(rtcp_parser); | 269 HandlePayloadSpecificCastItem(rtcp_parser); |
390 } | 270 } |
391 break; | 271 break; |
392 default: | 272 default: |
393 return; | 273 return; |
394 } | 274 } |
395 } | 275 } |
396 | 276 |
397 void RtcpReceiver::HandlePayloadSpecificRembItem(RtcpParser* rtcp_parser) { | |
398 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
399 | |
400 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) { | |
401 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) { | |
402 // Found matching ssrc. | |
403 VLOG(2) << "Cast RTCP received REMB with received_bitrate " | |
404 << rtcp_field.remb_item.bitrate; | |
405 return; | |
406 } | |
407 } | |
408 } | |
409 | |
410 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog( | 277 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog( |
411 RtcpParser* rtcp_parser) { | 278 RtcpParser* rtcp_parser) { |
412 const RtcpField& rtcp_field = rtcp_parser->Field(); | 279 const RtcpField& rtcp_field = rtcp_parser->Field(); |
413 | 280 |
414 uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc; | 281 uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc; |
415 if (remote_ssrc_ != remote_ssrc) { | 282 if (remote_ssrc_ != remote_ssrc) { |
416 // Message not to us. Iterate until we have passed this message. | 283 // Message not to us. Iterate until we have passed this message. |
417 RtcpFieldTypes field_type; | 284 RtcpFieldTypes field_type; |
418 do { | 285 do { |
419 field_type = rtcp_parser->Iterate(); | 286 field_type = rtcp_parser->Iterate(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 if (bitmask) { | 403 if (bitmask) { |
537 for (int i = 1; i <= 8; ++i) { | 404 for (int i = 1; i <= 8; ++i) { |
538 if (bitmask & 1) { | 405 if (bitmask & 1) { |
539 frame_it->second.insert(packet_id + i); | 406 frame_it->second.insert(packet_id + i); |
540 } | 407 } |
541 bitmask = bitmask >> 1; | 408 bitmask = bitmask >> 1; |
542 } | 409 } |
543 } | 410 } |
544 } | 411 } |
545 | 412 |
546 void RtcpReceiver::HandleFIR(RtcpParser* rtcp_parser) { | |
547 const RtcpField& rtcp_field = rtcp_parser->Field(); | |
548 | |
549 RtcpFieldTypes field_type = rtcp_parser->Iterate(); | |
550 while (field_type == kRtcpPayloadSpecificFirItemCode) { | |
551 HandleFIRItem(&rtcp_field); | |
552 field_type = rtcp_parser->Iterate(); | |
553 } | |
554 } | |
555 | |
556 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { | |
557 // Is it our sender that is requested to generate a new keyframe. | |
558 if (ssrc_ != rtcp_field->fir_item.ssrc) | |
559 return; | |
560 | |
561 VLOG(2) << "Cast RTCP received FIR on our SSRC " << ssrc_; | |
562 } | |
563 | |
564 } // namespace cast | 413 } // namespace cast |
565 } // namespace media | 414 } // namespace media |
OLD | NEW |