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.
5 #include "media/cast/net/rtp/receiver_stats.h"
7 #include "base/logging.h"
8 #include "media/cast/net/rtp/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 RtpReceiverStatistics
ReceiverStats::GetStatistics() {
26 RtpReceiverStatistics ret
;
28 if (interval_number_packets_
== 0) {
29 ret
.fraction_lost
= 0;
32 if (interval_wrap_count_
== 0) {
33 diff
= max_sequence_number_
- interval_min_sequence_number_
+ 1;
35 diff
= kMaxSequenceNumber
* (interval_wrap_count_
- 1) +
36 (max_sequence_number_
- interval_min_sequence_number_
+
37 kMaxSequenceNumber
+ 1);
41 ret
.fraction_lost
= 0;
44 (1 - static_cast<float>(interval_number_packets_
) / abs(diff
));
45 ret
.fraction_lost
= static_cast<uint8
>(256 * tmp_ratio
);
49 int expected_packets_num
= max_sequence_number_
- min_sequence_number_
+ 1;
50 if (total_number_packets_
== 0) {
51 ret
.cumulative_lost
= 0;
52 } else if (sequence_number_cycles_
== 0) {
53 ret
.cumulative_lost
= expected_packets_num
- total_number_packets_
;
56 kMaxSequenceNumber
* (sequence_number_cycles_
- 1) +
57 (expected_packets_num
- total_number_packets_
+ kMaxSequenceNumber
);
60 // Extended high sequence number consists of the highest seq number and the
61 // number of cycles (wrap).
62 ret
.extended_high_sequence_number
=
63 (sequence_number_cycles_
<< 16) + max_sequence_number_
;
65 ret
.jitter
= static_cast<uint32
>(std::abs(jitter_
.InMillisecondsRoundedUp()));
67 // Reset interval values.
68 interval_min_sequence_number_
= 0;
69 interval_number_packets_
= 0;
70 interval_wrap_count_
= 0;
75 void ReceiverStats::UpdateStatistics(const RtpCastHeader
& header
) {
76 const uint16 new_seq_num
= header
.sequence_number
;
78 if (interval_number_packets_
== 0) {
79 // First packet in the interval.
80 interval_min_sequence_number_
= new_seq_num
;
82 if (total_number_packets_
== 0) {
83 // First incoming packet.
84 min_sequence_number_
= new_seq_num
;
85 max_sequence_number_
= new_seq_num
;
88 if (IsNewerSequenceNumber(new_seq_num
, max_sequence_number_
)) {
90 if (new_seq_num
< max_sequence_number_
) {
91 ++sequence_number_cycles_
;
92 ++interval_wrap_count_
;
94 max_sequence_number_
= new_seq_num
;
98 base::TimeTicks now
= clock_
->NowTicks();
99 base::TimeDelta delta_new_timestamp
=
100 base::TimeDelta::FromMilliseconds(header
.rtp_timestamp
);
101 if (total_number_packets_
> 0) {
103 base::TimeDelta delta
=
104 (now
- last_received_packet_time_
) -
105 ((delta_new_timestamp
- last_received_timestamp_
) / 90);
106 jitter_
+= (delta
- jitter_
) / 16;
108 last_received_timestamp_
= delta_new_timestamp
;
109 last_received_packet_time_
= now
;
111 // Increment counters.
112 ++total_number_packets_
;
113 ++interval_number_packets_
;