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

Side by Side Diff: media/cast/rtcp/rtcp_receiver.cc

Issue 83903002: Cast: Add capabity to parse receiver and sender log messages over RTCP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Re-upload Created 7 years 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 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/rtcp/rtcp_receiver.h" 5 #include "media/cast/rtcp/rtcp_receiver.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "media/cast/rtcp/rtcp_utility.h" 9 #include "media/cast/rtcp/rtcp_utility.h"
10 10
11 namespace {
12
13 media::cast::CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) {
14 switch (event) {
15 case 1:
16 return media::cast::kAckSent;
17 case 2:
18 return media::cast::kAudioPlayoutDelay;
19 case 3:
20 return media::cast::kAudioFrameDecoded;
21 case 4:
22 return media::cast::kVideoFrameDecoded;
23 case 5:
24 return media::cast::kVideoRenderDelay;
25 case 6:
26 return media::cast::kPacketReceived;
27 default:
28 // If the sender adds new log messages we will end up here until we add
29 // the new messages in the receiver.
30 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event);
31 NOTREACHED();
32 return media::cast::kUnknown;
33 }
34 }
35
36 media::cast::RtcpSenderFrameStatus TranslateToFrameStatusFromWireFormat(
37 uint8 status) {
38 switch (status) {
39 case 0:
40 return media::cast::kRtcpSenderFrameStatusUnknown;
41 case 1:
42 return media::cast::kRtcpSenderFrameStatusDroppedByEncoder;
43 case 2:
44 return media::cast::kRtcpSenderFrameStatusDroppedByFlowControl;
45 case 3:
46 return media::cast::kRtcpSenderFrameStatusSentToNetwork;
47 default:
48 // If the sender adds new log messages we will end up here until we add
49 // the new messages in the receiver.
50 NOTREACHED();
51 VLOG(1) << "Unexpected status received: " << static_cast<int>(status);
52 return media::cast::kRtcpSenderFrameStatusUnknown;
53 }
54 }
55
56 } // namespace
57
11 namespace media { 58 namespace media {
12 namespace cast { 59 namespace cast {
13 60
14 RtcpReceiver::RtcpReceiver(RtcpSenderFeedback* sender_feedback, 61 RtcpReceiver::RtcpReceiver(RtcpSenderFeedback* sender_feedback,
15 RtcpReceiverFeedback* receiver_feedback, 62 RtcpReceiverFeedback* receiver_feedback,
16 RtcpRttFeedback* rtt_feedback, 63 RtcpRttFeedback* rtt_feedback,
17 uint32 local_ssrc) 64 uint32 local_ssrc)
18 : ssrc_(local_ssrc), 65 : ssrc_(local_ssrc),
19 remote_ssrc_(0), 66 remote_ssrc_(0),
20 sender_feedback_(sender_feedback), 67 sender_feedback_(sender_feedback),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 break; 107 break;
61 case kRtcpPayloadSpecificRpsiCode: 108 case kRtcpPayloadSpecificRpsiCode:
62 HandleRpsi(rtcp_parser); 109 HandleRpsi(rtcp_parser);
63 break; 110 break;
64 case kRtcpPayloadSpecificFirCode: 111 case kRtcpPayloadSpecificFirCode:
65 HandleFIR(rtcp_parser); 112 HandleFIR(rtcp_parser);
66 break; 113 break;
67 case kRtcpPayloadSpecificAppCode: 114 case kRtcpPayloadSpecificAppCode:
68 HandlePayloadSpecificApp(rtcp_parser); 115 HandlePayloadSpecificApp(rtcp_parser);
69 break; 116 break;
117 case kRtcpApplicationSpecificCastReceiverLogCode:
118 HandleApplicationSpecificCastReceiverLog(rtcp_parser);
119 break;
120 case kRtcpApplicationSpecificCastSenderLogCode:
121 HandleApplicationSpecificCastSenderLog(rtcp_parser);
122 break;
70 case kRtcpPayloadSpecificRembCode: 123 case kRtcpPayloadSpecificRembCode:
71 case kRtcpPayloadSpecificRembItemCode: 124 case kRtcpPayloadSpecificRembItemCode:
72 // Ignore this until we want to support interop with webrtc.
73 rtcp_parser->Iterate();
74 break;
75 case kRtcpPayloadSpecificCastCode: 125 case kRtcpPayloadSpecificCastCode:
76 case kRtcpPayloadSpecificCastNackItemCode: 126 case kRtcpPayloadSpecificCastNackItemCode:
77 rtcp_parser->Iterate(); 127 case kRtcpApplicationSpecificCastReceiverLogFrameCode:
78 break; 128 case kRtcpApplicationSpecificCastReceiverLogEventCode:
79 case kRtcpNotValidCode: 129 case kRtcpNotValidCode:
80 case kRtcpReportBlockItemCode: 130 case kRtcpReportBlockItemCode:
81 case kRtcpSdesChunkCode: 131 case kRtcpSdesChunkCode:
82 case kRtcpGenericRtpFeedbackNackItemCode: 132 case kRtcpGenericRtpFeedbackNackItemCode:
83 case kRtcpPayloadSpecificFirItemCode: 133 case kRtcpPayloadSpecificFirItemCode:
84 case kRtcpXrRrtrCode: 134 case kRtcpXrRrtrCode:
85 case kRtcpXrDlrrCode: 135 case kRtcpXrDlrrCode:
86 case kRtcpXrUnknownItemCode: 136 case kRtcpXrUnknownItemCode:
87 rtcp_parser->Iterate(); 137 rtcp_parser->Iterate();
88 DCHECK(false) << "Invalid state"; 138 NOTREACHED() << "Invalid state";
89 break; 139 break;
90 } 140 }
91 field_type = rtcp_parser->FieldType(); 141 field_type = rtcp_parser->FieldType();
92 } 142 }
93 } 143 }
94 144
95 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) { 145 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) {
96 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType(); 146 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
97 const RtcpField& rtcp_field = rtcp_parser->Field(); 147 const RtcpField& rtcp_field = rtcp_parser->Field();
98 148
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 rtt_feedback_->OnReceivedDelaySinceLastReport( 298 rtt_feedback_->OnReceivedDelaySinceLastReport(
249 rtcp_field.dlrr.receivers_ssrc, 299 rtcp_field.dlrr.receivers_ssrc,
250 rtcp_field.dlrr.last_receiver_report, 300 rtcp_field.dlrr.last_receiver_report,
251 rtcp_field.dlrr.delay_last_receiver_report); 301 rtcp_field.dlrr.delay_last_receiver_report);
252 } 302 }
253 } 303 }
254 304
255 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) { 305 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) {
256 const RtcpField& rtcp_field = rtcp_parser->Field(); 306 const RtcpField& rtcp_field = rtcp_parser->Field();
257 if (ssrc_ != rtcp_field.nack.media_ssrc) { 307 if (ssrc_ != rtcp_field.nack.media_ssrc) {
258 // Not to us. 308 RtcpFieldTypes field_type;
259 rtcp_parser->Iterate(); 309 // Message not to us. Iterate until we have passed this message.
310 do {
311 field_type = rtcp_parser->Iterate();
312 } while (field_type == kRtcpGenericRtpFeedbackNackItemCode);
260 return; 313 return;
261 } 314 }
262 std::list<uint16> nackSequenceNumbers; 315 std::list<uint16> nackSequenceNumbers;
263 316
264 RtcpFieldTypes field_type = rtcp_parser->Iterate(); 317 RtcpFieldTypes field_type = rtcp_parser->Iterate();
265 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) { 318 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) {
266 HandleNACKItem(&rtcp_field, &nackSequenceNumbers); 319 HandleNACKItem(&rtcp_field, &nackSequenceNumbers);
267 field_type = rtcp_parser->Iterate(); 320 field_type = rtcp_parser->Iterate();
268 } 321 }
269 } 322 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 } 380 }
328 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f); 381 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f);
329 382
330 VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id; 383 VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id;
331 } 384 }
332 385
333 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) { 386 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) {
334 const RtcpField& rtcp_field = rtcp_parser->Field(); 387 const RtcpField& rtcp_field = rtcp_parser->Field();
335 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc; 388 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc;
336 if (remote_ssrc_ != remote_ssrc) { 389 if (remote_ssrc_ != remote_ssrc) {
337 // Message not to us. 390 // Message not to us. Iterate until we have passed this message.
338 rtcp_parser->Iterate(); 391 RtcpFieldTypes field_type;
392 do {
393 field_type = rtcp_parser->Iterate();
394 } while (field_type == kRtcpPayloadSpecificRembCode ||
395 field_type == kRtcpPayloadSpecificRembItemCode ||
396 field_type == kRtcpPayloadSpecificCastCode ||
397 field_type == kRtcpPayloadSpecificCastNackItemCode);
339 return; 398 return;
340 } 399 }
341 400
342 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); 401 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
343 switch (packet_type) { 402 switch (packet_type) {
344 case kRtcpPayloadSpecificRembCode: 403 case kRtcpPayloadSpecificRembCode:
345 packet_type = rtcp_parser->Iterate(); 404 packet_type = rtcp_parser->Iterate();
346 if (packet_type == kRtcpPayloadSpecificRembItemCode) { 405 if (packet_type == kRtcpPayloadSpecificRembItemCode) {
347 HandlePayloadSpecificRembItem(rtcp_parser); 406 HandlePayloadSpecificRembItem(rtcp_parser);
348 rtcp_parser->Iterate(); 407 rtcp_parser->Iterate();
(...skipping 16 matching lines...) Expand all
365 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) { 424 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) {
366 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) { 425 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) {
367 // Found matching ssrc. 426 // Found matching ssrc.
368 VLOG(1) << "Cast RTCP received REMB with received_bitrate " 427 VLOG(1) << "Cast RTCP received REMB with received_bitrate "
369 << rtcp_field.remb_item.bitrate; 428 << rtcp_field.remb_item.bitrate;
370 return; 429 return;
371 } 430 }
372 } 431 }
373 } 432 }
374 433
434 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog(
435 RtcpParser* rtcp_parser) {
436 const RtcpField& rtcp_field = rtcp_parser->Field();
437
438 uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc;
439 if (remote_ssrc_ != remote_ssrc) {
440 // Message not to us. Iterate until we have passed this message.
441 RtcpFieldTypes field_type;
442 do {
443 field_type = rtcp_parser->Iterate();
444 } while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode ||
445 field_type == kRtcpApplicationSpecificCastReceiverLogEventCode);
446 return;
447 }
448 RtcpReceiverLogMessage receiver_log;
449 RtcpFieldTypes field_type = rtcp_parser->Iterate();
450 while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode) {
451 RtcpReceiverFrameLogMessage frame_log(
452 rtcp_field.cast_receiver_log.rtp_timestamp);
453
454 field_type = rtcp_parser->Iterate();
455 while (field_type == kRtcpApplicationSpecificCastReceiverLogEventCode) {
456 HandleApplicationSpecificCastReceiverEventLog(rtcp_parser,
457 &frame_log.event_log_messages);
458 field_type = rtcp_parser->Iterate();
459 }
460 receiver_log.push_back(frame_log);
461 }
462
463 if (receiver_feedback_ && !receiver_log.empty()) {
464 receiver_feedback_->OnReceivedReceiverLog(receiver_log);
465 }
466 }
467
468 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog(
469 RtcpParser* rtcp_parser,
470 RtcpReceiverEventLogMessages* event_log_messages) {
471 const RtcpField& rtcp_field = rtcp_parser->Field();
472
473 RtcpReceiverEventLogMessage event_log;
474 event_log.type = TranslateToLogEventFromWireFormat(
475 rtcp_field.cast_receiver_log.event);
476 event_log.event_timestamp = base::TimeTicks() +
477 base::TimeDelta::FromMilliseconds(
478 rtcp_field.cast_receiver_log.event_timestamp_base +
479 rtcp_field.cast_receiver_log.event_timestamp_delta);
480 event_log.delay_delta = base::TimeDelta::FromMilliseconds(
481 rtcp_field.cast_receiver_log.delay_delta_or_packet_id);
482 event_log.packet_id =
483 rtcp_field.cast_receiver_log.delay_delta_or_packet_id;
484 event_log_messages->push_back(event_log);
485 }
486
487 void RtcpReceiver::HandleApplicationSpecificCastSenderLog(
488 RtcpParser* rtcp_parser) {
489 const RtcpField& rtcp_field = rtcp_parser->Field();
490 uint32 remote_ssrc = rtcp_field.cast_sender_log.sender_ssrc;
491
492 if (remote_ssrc_ != remote_ssrc) {
493 RtcpFieldTypes field_type;
494 // Message not to us. Iterate until we have passed this message.
495 do {
496 field_type = rtcp_parser->Iterate();
497 } while (field_type == kRtcpApplicationSpecificCastSenderLogCode);
498 return;
499 }
500 RtcpSenderLogMessage sender_log;
501
502 RtcpFieldTypes field_type = rtcp_parser->Iterate();
503 while (field_type == kRtcpApplicationSpecificCastSenderLogCode) {
504 const RtcpField& rtcp_field = rtcp_parser->Field();
505 RtcpSenderFrameLogMessage frame_log;
506 frame_log.frame_status =
507 TranslateToFrameStatusFromWireFormat(rtcp_field.cast_sender_log.status);
508 frame_log.rtp_timestamp = rtcp_field.cast_sender_log.rtp_timestamp;
509 sender_log.push_back(frame_log);
510 field_type = rtcp_parser->Iterate();
511 }
512 if (receiver_feedback_) {
513 receiver_feedback_->OnReceivedSenderLog(sender_log);
514 }
515 }
516
375 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) { 517 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) {
376 const RtcpField& rtcp_field = rtcp_parser->Field(); 518 const RtcpField& rtcp_field = rtcp_parser->Field();
377
378 RtcpCastMessage cast_message(remote_ssrc_); 519 RtcpCastMessage cast_message(remote_ssrc_);
379 cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId( 520 cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId(
380 rtcp_field.cast_item.last_frame_id); 521 rtcp_field.cast_item.last_frame_id);
381 522
382 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); 523 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
383 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) { 524 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) {
384 const RtcpField& rtcp_field = rtcp_parser->Field(); 525 const RtcpField& rtcp_field = rtcp_parser->Field();
385 HandlePayloadSpecificCastNackItem( 526 HandlePayloadSpecificCastNackItem(
386 &rtcp_field, &cast_message.missing_frames_and_packets_); 527 &rtcp_field, &cast_message.missing_frames_and_packets_);
387 packet_type = rtcp_parser->Iterate(); 528 packet_type = rtcp_parser->Iterate();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 579
439 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { 580 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) {
440 // Is it our sender that is requested to generate a new keyframe. 581 // Is it our sender that is requested to generate a new keyframe.
441 if (ssrc_ != rtcp_field->fir_item.ssrc) return; 582 if (ssrc_ != rtcp_field->fir_item.ssrc) return;
442 583
443 VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_; 584 VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_;
444 } 585 }
445 586
446 } // namespace cast 587 } // namespace cast
447 } // namespace media 588 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698