Line data Source code
1 : /*
2 : * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 : *
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
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/video/report_block_stats.h"
12 :
13 : namespace webrtc {
14 :
15 : namespace {
16 0 : int FractionLost(uint32_t num_lost_sequence_numbers,
17 : uint32_t num_sequence_numbers) {
18 0 : if (num_sequence_numbers == 0) {
19 0 : return 0;
20 : }
21 0 : return ((num_lost_sequence_numbers * 255) + (num_sequence_numbers / 2)) /
22 0 : num_sequence_numbers;
23 : }
24 : } // namespace
25 :
26 :
27 : // Helper class for rtcp statistics.
28 0 : ReportBlockStats::ReportBlockStats()
29 : : num_sequence_numbers_(0),
30 0 : num_lost_sequence_numbers_(0) {
31 0 : }
32 :
33 0 : void ReportBlockStats::Store(const RtcpStatistics& rtcp_stats,
34 : uint32_t remote_ssrc,
35 : uint32_t source_ssrc) {
36 0 : RTCPReportBlock block;
37 0 : block.cumulativeLost = rtcp_stats.cumulative_lost;
38 0 : block.fractionLost = rtcp_stats.fraction_lost;
39 0 : block.extendedHighSeqNum = rtcp_stats.extended_max_sequence_number;
40 0 : block.jitter = rtcp_stats.jitter;
41 0 : block.remoteSSRC = remote_ssrc;
42 0 : block.sourceSSRC = source_ssrc;
43 0 : uint32_t num_sequence_numbers = 0;
44 0 : uint32_t num_lost_sequence_numbers = 0;
45 : StoreAndAddPacketIncrement(
46 0 : block, &num_sequence_numbers, &num_lost_sequence_numbers);
47 0 : }
48 :
49 0 : RTCPReportBlock ReportBlockStats::AggregateAndStore(
50 : const ReportBlockVector& report_blocks) {
51 0 : RTCPReportBlock aggregate;
52 0 : if (report_blocks.empty()) {
53 0 : return aggregate;
54 : }
55 0 : uint32_t num_sequence_numbers = 0;
56 0 : uint32_t num_lost_sequence_numbers = 0;
57 0 : ReportBlockVector::const_iterator report_block = report_blocks.begin();
58 0 : for (; report_block != report_blocks.end(); ++report_block) {
59 0 : aggregate.cumulativeLost += report_block->cumulativeLost;
60 0 : aggregate.jitter += report_block->jitter;
61 0 : StoreAndAddPacketIncrement(*report_block,
62 : &num_sequence_numbers,
63 0 : &num_lost_sequence_numbers);
64 : }
65 :
66 0 : if (report_blocks.size() == 1) {
67 : // No aggregation needed.
68 0 : return report_blocks[0];
69 : }
70 : // Fraction lost since previous report block.
71 0 : aggregate.fractionLost =
72 0 : FractionLost(num_lost_sequence_numbers, num_sequence_numbers);
73 0 : aggregate.jitter = static_cast<uint32_t>(
74 0 : (aggregate.jitter + report_blocks.size() / 2) / report_blocks.size());
75 0 : return aggregate;
76 : }
77 :
78 0 : void ReportBlockStats::StoreAndAddPacketIncrement(
79 : const RTCPReportBlock& report_block,
80 : uint32_t* num_sequence_numbers,
81 : uint32_t* num_lost_sequence_numbers) {
82 : // Get diff with previous report block.
83 : ReportBlockMap::iterator prev_report_block = prev_report_blocks_.find(
84 0 : report_block.sourceSSRC);
85 0 : if (prev_report_block != prev_report_blocks_.end()) {
86 0 : int seq_num_diff = report_block.extendedHighSeqNum -
87 0 : prev_report_block->second.extendedHighSeqNum;
88 0 : int cum_loss_diff = report_block.cumulativeLost -
89 0 : prev_report_block->second.cumulativeLost;
90 0 : if (seq_num_diff >= 0 && cum_loss_diff >= 0) {
91 0 : *num_sequence_numbers += seq_num_diff;
92 0 : *num_lost_sequence_numbers += cum_loss_diff;
93 : // Update total number of packets/lost packets.
94 0 : num_sequence_numbers_ += seq_num_diff;
95 0 : num_lost_sequence_numbers_ += cum_loss_diff;
96 : }
97 : }
98 : // Store current report block.
99 0 : prev_report_blocks_[report_block.sourceSSRC] = report_block;
100 0 : }
101 :
102 0 : int ReportBlockStats::FractionLostInPercent() const {
103 0 : if (num_sequence_numbers_ == 0) {
104 0 : return -1;
105 : }
106 0 : return FractionLost(
107 0 : num_lost_sequence_numbers_, num_sequence_numbers_) * 100 / 255;
108 : }
109 :
110 : } // namespace webrtc
111 :
|