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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 int32_t RTCPReceiver::RTT(uint32_t remoteSSRC, | 166 int32_t RTCPReceiver::RTT(uint32_t remoteSSRC, |
167 int64_t* RTT, | 167 int64_t* RTT, |
168 int64_t* avgRTT, | 168 int64_t* avgRTT, |
169 int64_t* minRTT, | 169 int64_t* minRTT, |
170 int64_t* maxRTT) const { | 170 int64_t* maxRTT) const { |
171 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 171 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
172 | 172 |
173 RTCPReportBlockInformation* reportBlock = | 173 const ReportBlockInformation* report_block = |
174 GetReportBlockInformation(remoteSSRC, main_ssrc_); | 174 GetReportBlockInformation(remoteSSRC, main_ssrc_); |
175 | 175 |
176 if (reportBlock == NULL) { | 176 if (!report_block || !report_block->HasRtt()) { |
177 return -1; | 177 return -1; |
178 } | 178 } |
179 if (RTT) { | 179 if (RTT) { |
180 *RTT = reportBlock->RTT; | 180 *RTT = report_block->LastRttMs(); |
181 } | 181 } |
182 if (avgRTT) { | 182 if (avgRTT) { |
183 *avgRTT = reportBlock->avgRTT; | 183 *avgRTT = report_block->AvgRttMs(); |
184 } | 184 } |
185 if (minRTT) { | 185 if (minRTT) { |
186 *minRTT = reportBlock->minRTT; | 186 *minRTT = report_block->MinRttMs(); |
187 } | 187 } |
188 if (maxRTT) { | 188 if (maxRTT) { |
189 *maxRTT = reportBlock->maxRTT; | 189 *maxRTT = report_block->MaxRttMs(); |
190 } | 190 } |
191 return 0; | 191 return 0; |
192 } | 192 } |
193 | 193 |
194 bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) { | 194 bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) { |
195 assert(rtt_ms); | 195 assert(rtt_ms); |
196 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 196 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
197 if (xr_rr_rtt_ms_ == 0) { | 197 if (xr_rr_rtt_ms_ == 0) { |
198 return false; | 198 return false; |
199 } | 199 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 // we can get multiple receive reports when we receive the report from a CE | 270 // we can get multiple receive reports when we receive the report from a CE |
271 int32_t RTCPReceiver::StatisticsReceived( | 271 int32_t RTCPReceiver::StatisticsReceived( |
272 std::vector<RTCPReportBlock>* receiveBlocks) const { | 272 std::vector<RTCPReportBlock>* receiveBlocks) const { |
273 assert(receiveBlocks); | 273 assert(receiveBlocks); |
274 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 274 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
275 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin(); | 275 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin(); |
276 for (; it != _receivedReportBlockMap.end(); ++it) { | 276 for (; it != _receivedReportBlockMap.end(); ++it) { |
277 const ReportBlockInfoMap* info_map = &(it->second); | 277 const ReportBlockInfoMap* info_map = &(it->second); |
278 ReportBlockInfoMap::const_iterator it_info = info_map->begin(); | 278 ReportBlockInfoMap::const_iterator it_info = info_map->begin(); |
279 for (; it_info != info_map->end(); ++it_info) { | 279 for (; it_info != info_map->end(); ++it_info) { |
280 receiveBlocks->push_back(it_info->second->remoteReceiveBlock); | 280 receiveBlocks->push_back(it_info->second->LastBlock()); |
281 } | 281 } |
282 } | 282 } |
283 return 0; | 283 return 0; |
284 } | 284 } |
285 | 285 |
286 int32_t | 286 int32_t |
287 RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, | 287 RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, |
288 RTCPUtility::RTCPParserV2* rtcpParser) | 288 RTCPUtility::RTCPParserV2* rtcpParser) |
289 { | 289 { |
290 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); | 290 CriticalSectionScoped lock(_criticalSectionRTCPReceiver); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to | 481 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to |
482 // which the information in this reception report block pertains. | 482 // which the information in this reception report block pertains. |
483 | 483 |
484 // Filter out all report blocks that are not for us. | 484 // Filter out all report blocks that are not for us. |
485 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) == | 485 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) == |
486 registered_ssrcs_.end()) { | 486 registered_ssrcs_.end()) { |
487 // This block is not for us ignore it. | 487 // This block is not for us ignore it. |
488 return; | 488 return; |
489 } | 489 } |
490 | 490 |
491 RTCPReportBlockInformation* reportBlock = | 491 ReportBlockInformation* reportBlock = CreateOrGetReportBlockInformation( |
492 CreateOrGetReportBlockInformation(remoteSSRC, | 492 remoteSSRC, rtcpPacket.ReportBlockItem.SSRC); |
493 rtcpPacket.ReportBlockItem.SSRC); | 493 |
494 if (reportBlock == NULL) { | 494 if (reportBlock == NULL) { |
495 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation(" | 495 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation(" |
496 << remoteSSRC << ")"; | 496 << remoteSSRC << ")"; |
497 return; | 497 return; |
498 } | 498 } |
499 | 499 |
500 _lastReceivedRrMs = _clock->TimeInMilliseconds(); | 500 _lastReceivedRrMs = _clock->TimeInMilliseconds(); |
501 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem; | 501 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem; |
502 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC; | |
503 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC; | |
504 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost; | |
505 reportBlock->remoteReceiveBlock.cumulativeLost = | |
506 rb.CumulativeNumOfPacketsLost; | |
507 if (rb.ExtendedHighestSequenceNumber > | 502 if (rb.ExtendedHighestSequenceNumber > |
508 reportBlock->remoteReceiveBlock.extendedHighSeqNum) { | 503 reportBlock->LastBlock().extendedHighSeqNum) { |
509 // We have successfully delivered new RTP packets to the remote side after | 504 // We have successfully delivered new RTP packets to the remote side after |
510 // the last RR was sent from the remote side. | 505 // the last RR was sent from the remote side. |
511 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs; | 506 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs; |
512 } | 507 } |
513 reportBlock->remoteReceiveBlock.extendedHighSeqNum = | |
514 rb.ExtendedHighestSequenceNumber; | |
515 reportBlock->remoteReceiveBlock.jitter = rb.Jitter; | |
516 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR; | |
517 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR; | |
518 | 508 |
519 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) { | 509 reportBlock->AddBlock(rb, remoteSSRC, NtpTime(*_clock)); |
520 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter; | |
521 } | |
522 | |
523 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR; | |
524 uint32_t rtt = 0; | |
525 | |
526 if (send_time > 0) { | |
527 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR; | |
528 // Local NTP time. | |
529 uint32_t receive_time = CompactNtp(NtpTime(*_clock)); | |
530 | |
531 // RTT in 1/(2^16) seconds. | |
532 uint32_t rtt_ntp = receive_time - delay - send_time; | |
533 // Convert to 1/1000 seconds (milliseconds). | |
534 uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp); | |
535 rtt = std::max<uint32_t>(rtt_ms, 1); | |
536 if (rtt > reportBlock->maxRTT) { | |
537 // Store max RTT. | |
538 reportBlock->maxRTT = rtt; | |
539 } | |
540 if (reportBlock->minRTT == 0) { | |
541 // First RTT. | |
542 reportBlock->minRTT = rtt; | |
543 } else if (rtt < reportBlock->minRTT) { | |
544 // Store min RTT. | |
545 reportBlock->minRTT = rtt; | |
546 } | |
547 // Store last RTT. | |
548 reportBlock->RTT = rtt; | |
549 | |
550 // store average RTT | |
551 if (reportBlock->numAverageCalcs != 0) { | |
552 float ac = static_cast<float>(reportBlock->numAverageCalcs); | |
553 float newAverage = | |
554 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt); | |
555 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f); | |
556 } else { | |
557 // First RTT. | |
558 reportBlock->avgRTT = rtt; | |
559 } | |
560 reportBlock->numAverageCalcs++; | |
561 } | |
562 | |
563 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC, | |
564 rtt); | |
565 | 510 |
566 rtcpPacketInformation.AddReportInfo(*reportBlock); | 511 rtcpPacketInformation.AddReportInfo(*reportBlock); |
567 } | 512 } |
568 | 513 |
569 RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation( | 514 ReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation( |
570 uint32_t remote_ssrc, | 515 uint32_t remote_ssrc, |
571 uint32_t source_ssrc) { | 516 uint32_t source_ssrc) { |
572 RTCPReportBlockInformation* info = | 517 ReportBlockInformation** info = |
573 GetReportBlockInformation(remote_ssrc, source_ssrc); | 518 &_receivedReportBlockMap[source_ssrc][remote_ssrc]; |
574 if (info == NULL) { | 519 if (!*info) { |
575 info = new RTCPReportBlockInformation; | 520 *info = new ReportBlockInformation; |
576 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info; | |
577 } | 521 } |
578 return info; | 522 return *info; |
579 } | 523 } |
580 | 524 |
581 RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation( | 525 const ReportBlockInformation* RTCPReceiver::GetReportBlockInformation( |
582 uint32_t remote_ssrc, | 526 uint32_t remote_ssrc, |
583 uint32_t source_ssrc) const { | 527 uint32_t source_ssrc) const { |
584 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc); | 528 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc); |
585 if (it == _receivedReportBlockMap.end()) { | 529 if (it == _receivedReportBlockMap.end()) { |
586 return NULL; | 530 return NULL; |
587 } | 531 } |
588 const ReportBlockInfoMap* info_map = &(it->second); | 532 const ReportBlockInfoMap* info_map = &(it->second); |
589 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc); | 533 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc); |
590 if (it_info == info_map->end()) { | 534 if (it_info == info_map->end()) { |
591 return NULL; | 535 return NULL; |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 return -1; | 1389 return -1; |
1446 } | 1390 } |
1447 num += receiveInfo->TmmbrSet.lengthOfSet(); | 1391 num += receiveInfo->TmmbrSet.lengthOfSet(); |
1448 receiveInfoIt++; | 1392 receiveInfoIt++; |
1449 } | 1393 } |
1450 } | 1394 } |
1451 return num; | 1395 return num; |
1452 } | 1396 } |
1453 | 1397 |
1454 } // namespace webrtc | 1398 } // namespace webrtc |
OLD | NEW |