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_utility.h" | 5 #include "media/cast/net/rtcp/rtcp_utility.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 } // namespace | 28 } // namespace |
29 | 29 |
30 RtcpParser::RtcpParser(uint32_t local_ssrc, uint32_t remote_ssrc) | 30 RtcpParser::RtcpParser(uint32_t local_ssrc, uint32_t remote_ssrc) |
31 : local_ssrc_(local_ssrc), | 31 : local_ssrc_(local_ssrc), |
32 remote_ssrc_(remote_ssrc), | 32 remote_ssrc_(remote_ssrc), |
33 has_sender_report_(false), | 33 has_sender_report_(false), |
34 has_last_report_(false), | 34 has_last_report_(false), |
35 has_cast_message_(false), | 35 has_cast_message_(false), |
36 has_cst2_message_(false), | 36 has_cst2_message_(false), |
37 has_receiver_reference_time_report_(false) {} | 37 has_receiver_reference_time_report_(false), |
| 38 has_picture_loss_indicator_(false) {} |
38 | 39 |
39 RtcpParser::~RtcpParser() {} | 40 RtcpParser::~RtcpParser() {} |
40 | 41 |
41 bool RtcpParser::Parse(base::BigEndianReader* reader) { | 42 bool RtcpParser::Parse(base::BigEndianReader* reader) { |
42 // Reset. | 43 // Reset. |
43 has_sender_report_ = false; | 44 has_sender_report_ = false; |
44 sender_report_ = RtcpSenderInfo(); | 45 sender_report_ = RtcpSenderInfo(); |
45 has_last_report_ = false; | 46 has_last_report_ = false; |
46 receiver_log_.clear(); | 47 receiver_log_.clear(); |
47 has_cast_message_ = false; | 48 has_cast_message_ = false; |
48 has_cst2_message_ = false; | 49 has_cst2_message_ = false; |
49 has_receiver_reference_time_report_ = false; | 50 has_receiver_reference_time_report_ = false; |
| 51 has_picture_loss_indicator_ = false; |
50 | 52 |
51 while (reader->remaining()) { | 53 while (reader->remaining()) { |
52 RtcpCommonHeader header; | 54 RtcpCommonHeader header; |
53 if (!ParseCommonHeader(reader, &header)) | 55 if (!ParseCommonHeader(reader, &header)) |
54 return false; | 56 return false; |
55 | 57 |
56 base::StringPiece tmp; | 58 base::StringPiece tmp; |
57 if (!reader->ReadPiece(&tmp, header.length_in_octets - 4)) | 59 if (!reader->ReadPiece(&tmp, header.length_in_octets - 4)) |
58 return false; | 60 return false; |
59 base::BigEndianReader chunk(tmp.data(), tmp.size()); | 61 base::BigEndianReader chunk(tmp.data(), tmp.size()); |
60 | 62 |
61 switch (header.PT) { | 63 switch (header.PT) { |
62 case kPacketTypeSenderReport: | 64 case kPacketTypeSenderReport: |
63 if (!ParseSR(&chunk, header)) | 65 if (!ParseSR(&chunk, header)) |
64 return false; | 66 return false; |
65 break; | 67 break; |
66 | 68 |
67 case kPacketTypeReceiverReport: | 69 case kPacketTypeReceiverReport: |
68 if (!ParseRR(&chunk, header)) | 70 if (!ParseRR(&chunk, header)) |
69 return false; | 71 return false; |
70 break; | 72 break; |
71 | 73 |
72 case kPacketTypeApplicationDefined: | 74 case kPacketTypeApplicationDefined: |
73 if (!ParseApplicationDefined(&chunk, header)) | 75 if (!ParseApplicationDefined(&chunk, header)) |
74 return false; | 76 return false; |
75 break; | 77 break; |
76 | 78 |
77 case kPacketTypePayloadSpecific: | 79 case kPacketTypePayloadSpecific: { |
78 if (!ParseFeedbackCommon(&chunk, header)) | 80 if (!ParseFeedbackCommon(&chunk, header)) |
79 return false; | 81 return false; |
| 82 if (!ParsePli(&chunk, header)) |
| 83 return false; |
80 break; | 84 break; |
| 85 } |
81 | 86 |
82 case kPacketTypeXr: | 87 case kPacketTypeXr: |
83 if (!ParseExtendedReport(&chunk, header)) | 88 if (!ParseExtendedReport(&chunk, header)) |
84 return false; | 89 return false; |
85 break; | 90 break; |
86 } | 91 } |
87 } | 92 } |
88 return true; | 93 return true; |
89 } | 94 } |
90 | 95 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 | 184 |
180 if (ssrc == local_ssrc_) { | 185 if (ssrc == local_ssrc_) { |
181 last_report_ = last_report; | 186 last_report_ = last_report; |
182 delay_since_last_report_ = delay; | 187 delay_since_last_report_ = delay; |
183 has_last_report_ = true; | 188 has_last_report_ = true; |
184 } | 189 } |
185 | 190 |
186 return true; | 191 return true; |
187 } | 192 } |
188 | 193 |
| 194 bool RtcpParser::ParsePli(base::BigEndianReader* reader, |
| 195 const RtcpCommonHeader& header) { |
| 196 if (header.IC != 1) |
| 197 return true; |
| 198 |
| 199 uint32_t receiver_ssrc, sender_ssrc; |
| 200 if (!reader->ReadU32(&receiver_ssrc)) |
| 201 return false; |
| 202 |
| 203 // Ignore this Rtcp if the receiver ssrc does not match. |
| 204 if (receiver_ssrc != remote_ssrc_) |
| 205 return true; |
| 206 |
| 207 if (!reader->ReadU32(&sender_ssrc)) |
| 208 return false; |
| 209 |
| 210 // Ignore this Rtcp if the sender ssrc does not match. |
| 211 if (sender_ssrc != local_ssrc_) |
| 212 return true; |
| 213 |
| 214 has_picture_loss_indicator_ = true; |
| 215 return true; |
| 216 } |
| 217 |
189 bool RtcpParser::ParseApplicationDefined(base::BigEndianReader* reader, | 218 bool RtcpParser::ParseApplicationDefined(base::BigEndianReader* reader, |
190 const RtcpCommonHeader& header) { | 219 const RtcpCommonHeader& header) { |
191 uint32_t sender_ssrc; | 220 uint32_t sender_ssrc; |
192 uint32_t name; | 221 uint32_t name; |
193 if (!reader->ReadU32(&sender_ssrc) || | 222 if (!reader->ReadU32(&sender_ssrc) || |
194 !reader->ReadU32(&name)) | 223 !reader->ReadU32(&name)) |
195 return false; | 224 return false; |
196 | 225 |
197 if (sender_ssrc != remote_ssrc_) | 226 if (sender_ssrc != remote_ssrc_) |
198 return true; | 227 return true; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 return true; | 303 return true; |
275 | 304 |
276 uint32_t name; | 305 uint32_t name; |
277 if (!reader->ReadU32(&name)) | 306 if (!reader->ReadU32(&name)) |
278 return false; | 307 return false; |
279 | 308 |
280 if (name != kCast) { | 309 if (name != kCast) { |
281 return true; | 310 return true; |
282 } | 311 } |
283 | 312 |
284 cast_message_.media_ssrc = remote_ssrc; | 313 cast_message_.remote_ssrc = remote_ssrc; |
285 | 314 |
286 uint8_t last_frame_id; | 315 uint8_t last_frame_id; |
287 uint8_t number_of_lost_fields; | 316 uint8_t number_of_lost_fields; |
288 if (!reader->ReadU8(&last_frame_id) || | 317 if (!reader->ReadU8(&last_frame_id) || |
289 !reader->ReadU8(&number_of_lost_fields) || | 318 !reader->ReadU8(&number_of_lost_fields) || |
290 !reader->ReadU16(&cast_message_.target_delay_ms)) | 319 !reader->ReadU16(&cast_message_.target_delay_ms)) |
291 return false; | 320 return false; |
292 | 321 |
293 // Please note, this frame_id is still only 8-bit! | 322 // Please note, this frame_id is still only 8-bit! |
294 cast_message_.ack_frame_id = last_frame_id; | 323 cast_message_.ack_frame_id = last_frame_id; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 uint32_t ssrc_of_sender; | 537 uint32_t ssrc_of_sender; |
509 base::BigEndianReader big_endian_reader( | 538 base::BigEndianReader big_endian_reader( |
510 reinterpret_cast<const char*>(rtcp_buffer), length); | 539 reinterpret_cast<const char*>(rtcp_buffer), length); |
511 big_endian_reader.Skip(4); // Skip header. | 540 big_endian_reader.Skip(4); // Skip header. |
512 big_endian_reader.ReadU32(&ssrc_of_sender); | 541 big_endian_reader.ReadU32(&ssrc_of_sender); |
513 return ssrc_of_sender; | 542 return ssrc_of_sender; |
514 } | 543 } |
515 | 544 |
516 } // namespace cast | 545 } // namespace cast |
517 } // namespace media | 546 } // namespace media |
OLD | NEW |