9d34583a769c185805c845d2c3a8848b7cfd925a
[platform/framework/web/crosswalk.git] / src / media / cast / rtp_receiver / receiver_stats.cc
1 // Copyright 2013 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/rtp_receiver/receiver_stats.h"
6
7 #include "base/logging.h"
8 #include "media/cast/rtp_receiver/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       *fraction_lost =  static_cast<uint8>((256 * (1 -
48           static_cast<float>(interval_number_packets_) / abs(diff))));
49     }
50   }
51
52   int expected_packets_num = max_sequence_number_ - min_sequence_number_ + 1;
53   if (total_number_packets_ == 0) {
54     *cumulative_lost = 0;
55   } else if (sequence_number_cycles_ == 0) {
56     *cumulative_lost = expected_packets_num - total_number_packets_;
57   } else {
58     *cumulative_lost = kMaxSequenceNumber * (sequence_number_cycles_ - 1) +
59         (expected_packets_num - total_number_packets_ + kMaxSequenceNumber);
60   }
61
62   // Extended high sequence number consists of the highest seq number and the
63   // number of cycles (wrap).
64   *extended_high_sequence_number = (sequence_number_cycles_ << 16) +
65       max_sequence_number_;
66
67   *jitter = static_cast<uint32>(abs(jitter_.InMillisecondsRoundedUp()));
68
69   // Reset interval values.
70   interval_min_sequence_number_ = 0;
71   interval_number_packets_ = 0;
72   interval_wrap_count_ = 0;
73 }
74
75 void ReceiverStats::UpdateStatistics(const RtpCastHeader& header) {
76   uint16 new_seq_num = header.webrtc.header.sequenceNumber;
77
78   if (interval_number_packets_ == 0) {
79     // First packet in the interval.
80     interval_min_sequence_number_ = new_seq_num;
81   }
82   if (total_number_packets_ == 0) {
83     // First incoming packet.
84     min_sequence_number_ = new_seq_num;
85     max_sequence_number_ = new_seq_num;
86   }
87
88   if (IsNewerSequenceNumber(new_seq_num, max_sequence_number_)) {
89     // Check wrap.
90     if (new_seq_num < max_sequence_number_) {
91       ++sequence_number_cycles_;
92       ++interval_wrap_count_;
93     }
94     max_sequence_number_ = new_seq_num;
95   }
96
97   // Compute Jitter.
98   base::TimeTicks now = clock_->NowTicks();
99   base::TimeDelta delta_new_timestamp =
100       base::TimeDelta::FromMilliseconds(header.webrtc.header.timestamp);
101   if (total_number_packets_ > 0) {
102     // Update jitter.
103     base::TimeDelta delta = (now - last_received_packet_time_) -
104         ((delta_new_timestamp - last_received_timestamp_) / 90);
105     jitter_ += (delta - jitter_) / 16;
106   }
107   last_received_timestamp_ = delta_new_timestamp;
108   last_received_packet_time_ = now;
109
110   // Increment counters.
111   ++total_number_packets_;
112   ++interval_number_packets_;
113 }
114
115 }  // namespace cast
116 }  // namespace media