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

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: Merge TOT Created 7 years, 1 month 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
« no previous file with comments | « media/cast/rtcp/rtcp_receiver.h ('k') | media/cast/rtcp/rtcp_receiver_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/logging.h" 7 #include "base/logging.h"
8 #include "media/cast/rtcp/rtcp_utility.h" 8 #include "media/cast/rtcp/rtcp_utility.h"
9 9
10 namespace {
11
12 media::cast::CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) {
13 switch (event) {
14 case 1:
15 return media::cast::kAckSent;
16 case 2:
17 return media::cast::kAudioPlayoutDelay;
18 case 3:
19 return media::cast::kAudioFrameDecoded;
20 case 4:
21 return media::cast::kVideoFrameDecoded;
22 case 5:
23 return media::cast::kVideoRenderDelay;
24 case 6:
25 return media::cast::kPacketReceived;
26 default:
27 // If the sender adds new log messages we will end up here until we add
28 // the new messages in the receiver.
29 VLOG(1) << "Unexpected log message received: " << static_cast<int>(event);
30 NOTREACHED();
31 return media::cast::kUnknown;
32 }
33 }
34
35 media::cast::RtcpSenderFrameStatus TranslateToFrameStatusFromWireFormat(
36 uint8 status) {
37 switch (status) {
38 case 0:
39 return media::cast::kRtcpSenderFrameStatusUnknown;
40 case 1:
41 return media::cast::kRtcpSenderFrameStatusDroppedByEncoder;
42 case 2:
43 return media::cast::kRtcpSenderFrameStatusDroppedByFlowControl;
44 case 3:
45 return media::cast::kRtcpSenderFrameStatusSentToNetwork;
46 default:
47 // If the sender adds new log messages we will end up here until we add
48 // the new messages in the receiver.
49 NOTREACHED();
50 VLOG(1) << "Unexpected status received: " << static_cast<int>(status);
51 return media::cast::kRtcpSenderFrameStatusUnknown;
52 }
53 }
54
55 } // namespace
56
10 namespace media { 57 namespace media {
11 namespace cast { 58 namespace cast {
12 59
13 RtcpReceiver::RtcpReceiver(scoped_refptr<CastEnvironment> cast_environment, 60 RtcpReceiver::RtcpReceiver(scoped_refptr<CastEnvironment> cast_environment,
14 RtcpSenderFeedback* sender_feedback, 61 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),
(...skipping 40 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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 rtt_feedback_->OnReceivedDelaySinceLastReport( 295 rtt_feedback_->OnReceivedDelaySinceLastReport(
246 rtcp_field.dlrr.receivers_ssrc, 296 rtcp_field.dlrr.receivers_ssrc,
247 rtcp_field.dlrr.last_receiver_report, 297 rtcp_field.dlrr.last_receiver_report,
248 rtcp_field.dlrr.delay_last_receiver_report); 298 rtcp_field.dlrr.delay_last_receiver_report);
249 } 299 }
250 } 300 }
251 301
252 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) { 302 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) {
253 const RtcpField& rtcp_field = rtcp_parser->Field(); 303 const RtcpField& rtcp_field = rtcp_parser->Field();
254 if (ssrc_ != rtcp_field.nack.media_ssrc) { 304 if (ssrc_ != rtcp_field.nack.media_ssrc) {
255 // Not to us. 305 RtcpFieldTypes field_type;
256 rtcp_parser->Iterate(); 306 // Message not to us. Iterate until we have passed this message.
307 do {
308 field_type = rtcp_parser->Iterate();
309 } while (field_type == kRtcpGenericRtpFeedbackNackItemCode);
257 return; 310 return;
258 } 311 }
259 std::list<uint16> nackSequenceNumbers; 312 std::list<uint16> nackSequenceNumbers;
260 313
261 RtcpFieldTypes field_type = rtcp_parser->Iterate(); 314 RtcpFieldTypes field_type = rtcp_parser->Iterate();
262 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) { 315 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) {
263 HandleNACKItem(&rtcp_field, &nackSequenceNumbers); 316 HandleNACKItem(&rtcp_field, &nackSequenceNumbers);
264 field_type = rtcp_parser->Iterate(); 317 field_type = rtcp_parser->Iterate();
265 } 318 }
266 } 319 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 377 }
325 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f); 378 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f);
326 379
327 VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id; 380 VLOG(1) << "Cast RTCP received RPSI with picture_id " << rpsi_picture_id;
328 } 381 }
329 382
330 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) { 383 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) {
331 const RtcpField& rtcp_field = rtcp_parser->Field(); 384 const RtcpField& rtcp_field = rtcp_parser->Field();
332 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc; 385 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc;
333 if (remote_ssrc_ != remote_ssrc) { 386 if (remote_ssrc_ != remote_ssrc) {
334 // Message not to us. 387 // Message not to us. Iterate until we have passed this message.
335 rtcp_parser->Iterate(); 388 RtcpFieldTypes field_type;
389 do {
390 field_type = rtcp_parser->Iterate();
391 } while (field_type == kRtcpPayloadSpecificRembCode ||
392 field_type == kRtcpPayloadSpecificRembItemCode ||
393 field_type == kRtcpPayloadSpecificCastCode ||
394 field_type == kRtcpPayloadSpecificCastNackItemCode);
336 return; 395 return;
337 } 396 }
338 397
339 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); 398 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
340 switch (packet_type) { 399 switch (packet_type) {
341 case kRtcpPayloadSpecificRembCode: 400 case kRtcpPayloadSpecificRembCode:
342 packet_type = rtcp_parser->Iterate(); 401 packet_type = rtcp_parser->Iterate();
343 if (packet_type == kRtcpPayloadSpecificRembItemCode) { 402 if (packet_type == kRtcpPayloadSpecificRembItemCode) {
344 HandlePayloadSpecificRembItem(rtcp_parser); 403 HandlePayloadSpecificRembItem(rtcp_parser);
345 rtcp_parser->Iterate(); 404 rtcp_parser->Iterate();
(...skipping 16 matching lines...) Expand all
362 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) { 421 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) {
363 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) { 422 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) {
364 // Found matching ssrc. 423 // Found matching ssrc.
365 VLOG(1) << "Cast RTCP received REMB with received_bitrate " 424 VLOG(1) << "Cast RTCP received REMB with received_bitrate "
366 << rtcp_field.remb_item.bitrate; 425 << rtcp_field.remb_item.bitrate;
367 return; 426 return;
368 } 427 }
369 } 428 }
370 } 429 }
371 430
431 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog(
432 RtcpParser* rtcp_parser) {
433 const RtcpField& rtcp_field = rtcp_parser->Field();
434
435 uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc;
436 if (remote_ssrc_ != remote_ssrc) {
437 // Message not to us. Iterate until we have passed this message.
438 RtcpFieldTypes field_type;
439 do {
440 field_type = rtcp_parser->Iterate();
441 } while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode ||
442 field_type == kRtcpApplicationSpecificCastReceiverLogEventCode);
443 return;
444 }
445 RtcpReceiverLogMessage receiver_log;
446 RtcpFieldTypes field_type = rtcp_parser->Iterate();
447 while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode) {
448 RtcpReceiverFrameLogMessage frame_log(
449 rtcp_field.cast_receiver_log.rtp_timestamp);
450
451 field_type = rtcp_parser->Iterate();
452 while (field_type == kRtcpApplicationSpecificCastReceiverLogEventCode) {
453 HandleApplicationSpecificCastReceiverEventLog(rtcp_parser,
454 &frame_log.event_log_messages_);
455 field_type = rtcp_parser->Iterate();
456 }
457 receiver_log.push_back(frame_log);
458 }
459
460 if (receiver_feedback_ && !receiver_log.empty()) {
461 receiver_feedback_->OnReceivedReceiverLog(receiver_log);
462 }
463 }
464
465 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog(
466 RtcpParser* rtcp_parser,
467 RtcpReceiverEventLogMessages* event_log_messages) {
468 const RtcpField& rtcp_field = rtcp_parser->Field();
469
470 RtcpReceiverEventLogMessage event_log;
471 event_log.type = TranslateToLogEventFromWireFormat(
472 rtcp_field.cast_receiver_log.event);
473 event_log.event_timestamp = base::TimeTicks() +
474 base::TimeDelta::FromMilliseconds(
475 rtcp_field.cast_receiver_log.event_timestamp_base +
476 rtcp_field.cast_receiver_log.event_timestamp_delta);
477 event_log.delay_delta = base::TimeDelta::FromMilliseconds(
478 rtcp_field.cast_receiver_log.delay_delta_or_packet_id);
479 event_log.packet_id =
480 rtcp_field.cast_receiver_log.delay_delta_or_packet_id;
481 event_log_messages->push_back(event_log);
482 }
483
484 void RtcpReceiver::HandleApplicationSpecificCastSenderLog(
485 RtcpParser* rtcp_parser) {
486 const RtcpField& rtcp_field = rtcp_parser->Field();
487 uint32 remote_ssrc = rtcp_field.cast_sender_log.sender_ssrc;
488
489 if (remote_ssrc_ != remote_ssrc) {
490 RtcpFieldTypes field_type;
491 // Message not to us. Iterate until we have passed this message.
492 do {
493 field_type = rtcp_parser->Iterate();
494 } while (field_type == kRtcpApplicationSpecificCastSenderLogCode);
495 return;
496 }
497 RtcpSenderLogMessage sender_log;
498
499 RtcpFieldTypes field_type = rtcp_parser->Iterate();
500 while (field_type == kRtcpApplicationSpecificCastSenderLogCode) {
501 const RtcpField& rtcp_field = rtcp_parser->Field();
502 RtcpSenderFrameLogMessage frame_log;
503 frame_log.frame_status =
504 TranslateToFrameStatusFromWireFormat(rtcp_field.cast_sender_log.status);
505 frame_log.rtp_timestamp = rtcp_field.cast_sender_log.rtp_timestamp;
506 sender_log.push_back(frame_log);
507 field_type = rtcp_parser->Iterate();
508 }
509 if (receiver_feedback_) {
510 receiver_feedback_->OnReceivedSenderLog(sender_log);
511 }
512 }
513
372 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) { 514 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) {
373 const RtcpField& rtcp_field = rtcp_parser->Field(); 515 const RtcpField& rtcp_field = rtcp_parser->Field();
374
375 RtcpCastMessage cast_message(remote_ssrc_); 516 RtcpCastMessage cast_message(remote_ssrc_);
376 cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId( 517 cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId(
377 rtcp_field.cast_item.last_frame_id); 518 rtcp_field.cast_item.last_frame_id);
378 519
379 RtcpFieldTypes packet_type = rtcp_parser->Iterate(); 520 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
380 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) { 521 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) {
381 const RtcpField& rtcp_field = rtcp_parser->Field(); 522 const RtcpField& rtcp_field = rtcp_parser->Field();
382 HandlePayloadSpecificCastNackItem( 523 HandlePayloadSpecificCastNackItem(
383 &rtcp_field, &cast_message.missing_frames_and_packets_); 524 &rtcp_field, &cast_message.missing_frames_and_packets_);
384 packet_type = rtcp_parser->Iterate(); 525 packet_type = rtcp_parser->Iterate();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 576
436 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) { 577 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) {
437 // Is it our sender that is requested to generate a new keyframe. 578 // Is it our sender that is requested to generate a new keyframe.
438 if (ssrc_ != rtcp_field->fir_item.ssrc) return; 579 if (ssrc_ != rtcp_field->fir_item.ssrc) return;
439 580
440 VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_; 581 VLOG(1) << "Cast RTCP received FIR on our SSRC " << ssrc_;
441 } 582 }
442 583
443 } // namespace cast 584 } // namespace cast
444 } // namespace media 585 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/rtcp/rtcp_receiver.h ('k') | media/cast/rtcp/rtcp_receiver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698