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.
5 #include "media/cast/rtp_receiver/receiver_stats.h"
7 #include "base/logging.h"
8 #include "media/cast/rtp_receiver/rtp_receiver_defines.h"
13 static const uint32 kMaxSequenceNumber
= 65536;
15 ReceiverStats::ReceiverStats(base::TickClock
* 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) {}
25 ReceiverStats::~ReceiverStats() {}
27 void ReceiverStats::GetStatistics(uint8
* fraction_lost
,
28 uint32
* cumulative_lost
,
29 uint32
* extended_high_sequence_number
,
32 if (interval_number_packets_
== 0) {
36 if (interval_wrap_count_
== 0) {
37 diff
= max_sequence_number_
- interval_min_sequence_number_
+ 1;
39 diff
= kMaxSequenceNumber
* (interval_wrap_count_
- 1) +
40 (max_sequence_number_
- interval_min_sequence_number_
+
41 kMaxSequenceNumber
+ 1);
48 (1 - static_cast<float>(interval_number_packets_
) / abs(diff
));
49 *fraction_lost
= static_cast<uint8
>(256 * tmp_ratio
);
53 int expected_packets_num
= max_sequence_number_
- min_sequence_number_
+ 1;
54 if (total_number_packets_
== 0) {
56 } else if (sequence_number_cycles_
== 0) {
57 *cumulative_lost
= expected_packets_num
- total_number_packets_
;
60 kMaxSequenceNumber
* (sequence_number_cycles_
- 1) +
61 (expected_packets_num
- total_number_packets_
+ kMaxSequenceNumber
);
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_
;
69 *jitter
= static_cast<uint32
>(std::abs(jitter_
.InMillisecondsRoundedUp()));
71 // Reset interval values.
72 interval_min_sequence_number_
= 0;
73 interval_number_packets_
= 0;
74 interval_wrap_count_
= 0;
77 void ReceiverStats::UpdateStatistics(const RtpCastHeader
& header
) {
78 const uint16 new_seq_num
= header
.sequence_number
;
80 if (interval_number_packets_
== 0) {
81 // First packet in the interval.
82 interval_min_sequence_number_
= new_seq_num
;
84 if (total_number_packets_
== 0) {
85 // First incoming packet.
86 min_sequence_number_
= new_seq_num
;
87 max_sequence_number_
= new_seq_num
;
90 if (IsNewerSequenceNumber(new_seq_num
, max_sequence_number_
)) {
92 if (new_seq_num
< max_sequence_number_
) {
93 ++sequence_number_cycles_
;
94 ++interval_wrap_count_
;
96 max_sequence_number_
= new_seq_num
;
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) {
105 base::TimeDelta delta
=
106 (now
- last_received_packet_time_
) -
107 ((delta_new_timestamp
- last_received_timestamp_
) / 90);
108 jitter_
+= (delta
- jitter_
) / 16;
110 last_received_timestamp_
= delta_new_timestamp
;
111 last_received_packet_time_
= now
;
113 // Increment counters.
114 ++total_number_packets_
;
115 ++interval_number_packets_
;