Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / cast / net / rtp / receiver_stats.cc
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.
4
5 #include "media/cast/net/rtp/receiver_stats.h"
6
7 #include "base/logging.h"
8 #include "media/cast/net/rtp/rtp_receiver_defines.h"
9
10 namespace media {
11 namespace cast {
12
13 static const uint32 kMaxSequenceNumber = 65536;
14
15 ReceiverStats::ReceiverStats(base::TickClock* clock)
16     : clock_(clock),
17       min_sequence_number_(0),
18       max_sequence_number_(0),
19       total_number_packets_(0),
20       sequence_number_cycles_(0),
21       interval_min_sequence_number_(0),
22       interval_number_packets_(0),
23       interval_wrap_count_(0) {}
24
25 ReceiverStats::~ReceiverStats() {}
26
27 void ReceiverStats::GetStatistics(uint8* fraction_lost,
28                                   uint32* cumulative_lost,
29                                   uint32* extended_high_sequence_number,
30                                   uint32* jitter) {
31   // Compute losses.
32   if (interval_number_packets_ == 0) {
33     *fraction_lost = 0;
34   } else {
35     int diff = 0;
36     if (interval_wrap_count_ == 0) {
37       diff = max_sequence_number_ - interval_min_sequence_number_ + 1;
38     } else {
39       diff = kMaxSequenceNumber * (interval_wrap_count_ - 1) +
40              (max_sequence_number_ - interval_min_sequence_number_ +
41               kMaxSequenceNumber + 1);
42     }
43
44     if (diff < 1) {
45       *fraction_lost = 0;
46     } else {
47       float tmp_ratio =
48           (1 - static_cast<float>(interval_number_packets_) / abs(diff));
49       *fraction_lost = static_cast<uint8>(256 * tmp_ratio);
50     }
51   }
52
53   int expected_packets_num = max_sequence_number_ - min_sequence_number_ + 1;
54   if (total_number_packets_ == 0) {
55     *cumulative_lost = 0;
56   } else if (sequence_number_cycles_ == 0) {
57     *cumulative_lost = expected_packets_num - total_number_packets_;
58   } else {
59     *cumulative_lost =
60         kMaxSequenceNumber * (sequence_number_cycles_ - 1) +
61         (expected_packets_num - total_number_packets_ + kMaxSequenceNumber);
62   }
63
64   // Extended high sequence number consists of the highest seq number and the
65   // number of cycles (wrap).
66   *extended_high_sequence_number =
67       (sequence_number_cycles_ << 16) + max_sequence_number_;
68
69   *jitter = static_cast<uint32>(std::abs(jitter_.InMillisecondsRoundedUp()));
70
71   // Reset interval values.
72   interval_min_sequence_number_ = 0;
73   interval_number_packets_ = 0;
74   interval_wrap_count_ = 0;
75 }
76
77 void ReceiverStats::UpdateStatistics(const RtpCastHeader& header) {
78   const uint16 new_seq_num = header.sequence_number;
79
80   if (interval_number_packets_ == 0) {
81     // First packet in the interval.
82     interval_min_sequence_number_ = new_seq_num;
83   }
84   if (total_number_packets_ == 0) {
85     // First incoming packet.
86     min_sequence_number_ = new_seq_num;
87     max_sequence_number_ = new_seq_num;
88   }
89
90   if (IsNewerSequenceNumber(new_seq_num, max_sequence_number_)) {
91     // Check wrap.
92     if (new_seq_num < max_sequence_number_) {
93       ++sequence_number_cycles_;
94       ++interval_wrap_count_;
95     }
96     max_sequence_number_ = new_seq_num;
97   }
98
99   // Compute Jitter.
100   base::TimeTicks now = clock_->NowTicks();
101   base::TimeDelta delta_new_timestamp =
102       base::TimeDelta::FromMilliseconds(header.rtp_timestamp);
103   if (total_number_packets_ > 0) {
104     // Update jitter.
105     base::TimeDelta delta =
106         (now - last_received_packet_time_) -
107         ((delta_new_timestamp - last_received_timestamp_) / 90);
108     jitter_ += (delta - jitter_) / 16;
109   }
110   last_received_timestamp_ = delta_new_timestamp;
111   last_received_packet_time_ = now;
112
113   // Increment counters.
114   ++total_number_packets_;
115   ++interval_number_packets_;
116 }
117
118 }  // namespace cast
119 }  // namespace media