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
3 // found in the LICENSE file.
5 #include "media/cast/net/rtcp/rtcp_receiver.h"
7 #include "base/big_endian.h"
8 #include "base/logging.h"
9 #include "media/cast/net/cast_transport_defines.h"
10 #include "media/cast/net/rtcp/rtcp_utility.h"
14 // A receiver frame event is identified by frame RTP timestamp, event timestamp
16 // A receiver packet event is identified by all of the above plus packet id.
17 // The key format is as follows:
19 // bits 0-11: zeroes (unused).
20 // bits 12-15: event type ID.
21 // bits 16-31: packet ID if packet event, 0 otherwise.
22 // bits 32-63: RTP timestamp.
24 // bits 0-63: event TimeTicks internal value.
25 std::pair<uint64, uint64> GetReceiverEventKey(
26 uint32 frame_rtp_timestamp, const base::TimeTicks& event_timestamp,
27 uint8 event_type, uint16 packet_id_or_zero) {
28 uint64 value1 = event_type;
30 value1 |= packet_id_or_zero;
32 value1 |= frame_rtp_timestamp;
33 return std::make_pair(
34 value1, static_cast<uint64>(event_timestamp.ToInternalValue()));
42 RtcpReceiver::RtcpReceiver(RtcpMessageHandler* handler,
47 receiver_event_history_size_(0) {
51 RtcpReceiver::~RtcpReceiver() {}
54 bool RtcpReceiver::IsRtcpPacket(const uint8* packet, size_t length) {
55 if (length < kMinLengthOfRtcp) {
56 LOG(ERROR) << "Invalid RTCP packet received.";
60 uint8 packet_type = packet[1];
61 if (packet_type >= kPacketTypeLow &&
62 packet_type <= kPacketTypeHigh) {
69 uint32 RtcpReceiver::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) {
70 if (length < kMinLengthOfRtcp)
72 uint32 ssrc_of_sender;
73 base::BigEndianReader big_endian_reader(
74 reinterpret_cast<const char*>(rtcp_buffer), length);
75 big_endian_reader.Skip(4); // Skip header
76 big_endian_reader.ReadU32(&ssrc_of_sender);
77 return ssrc_of_sender;
80 void RtcpReceiver::SetRemoteSSRC(uint32 ssrc) { remote_ssrc_ = ssrc; }
82 void RtcpReceiver::SetCastReceiverEventHistorySize(size_t size) {
83 receiver_event_history_size_ = size;
86 void RtcpReceiver::IncomingRtcpPacket(RtcpParser* rtcp_parser) {
87 RtcpFieldTypes field_type = rtcp_parser->Begin();
88 while (field_type != kRtcpNotValidCode) {
89 // Each "case" is responsible for iterate the parser to the next top
93 HandleSenderReport(rtcp_parser);
96 HandleReceiverReport(rtcp_parser);
99 HandleXr(rtcp_parser);
101 case kRtcpPayloadSpecificAppCode:
102 HandlePayloadSpecificApp(rtcp_parser);
104 case kRtcpApplicationSpecificCastReceiverLogCode:
105 HandleApplicationSpecificCastReceiverLog(rtcp_parser);
107 case kRtcpPayloadSpecificCastCode:
108 case kRtcpPayloadSpecificCastNackItemCode:
109 case kRtcpApplicationSpecificCastReceiverLogFrameCode:
110 case kRtcpApplicationSpecificCastReceiverLogEventCode:
111 case kRtcpNotValidCode:
112 case kRtcpReportBlockItemCode:
113 case kRtcpXrRrtrCode:
114 case kRtcpXrDlrrCode:
115 case kRtcpXrUnknownItemCode:
116 rtcp_parser->Iterate();
117 NOTREACHED() << "Invalid state";
120 field_type = rtcp_parser->FieldType();
124 void RtcpReceiver::HandleSenderReport(RtcpParser* rtcp_parser) {
125 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
126 const RtcpField& rtcp_field = rtcp_parser->Field();
128 DCHECK(rtcp_field_type == kRtcpSrCode) << "Invalid state";
130 // Synchronization source identifier for the originator of this SR packet.
131 uint32 remote_ssrc = rtcp_field.sender_report.sender_ssrc;
133 VLOG(2) << "Cast RTCP received SR from SSRC " << remote_ssrc;
135 if (remote_ssrc_ == remote_ssrc) {
136 RtcpSenderInfo remote_sender_info;
137 remote_sender_info.ntp_seconds =
138 rtcp_field.sender_report.ntp_most_significant;
139 remote_sender_info.ntp_fraction =
140 rtcp_field.sender_report.ntp_least_significant;
141 remote_sender_info.rtp_timestamp = rtcp_field.sender_report.rtp_timestamp;
142 remote_sender_info.send_packet_count =
143 rtcp_field.sender_report.sender_packet_count;
144 remote_sender_info.send_octet_count =
145 rtcp_field.sender_report.sender_octet_count;
146 handler_->OnReceivedSenderReport(remote_sender_info);
148 rtcp_field_type = rtcp_parser->Iterate();
149 while (rtcp_field_type == kRtcpReportBlockItemCode) {
150 HandleReportBlock(&rtcp_field, remote_ssrc);
151 rtcp_field_type = rtcp_parser->Iterate();
155 void RtcpReceiver::HandleReceiverReport(RtcpParser* rtcp_parser) {
156 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
157 const RtcpField& rtcp_field = rtcp_parser->Field();
159 DCHECK(rtcp_field_type == kRtcpRrCode) << "Invalid state";
161 uint32 remote_ssrc = rtcp_field.receiver_report.sender_ssrc;
163 VLOG(2) << "Cast RTCP received RR from SSRC " << remote_ssrc;
165 rtcp_field_type = rtcp_parser->Iterate();
166 while (rtcp_field_type == kRtcpReportBlockItemCode) {
167 HandleReportBlock(&rtcp_field, remote_ssrc);
168 rtcp_field_type = rtcp_parser->Iterate();
172 void RtcpReceiver::HandleReportBlock(const RtcpField* rtcp_field,
173 uint32 remote_ssrc) {
174 // This will be called once per report block in the Rtcp packet.
175 // We filter out all report blocks that are not for us.
176 // Each packet has max 31 RR blocks.
178 // We can calculate RTT if we send a send report and get a report block back.
180 // |rtcp_field.ReportBlockItem.ssrc| is the ssrc identifier of the source to
181 // which the information in this reception report block pertains.
183 const RtcpFieldReportBlockItem& rb = rtcp_field->report_block_item;
185 // Filter out all report blocks that are not for us.
186 if (rb.ssrc != ssrc_) {
187 // This block is not for us ignore it.
190 VLOG(2) << "Cast RTCP received RB from SSRC " << remote_ssrc;
192 RtcpReportBlock report_block;
193 report_block.remote_ssrc = remote_ssrc;
194 report_block.media_ssrc = rb.ssrc;
195 report_block.fraction_lost = rb.fraction_lost;
196 report_block.cumulative_lost = rb.cumulative_number_of_packets_lost;
197 report_block.extended_high_sequence_number =
198 rb.extended_highest_sequence_number;
199 report_block.jitter = rb.jitter;
200 report_block.last_sr = rb.last_sender_report;
201 report_block.delay_since_last_sr = rb.delay_last_sender_report;
202 handler_->OnReceivedDelaySinceLastReport(
203 rb.last_sender_report, rb.delay_last_sender_report);
206 void RtcpReceiver::HandleXr(RtcpParser* rtcp_parser) {
207 RtcpFieldTypes rtcp_field_type = rtcp_parser->FieldType();
208 const RtcpField& rtcp_field = rtcp_parser->Field();
210 DCHECK(rtcp_field_type == kRtcpXrCode) << "Invalid state";
212 uint32 remote_ssrc = rtcp_field.extended_report.sender_ssrc;
213 rtcp_field_type = rtcp_parser->Iterate();
215 while (rtcp_field_type == kRtcpXrDlrrCode ||
216 rtcp_field_type == kRtcpXrRrtrCode ||
217 rtcp_field_type == kRtcpXrUnknownItemCode) {
218 if (rtcp_field_type == kRtcpXrRrtrCode) {
219 HandleRrtr(rtcp_parser, remote_ssrc);
220 } else if (rtcp_field_type == kRtcpXrDlrrCode) {
221 HandleDlrr(rtcp_parser);
223 rtcp_field_type = rtcp_parser->Iterate();
227 void RtcpReceiver::HandleRrtr(RtcpParser* rtcp_parser, uint32 remote_ssrc) {
228 if (remote_ssrc_ != remote_ssrc) {
232 const RtcpField& rtcp_field = rtcp_parser->Field();
233 RtcpReceiverReferenceTimeReport remote_time_report;
234 remote_time_report.remote_ssrc = remote_ssrc;
235 remote_time_report.ntp_seconds = rtcp_field.rrtr.ntp_most_significant;
236 remote_time_report.ntp_fraction = rtcp_field.rrtr.ntp_least_significant;
237 handler_->OnReceiverReferenceTimeReport(remote_time_report);
240 void RtcpReceiver::HandleDlrr(RtcpParser* rtcp_parser) {
241 const RtcpField& rtcp_field = rtcp_parser->Field();
242 if (remote_ssrc_ != rtcp_field.dlrr.receivers_ssrc) {
246 handler_->OnReceivedDelaySinceLastReport(
247 rtcp_field.dlrr.last_receiver_report,
248 rtcp_field.dlrr.delay_last_receiver_report);
251 void RtcpReceiver::HandlePayloadSpecificApp(RtcpParser* rtcp_parser) {
252 const RtcpField& rtcp_field = rtcp_parser->Field();
253 uint32 remote_ssrc = rtcp_field.application_specific.sender_ssrc;
254 if (remote_ssrc_ != remote_ssrc) {
255 // Message not to us. Iterate until we have passed this message.
256 RtcpFieldTypes field_type;
258 field_type = rtcp_parser->Iterate();
259 } while (field_type == kRtcpPayloadSpecificCastCode ||
260 field_type == kRtcpPayloadSpecificCastNackItemCode);
264 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
265 switch (packet_type) {
266 case kRtcpPayloadSpecificCastCode:
267 packet_type = rtcp_parser->Iterate();
268 if (packet_type == kRtcpPayloadSpecificCastCode) {
269 HandlePayloadSpecificCastItem(rtcp_parser);
277 void RtcpReceiver::HandleApplicationSpecificCastReceiverLog(
278 RtcpParser* rtcp_parser) {
279 const RtcpField& rtcp_field = rtcp_parser->Field();
281 uint32 remote_ssrc = rtcp_field.cast_receiver_log.sender_ssrc;
282 if (remote_ssrc_ != remote_ssrc) {
283 // Message not to us. Iterate until we have passed this message.
284 RtcpFieldTypes field_type;
286 field_type = rtcp_parser->Iterate();
287 } while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode ||
288 field_type == kRtcpApplicationSpecificCastReceiverLogEventCode);
291 RtcpReceiverLogMessage receiver_log;
292 RtcpFieldTypes field_type = rtcp_parser->Iterate();
293 while (field_type == kRtcpApplicationSpecificCastReceiverLogFrameCode) {
294 RtcpReceiverFrameLogMessage frame_log(
295 rtcp_field.cast_receiver_log.rtp_timestamp);
297 field_type = rtcp_parser->Iterate();
298 while (field_type == kRtcpApplicationSpecificCastReceiverLogEventCode) {
299 HandleApplicationSpecificCastReceiverEventLog(
300 rtcp_field.cast_receiver_log.rtp_timestamp,
302 &frame_log.event_log_messages_);
303 field_type = rtcp_parser->Iterate();
306 if (!frame_log.event_log_messages_.empty())
307 receiver_log.push_back(frame_log);
310 if (!receiver_log.empty())
311 handler_->OnReceivedReceiverLog(receiver_log);
314 void RtcpReceiver::HandleApplicationSpecificCastReceiverEventLog(
315 uint32 frame_rtp_timestamp,
316 RtcpParser* rtcp_parser,
317 RtcpReceiverEventLogMessages* event_log_messages) {
318 const RtcpField& rtcp_field = rtcp_parser->Field();
320 const uint8 event = rtcp_field.cast_receiver_log.event;
321 const CastLoggingEvent event_type = TranslateToLogEventFromWireFormat(event);
322 uint16 packet_id = event_type == PACKET_RECEIVED ?
323 rtcp_field.cast_receiver_log.delay_delta_or_packet_id.packet_id : 0;
324 const base::TimeTicks event_timestamp =
326 base::TimeDelta::FromMilliseconds(
327 rtcp_field.cast_receiver_log.event_timestamp_base +
328 rtcp_field.cast_receiver_log.event_timestamp_delta);
330 // The following code checks to see if we have already seen this event.
331 // The algorithm works by maintaining a sliding window of events. We have
332 // a queue and a set of events. We enqueue every new event and insert it
333 // into the set. When the queue becomes too big we remove the oldest event
334 // from both the queue and the set.
335 ReceiverEventKey key =
337 frame_rtp_timestamp, event_timestamp, event, packet_id);
338 if (receiver_event_key_set_.find(key) != receiver_event_key_set_.end()) {
341 receiver_event_key_set_.insert(key);
342 receiver_event_key_queue_.push(key);
344 if (receiver_event_key_queue_.size() > receiver_event_history_size_) {
345 const ReceiverEventKey oldest_key = receiver_event_key_queue_.front();
346 receiver_event_key_queue_.pop();
347 receiver_event_key_set_.erase(oldest_key);
351 RtcpReceiverEventLogMessage event_log;
352 event_log.type = event_type;
353 event_log.event_timestamp = event_timestamp;
354 event_log.delay_delta = base::TimeDelta::FromMilliseconds(
355 rtcp_field.cast_receiver_log.delay_delta_or_packet_id.delay_delta);
356 event_log.packet_id =
357 rtcp_field.cast_receiver_log.delay_delta_or_packet_id.packet_id;
358 event_log_messages->push_back(event_log);
361 void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) {
362 const RtcpField& rtcp_field = rtcp_parser->Field();
363 RtcpCastMessage cast_message(remote_ssrc_);
364 cast_message.ack_frame_id = ack_frame_id_wrap_helper_.MapTo32bitsFrameId(
365 rtcp_field.cast_item.last_frame_id);
366 cast_message.target_delay_ms = rtcp_field.cast_item.target_delay_ms;
368 RtcpFieldTypes packet_type = rtcp_parser->Iterate();
369 while (packet_type == kRtcpPayloadSpecificCastNackItemCode) {
370 const RtcpField& rtcp_field = rtcp_parser->Field();
371 HandlePayloadSpecificCastNackItem(
372 &rtcp_field, &cast_message.missing_frames_and_packets);
373 packet_type = rtcp_parser->Iterate();
375 handler_->OnReceivedCastFeedback(cast_message);
378 void RtcpReceiver::HandlePayloadSpecificCastNackItem(
379 const RtcpField* rtcp_field,
380 MissingFramesAndPacketsMap* missing_frames_and_packets) {
382 MissingFramesAndPacketsMap::iterator frame_it =
383 missing_frames_and_packets->find(rtcp_field->cast_nack_item.frame_id);
385 if (frame_it == missing_frames_and_packets->end()) {
386 // First missing packet in a frame.
387 PacketIdSet empty_set;
388 std::pair<MissingFramesAndPacketsMap::iterator, bool> ret =
389 missing_frames_and_packets->insert(std::pair<uint8, PacketIdSet>(
390 rtcp_field->cast_nack_item.frame_id, empty_set));
391 frame_it = ret.first;
392 DCHECK(frame_it != missing_frames_and_packets->end()) << "Invalid state";
394 uint16 packet_id = rtcp_field->cast_nack_item.packet_id;
395 frame_it->second.insert(packet_id);
397 if (packet_id == kRtcpCastAllPacketsLost) {
398 // Special case all packets in a frame is missing.
401 uint8 bitmask = rtcp_field->cast_nack_item.bitmask;
404 for (int i = 1; i <= 8; ++i) {
406 frame_it->second.insert(packet_id + i);
408 bitmask = bitmask >> 1;