OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 #include <algorithm> | 16 #include <algorithm> |
17 | 17 |
18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
20 #include "webrtc/base/trace_event.h" | 20 #include "webrtc/base/trace_event.h" |
21 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 21 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
22 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | 22 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
23 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" | 23 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" |
24 #include "webrtc/modules/rtp_rtcp/source/time_util.h" | 24 #include "webrtc/modules/rtp_rtcp/source/time_util.h" |
25 #include "webrtc/system_wrappers/include/ntp_time.h" | 25 #include "webrtc/system_wrappers/include/ntp_time.h" |
26 | 26 |
27 namespace webrtc { | 27 namespace webrtc { |
| 28 using rtcp::ReportBlockInformation; |
28 using RTCPHelp::RTCPPacketInformation; | 29 using RTCPHelp::RTCPPacketInformation; |
29 using RTCPHelp::RTCPReceiveInformation; | 30 using RTCPHelp::RTCPReceiveInformation; |
30 using RTCPHelp::RTCPReportBlockInformation; | |
31 using RTCPUtility::kBtVoipMetric; | 31 using RTCPUtility::kBtVoipMetric; |
32 using RTCPUtility::RTCPCnameInformation; | 32 using RTCPUtility::RTCPCnameInformation; |
33 using RTCPUtility::RTCPPacketReportBlockItem; | 33 using RTCPUtility::RTCPPacketReportBlockItem; |
34 using RTCPUtility::RTCPPacketTypes; | 34 using RTCPUtility::RTCPPacketTypes; |
35 | 35 |
36 // The number of RTCP time intervals needed to trigger a timeout. | 36 // The number of RTCP time intervals needed to trigger a timeout. |
37 const int kRrTimeoutIntervals = 3; | 37 const int kRrTimeoutIntervals = 3; |
38 | 38 |
39 const int64_t kMaxWarningLogIntervalMs = 10000; | 39 const int64_t kMaxWarningLogIntervalMs = 10000; |
40 | 40 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
167 int32_t RTCPReceiver::RTT(uint32_t remoteSSRC, | 167 int32_t RTCPReceiver::RTT(uint32_t remoteSSRC, |
168 int64_t* RTT, | 168 int64_t* RTT, |
169 int64_t* avgRTT, | 169 int64_t* avgRTT, |
170 int64_t* minRTT, | 170 int64_t* minRTT, |
171 int64_t* maxRTT) const { | 171 int64_t* maxRTT) const { |
172 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 172 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
173 | 173 |
174 RTCPReportBlockInformation* reportBlock = | 174 const ReportBlockInformation* report_block = |
175 GetReportBlockInformation(remoteSSRC, main_ssrc_); | 175 GetReportBlockInformation(remoteSSRC, main_ssrc_); |
176 | 176 |
177 if (reportBlock == NULL) { | 177 if (!report_block || !report_block->HasRtt()) { |
178 return -1; | 178 return -1; |
179 } | 179 } |
180 if (RTT) { | 180 if (RTT) { |
181 *RTT = reportBlock->RTT; | 181 *RTT = report_block->LastRttMs(); |
182 } | 182 } |
183 if (avgRTT) { | 183 if (avgRTT) { |
184 *avgRTT = reportBlock->avgRTT; | 184 *avgRTT = report_block->AvgRttMs(); |
185 } | 185 } |
186 if (minRTT) { | 186 if (minRTT) { |
187 *minRTT = reportBlock->minRTT; | 187 *minRTT = report_block->MinRttMs(); |
188 } | 188 } |
189 if (maxRTT) { | 189 if (maxRTT) { |
190 *maxRTT = reportBlock->maxRTT; | 190 *maxRTT = report_block->MaxRttMs(); |
191 } | 191 } |
192 return 0; | 192 return 0; |
193 } | 193 } |
194 | 194 |
195 bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) { | 195 bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) { |
196 assert(rtt_ms); | 196 assert(rtt_ms); |
197 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 197 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
198 if (xr_rr_rtt_ms_ == 0) { | 198 if (xr_rr_rtt_ms_ == 0) { |
199 return false; | 199 return false; |
200 } | 200 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 // we can get multiple receive reports when we receive the report from a CE | 271 // we can get multiple receive reports when we receive the report from a CE |
272 int32_t RTCPReceiver::StatisticsReceived( | 272 int32_t RTCPReceiver::StatisticsReceived( |
273 std::vector<RTCPReportBlock>* receiveBlocks) const { | 273 std::vector<RTCPReportBlock>* receiveBlocks) const { |
274 assert(receiveBlocks); | 274 assert(receiveBlocks); |
275 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 275 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
276 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin(); | 276 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin(); |
277 for (; it != _receivedReportBlockMap.end(); ++it) { | 277 for (; it != _receivedReportBlockMap.end(); ++it) { |
278 const ReportBlockInfoMap* info_map = &(it->second); | 278 const ReportBlockInfoMap* info_map = &(it->second); |
279 ReportBlockInfoMap::const_iterator it_info = info_map->begin(); | 279 ReportBlockInfoMap::const_iterator it_info = info_map->begin(); |
280 for (; it_info != info_map->end(); ++it_info) { | 280 for (; it_info != info_map->end(); ++it_info) { |
281 receiveBlocks->push_back(it_info->second->remoteReceiveBlock); | 281 receiveBlocks->push_back(it_info->second->LastBlock()); |
282 } | 282 } |
283 } | 283 } |
284 return 0; | 284 return 0; |
285 } | 285 } |
286 | 286 |
287 int32_t | 287 int32_t |
288 RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, | 288 RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, |
289 RTCPUtility::RTCPParserV2* rtcpParser) | 289 RTCPUtility::RTCPParserV2* rtcpParser) |
290 { | 290 { |
291 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 291 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to | 482 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to |
483 // which the information in this reception report block pertains. | 483 // which the information in this reception report block pertains. |
484 | 484 |
485 // Filter out all report blocks that are not for us. | 485 // Filter out all report blocks that are not for us. |
486 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) == | 486 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) == |
487 registered_ssrcs_.end()) { | 487 registered_ssrcs_.end()) { |
488 // This block is not for us ignore it. | 488 // This block is not for us ignore it. |
489 return; | 489 return; |
490 } | 490 } |
491 | 491 |
492 RTCPReportBlockInformation* reportBlock = | 492 ReportBlockInformation* reportBlock = CreateOrGetReportBlockInformation( |
493 CreateOrGetReportBlockInformation(remoteSSRC, | 493 remoteSSRC, rtcpPacket.ReportBlockItem.SSRC); |
494 rtcpPacket.ReportBlockItem.SSRC); | 494 |
495 if (reportBlock == NULL) { | 495 if (reportBlock == NULL) { |
496 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation(" | 496 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation(" |
497 << remoteSSRC << ")"; | 497 << remoteSSRC << ")"; |
498 return; | 498 return; |
499 } | 499 } |
500 | 500 |
501 _lastReceivedRrMs = _clock->TimeInMilliseconds(); | 501 _lastReceivedRrMs = _clock->TimeInMilliseconds(); |
502 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem; | 502 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem; |
503 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC; | |
504 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC; | |
505 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost; | |
506 reportBlock->remoteReceiveBlock.cumulativeLost = | |
507 rb.CumulativeNumOfPacketsLost; | |
508 if (rb.ExtendedHighestSequenceNumber > | 503 if (rb.ExtendedHighestSequenceNumber > |
509 reportBlock->remoteReceiveBlock.extendedHighSeqNum) { | 504 reportBlock->LastBlock().extendedHighSeqNum) { |
510 // We have successfully delivered new RTP packets to the remote side after | 505 // We have successfully delivered new RTP packets to the remote side after |
511 // the last RR was sent from the remote side. | 506 // the last RR was sent from the remote side. |
512 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs; | 507 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs; |
513 } | 508 } |
514 reportBlock->remoteReceiveBlock.extendedHighSeqNum = | |
515 rb.ExtendedHighestSequenceNumber; | |
516 reportBlock->remoteReceiveBlock.jitter = rb.Jitter; | |
517 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR; | |
518 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR; | |
519 | 509 |
520 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) { | 510 reportBlock->AddBlock(rb, remoteSSRC, NtpTime(*_clock)); |
521 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter; | |
522 } | |
523 | |
524 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR; | |
525 uint32_t rtt = 0; | |
526 | |
527 if (send_time > 0) { | |
528 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR; | |
529 // Local NTP time. | |
530 uint32_t receive_time = CompactNtp(NtpTime(*_clock)); | |
531 | |
532 // RTT in 1/(2^16) seconds. | |
533 uint32_t rtt_ntp = receive_time - delay - send_time; | |
534 // Convert to 1/1000 seconds (milliseconds). | |
535 uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp); | |
536 rtt = std::max<uint32_t>(rtt_ms, 1); | |
537 if (rtt > reportBlock->maxRTT) { | |
538 // Store max RTT. | |
539 reportBlock->maxRTT = rtt; | |
540 } | |
541 if (reportBlock->minRTT == 0) { | |
542 // First RTT. | |
543 reportBlock->minRTT = rtt; | |
544 } else if (rtt < reportBlock->minRTT) { | |
545 // Store min RTT. | |
546 reportBlock->minRTT = rtt; | |
547 } | |
548 // Store last RTT. | |
549 reportBlock->RTT = rtt; | |
550 | |
551 // store average RTT | |
552 if (reportBlock->numAverageCalcs != 0) { | |
553 float ac = static_cast<float>(reportBlock->numAverageCalcs); | |
554 float newAverage = | |
555 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt); | |
556 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f); | |
557 } else { | |
558 // First RTT. | |
559 reportBlock->avgRTT = rtt; | |
560 } | |
561 reportBlock->numAverageCalcs++; | |
562 } | |
563 | |
564 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC, | |
565 rtt); | |
566 | 511 |
567 rtcpPacketInformation.AddReportInfo(*reportBlock); | 512 rtcpPacketInformation.AddReportInfo(*reportBlock); |
568 } | 513 } |
569 | 514 |
570 RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation( | 515 ReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation( |
571 uint32_t remote_ssrc, | 516 uint32_t remote_ssrc, |
572 uint32_t source_ssrc) { | 517 uint32_t source_ssrc) { |
573 RTCPReportBlockInformation* info = | 518 ReportBlockInformation** info = |
574 GetReportBlockInformation(remote_ssrc, source_ssrc); | 519 &_receivedReportBlockMap[source_ssrc][remote_ssrc]; |
575 if (info == NULL) { | 520 if (!*info) { |
576 info = new RTCPReportBlockInformation; | 521 *info = new ReportBlockInformation; |
577 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info; | |
578 } | 522 } |
579 return info; | 523 return *info; |
580 } | 524 } |
581 | 525 |
582 RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation( | 526 const ReportBlockInformation* RTCPReceiver::GetReportBlockInformation( |
583 uint32_t remote_ssrc, | 527 uint32_t remote_ssrc, |
584 uint32_t source_ssrc) const { | 528 uint32_t source_ssrc) const { |
585 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc); | 529 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc); |
586 if (it == _receivedReportBlockMap.end()) { | 530 if (it == _receivedReportBlockMap.end()) { |
587 return NULL; | 531 return NULL; |
588 } | 532 } |
589 const ReportBlockInfoMap* info_map = &(it->second); | 533 const ReportBlockInfoMap* info_map = &(it->second); |
590 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc); | 534 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc); |
591 if (it_info == info_map->end()) { | 535 if (it_info == info_map->end()) { |
592 return NULL; | 536 return NULL; |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 return -1; | 1390 return -1; |
1447 } | 1391 } |
1448 num += receiveInfo->TmmbrSet.lengthOfSet(); | 1392 num += receiveInfo->TmmbrSet.lengthOfSet(); |
1449 receiveInfoIt++; | 1393 receiveInfoIt++; |
1450 } | 1394 } |
1451 } | 1395 } |
1452 return num; | 1396 return num; |
1453 } | 1397 } |
1454 | 1398 |
1455 } // namespace webrtc | 1399 } // namespace webrtc |
OLD | NEW |