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
3 // found in the LICENSE file.
5 #include "media/cast/rtcp/rtcp_receiver.h"
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9 #include "media/cast/rtcp/rtcp_utility.h"
14 RtcpReceiver::RtcpReceiver(RtcpSenderFeedback* sender_feedback,
15 RtcpReceiverFeedback* receiver_feedback,
16 RtcpRttFeedback* rtt_feedback,
20 sender_feedback_(sender_feedback),
21 receiver_feedback_(receiver_feedback),
22 rtt_feedback_(rtt_feedback) {
25 RtcpReceiver::~RtcpReceiver() {}
27 void RtcpReceiver::SetRemoteSSRC(uint32 ssrc) {
31 void RtcpReceiver::IncomingRtcpPacket(RtcpParser* rtcp_parser) {
32 RtcpFieldTypes field_type = rtcp_parser->Begin();
33 while (field_type != kRtcpNotValidCode) {
34 // Each "case" is responsible for iterate the parser to the next top
38 HandleSenderReport(rtcp_parser);
41 HandleReceiverReport(rtcp_parser);
44 HandleSDES(rtcp_parser);
47 HandleBYE(rtcp_parser);
50 HandleXr(rtcp_parser);
52 case kRtcpGenericRtpFeedbackNackCode:
53 HandleNACK(rtcp_parser);
55 case kRtcpGenericRtpFeedbackSrReqCode:
56 HandleSendReportRequest(rtcp_parser);
58 case kRtcpPayloadSpecificPliCode:
59 HandlePLI(rtcp_parser);
61 case kRtcpPayloadSpecificRpsiCode:
62 HandleRpsi(rtcp_parser);
64 case kRtcpPayloadSpecificFirCode:
65 HandleFIR(rtcp_parser);
67 case kRtcpPayloadSpecificAppCode:
68 HandlePayloadSpecificApp(rtcp_parser);
70 case kRtcpPayloadSpecificRembCode:
71 case kRtcpPayloadSpecificRembItemCode:
72 // Ignore this until we want to support interop with webrtc.
73 rtcp_parser->Iterate();
75 case kRtcpPayloadSpecificCastCode:
76 case kRtcpPayloadSpecificCastNackItemCode:
77 rtcp_parser->Iterate();
79 case kRtcpNotValidCode:
80 case kRtcpReportBlockItemCode:
81 case kRtcpSdesChunkCode:
82 case kRtcpGenericRtpFeedbackNackItemCode:
83 case kRtcpPayloadSpecificFirItemCode:
86 case kRtcpXrUnknownItemCode:
87 rtcp_parser->Iterate();
88 DCHECK(false) << "Invalid state";
91 field_type = rtcp_parser->FieldType();
95 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) {
96 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
97 const RtcpField& rtcp_field = rtcp_parser->Field();
99 DCHECK(rtcp_field_type == kRtcpSrCode) << "Invalid state";
101 // Synchronization source identifier for the originator of this SR packet.
102 uint32 remote_ssrc = rtcp_field.sender_report.sender_ssrc;
104 TRACE_EVENT_INSTANT1("cast_rtcp", "SR", TRACE_EVENT_SCOPE_THREAD,
105 "remote_ssrc", remote_ssrc);
107 if (remote_ssrc_ == remote_ssrc) {
108 RtcpSenderInfo remote_sender_info;
109 remote_sender_info.ntp_seconds =
110 rtcp_field.sender_report.ntp_most_significant;
111 remote_sender_info.ntp_fraction =
112 rtcp_field.sender_report.ntp_least_significant;
113 remote_sender_info.rtp_timestamp =
114 rtcp_field.sender_report.rtp_timestamp;
115 remote_sender_info.send_packet_count =
116 rtcp_field.sender_report.sender_packet_count;
117 remote_sender_info.send_octet_count =
118 rtcp_field.sender_report.sender_octet_count;
119 if (receiver_feedback_) {
120 receiver_feedback_->OnReceivedSenderReport(remote_sender_info);
123 rtcp_field_type = rtcp_parser->Iterate();
124 while (rtcp_field_type == kRtcpReportBlockItemCode) {
125 HandleReportBlock(&rtcp_field, remote_ssrc);
126 rtcp_field_type = rtcp_parser->Iterate();
130 void RtcpReceiver::HandleReceiverReport(RtcpParser* rtcp_parser) {
131 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
132 const RtcpField& rtcp_field = rtcp_parser->Field();
134 DCHECK(rtcp_field_type == kRtcpRrCode) << "Invalid state";
136 uint32 remote_ssrc = rtcp_field.receiver_report.sender_ssrc;
138 TRACE_EVENT_INSTANT1("cast_rtcp", "RR", TRACE_EVENT_SCOPE_THREAD,
139 "remote_ssrc", remote_ssrc);
141 rtcp_field_type = rtcp_parser->Iterate();
142 while (rtcp_field_type == kRtcpReportBlockItemCode) {
143 HandleReportBlock(&rtcp_field, remote_ssrc);
144 rtcp_field_type = rtcp_parser->Iterate();
148 void RtcpReceiver::HandleReportBlock(const RtcpField* rtcp_field,
149 uint32 remote_ssrc) {
150 // This will be called once per report block in the Rtcp packet.
151 // We filter out all report blocks that are not for us.
152 // Each packet has max 31 RR blocks.
154 // We can calculate RTT if we send a send report and get a report block back.
156 // |rtcp_field.ReportBlockItem.ssrc| is the ssrc identifier of the source to
157 // which the information in this reception report block pertains.
159 const RtcpFieldReportBlockItem& rb = rtcp_field->report_block_item;
161 // Filter out all report blocks that are not for us.
162 if (rb.ssrc != ssrc_) {
163 // This block is not for us ignore it.
166 TRACE_EVENT_INSTANT2("cast_rtcp", "RB", TRACE_EVENT_SCOPE_THREAD,
167 "remote_ssrc", remote_ssrc,
170 TRACE_COUNTER_ID1("cast_rtcp", "RtcpReceiver::FractionLost",
171 rb.ssrc, rb.fraction_lost);
172 TRACE_COUNTER_ID1("cast_rtcp", "RtcpReceiver::CumulativeNumberOfPacketsLost",
173 rb.ssrc, rb.cumulative_number_of_packets_lost);
174 TRACE_COUNTER_ID1("cast_rtcp", "RtcpReceiver::Jitter",
177 RtcpReportBlock report_block;
178 report_block.remote_ssrc = remote_ssrc;
179 report_block.media_ssrc = rb.ssrc;
180 report_block.fraction_lost = rb.fraction_lost;
181 report_block.cumulative_lost = rb.cumulative_number_of_packets_lost;
182 report_block.extended_high_sequence_number =
183 rb.extended_highest_sequence_number;
184 report_block.jitter = rb.jitter;
185 report_block.last_sr = rb.last_sender_report;
186 report_block.delay_since_last_sr = rb.delay_last_sender_report;
188 if (sender_feedback_) {
189 sender_feedback_->OnReceivedReportBlock(report_block);
192 rtt_feedback_->OnReceivedDelaySinceLastReport(rb.ssrc,
193 rb.last_sender_report,
194 rb.delay_last_sender_report);
198 void RtcpReceiver::HandleSDES(RtcpParser* rtcp_parser) {
199 RtcpFieldTypes field_type = rtcp_parser->Iterate();
200 while (field_type == kRtcpSdesChunkCode) {
201 HandleSDESChunk(rtcp_parser);
202 field_type = rtcp_parser->Iterate();
206 void RtcpReceiver::HandleSDESChunk(RtcpParser* rtcp_parser) {
207 const RtcpField& rtcp_field = rtcp_parser->Field();
208 TRACE_EVENT_INSTANT1("cast_rtcp", "SDES", TRACE_EVENT_SCOPE_THREAD,
209 "cname", TRACE_STR_COPY(rtcp_field.c_name.name));
212 void RtcpReceiver::HandleXr(RtcpParser* rtcp_parser) {
213 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
214 const RtcpField& rtcp_field = rtcp_parser->Field();
216 DCHECK(rtcp_field_type == kRtcpXrCode) << "Invalid state";
218 uint32 remote_ssrc = rtcp_field.extended_report.sender_ssrc;
219 rtcp_field_type = rtcp_parser->Iterate();
221 while (rtcp_field_type == kRtcpXrDlrrCode ||
222 rtcp_field_type == kRtcpXrRrtrCode ||
223 rtcp_field_type == kRtcpXrUnknownItemCode) {
224 if (rtcp_field_type == kRtcpXrRrtrCode) {
225 HandleRrtr(rtcp_parser, remote_ssrc);
226 } else if (rtcp_field_type == kRtcpXrDlrrCode) {
227 HandleDlrr(rtcp_parser);
229 rtcp_field_type = rtcp_parser->Iterate();
233 void RtcpReceiver::HandleRrtr(RtcpParser* rtcp_parser, uint32 remote_ssrc) {
234 if (remote_ssrc_ != remote_ssrc) {
238 const RtcpField& rtcp_field = rtcp_parser->Field();
239 RtcpReceiverReferenceTimeReport remote_time_report;
240 remote_time_report.remote_ssrc = remote_ssrc;
241 remote_time_report.ntp_seconds = rtcp_field.rrtr.ntp_most_significant;
242 remote_time_report.ntp_fraction = rtcp_field.rrtr.ntp_least_significant;
244 if (receiver_feedback_) {
245 receiver_feedback_->OnReceiverReferenceTimeReport(remote_time_report);
249 void RtcpReceiver::HandleDlrr(RtcpParser* rtcp_parser) {
250 const RtcpField& rtcp_field = rtcp_parser->Field();
251 if (remote_ssrc_ != rtcp_field.dlrr.receivers_ssrc) {
256 rtt_feedback_->OnReceivedDelaySinceLastReport(
257 rtcp_field.dlrr.receivers_ssrc,
258 rtcp_field.dlrr.last_receiver_report,
259 rtcp_field.dlrr.delay_last_receiver_report);
263 void RtcpReceiver::HandleNACK(RtcpParser* rtcp_parser) {
264 const RtcpField& rtcp_field = rtcp_parser->Field();
265 if (ssrc_ != rtcp_field.nack.media_ssrc) {
267 rtcp_parser->Iterate();
270 std::list<uint16> nackSequenceNumbers;
272 RtcpFieldTypes field_type = rtcp_parser->Iterate();
273 while (field_type == kRtcpGenericRtpFeedbackNackItemCode) {
274 HandleNACKItem(&rtcp_field, &nackSequenceNumbers);
275 field_type = rtcp_parser->Iterate();
277 if (sender_feedback_) {
278 sender_feedback_->OnReceivedNackRequest(nackSequenceNumbers);
282 void RtcpReceiver::HandleNACKItem(const RtcpField* rtcp_field,
283 std::list<uint16>* nack_sequence_numbers) {
284 nack_sequence_numbers->push_back(rtcp_field->nack_item.packet_id);
286 uint16 bitmask = rtcp_field->nack_item.bitmask;
288 for (int i = 1; i <= 16; ++i) {
290 nack_sequence_numbers->push_back(rtcp_field->nack_item.packet_id + i);
292 bitmask = bitmask >> 1;
297 void RtcpReceiver::HandleBYE(RtcpParser* rtcp_parser) {
298 const RtcpField& rtcp_field = rtcp_parser->Field();
299 uint32 remote_ssrc = rtcp_field.bye.sender_ssrc;
300 if (remote_ssrc_ == remote_ssrc) {
301 TRACE_EVENT_INSTANT1("cast_rtcp", "BYE", TRACE_EVENT_SCOPE_THREAD,
302 "remote_ssrc", remote_ssrc);
304 rtcp_parser->Iterate();
307 void RtcpReceiver::HandlePLI(RtcpParser* rtcp_parser) {
308 const RtcpField& rtcp_field = rtcp_parser->Field();
309 if (ssrc_ == rtcp_field.pli.media_ssrc) {
310 // Received a signal that we need to send a new key frame.
311 if (sender_feedback_) {
312 sender_feedback_->OnReceivedIntraFrameRequest();
315 rtcp_parser->Iterate();
318 void RtcpReceiver::HandleSendReportRequest(RtcpParser* rtcp_parser) {
319 if (receiver_feedback_) {
320 receiver_feedback_->OnReceivedSendReportRequest();
322 rtcp_parser->Iterate();
325 void RtcpReceiver::HandleRpsi(RtcpParser* rtcp_parser) {
326 const RtcpField& rtcp_field = rtcp_parser->Field();
327 if (rtcp_parser->Iterate() != kRtcpPayloadSpecificRpsiCode) {
330 if (rtcp_field.rpsi.number_of_valid_bits % 8 != 0) {
334 uint64 rpsi_picture_id = 0;
336 // Convert native_bit_string to rpsi_picture_id
337 uint8 bytes = rtcp_field.rpsi.number_of_valid_bits / 8;
338 for (uint8 n = 0; n < (bytes - 1); ++n) {
339 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[n] & 0x7f);
340 rpsi_picture_id <<= 7; // Prepare next.
342 rpsi_picture_id += (rtcp_field.rpsi.native_bit_string[bytes - 1] & 0x7f);
343 if (sender_feedback_) {
344 sender_feedback_->OnReceivedRpsi(rtcp_field.rpsi.payload_type,
349 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) {
350 const RtcpField& rtcp_field = rtcp_parser->Field();
351 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc;
352 if (remote_ssrc_ != remote_ssrc) {
353 // Message not to us.
354 rtcp_parser->Iterate();
358 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
359 switch (packet_type) {
360 case kRtcpPayloadSpecificRembCode:
361 packet_type = rtcp_parser->Iterate();
362 if (packet_type == kRtcpPayloadSpecificRembItemCode) {
363 HandlePayloadSpecificRembItem(rtcp_parser);
364 rtcp_parser->Iterate();
367 case kRtcpPayloadSpecificCastCode:
368 packet_type = rtcp_parser->Iterate();
369 if (packet_type == kRtcpPayloadSpecificCastCode) {
370 HandlePayloadSpecificCastItem(rtcp_parser);
378 void RtcpReceiver::HandlePayloadSpecificRembItem(RtcpParser* rtcp_parser) {
379 const RtcpField& rtcp_field = rtcp_parser->Field();
381 for (int i = 0; i < rtcp_field.remb_item.number_of_ssrcs; ++i) {
382 if (rtcp_field.remb_item.ssrcs[i] == ssrc_) {
383 // Found matching ssrc.
384 if (sender_feedback_) {
385 sender_feedback_->OnReceivedRemb(rtcp_field.remb_item.bitrate);
392 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) {
393 const RtcpField& rtcp_field = rtcp_parser->Field();
395 RtcpCastMessage cast_message(remote_ssrc_);
396 cast_message.ack_frame_id_ = rtcp_field.cast_item.last_frame_id;
398 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
399 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) {
400 const RtcpField& rtcp_field = rtcp_parser->Field();
401 HandlePayloadSpecificCastNackItem(
402 &rtcp_field, &cast_message.missing_frames_and_packets_);
403 packet_type = rtcp_parser->Iterate();
405 if (sender_feedback_) {
406 sender_feedback_->OnReceivedCastFeedback(cast_message);
410 void RtcpReceiver::HandlePayloadSpecificCastNackItem(
411 const RtcpField* rtcp_field,
412 MissingFramesAndPacketsMap* missing_frames_and_packets) {
414 MissingFramesAndPacketsMap::iterator frame_it =
415 missing_frames_and_packets->find(rtcp_field->cast_nack_item.frame_id);
417 if (frame_it == missing_frames_and_packets->end()) {
418 // First missing packet in a frame.
419 PacketIdSet empty_set;
420 std::pair<MissingFramesAndPacketsMap::iterator, bool> ret =
421 missing_frames_and_packets->insert(std::pair<uint8, PacketIdSet>(
422 rtcp_field->cast_nack_item.frame_id, empty_set));
423 frame_it = ret.first;
424 DCHECK(frame_it != missing_frames_and_packets->end()) << "Invalid state";
426 if (rtcp_field->cast_nack_item.packet_id == kRtcpCastAllPacketsLost) {
427 // Special case all packets in a frame is missing.
430 uint16 packet_id = rtcp_field->cast_nack_item.packet_id;
431 uint8 bitmask = rtcp_field->cast_nack_item.bitmask;
433 frame_it->second.insert(packet_id);
436 for (int i = 1; i <= 8; ++i) {
438 frame_it->second.insert(packet_id + i);
440 bitmask = bitmask >> 1;
445 void RtcpReceiver::HandleFIR(RtcpParser* rtcp_parser) {
446 const RtcpField& rtcp_field = rtcp_parser->Field();
448 RtcpFieldTypes field_type = rtcp_parser->Iterate();
449 while (field_type == kRtcpPayloadSpecificFirItemCode) {
450 HandleFIRItem(&rtcp_field);
451 field_type = rtcp_parser->Iterate();
455 void RtcpReceiver::HandleFIRItem(const RtcpField* rtcp_field) {
456 // Is it our sender that is requested to generate a new keyframe.
457 if (ssrc_ != rtcp_field->fir_item.ssrc) return;
458 if (sender_feedback_) {
459 sender_feedback_->OnReceivedIntraFrameRequest();