| 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 |