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.
8 #include "base/logging.h"
9 #include "base/time/tick_clock.h"
10 #include "media/cast/logging/receiver_time_offset_estimator_impl.h"
15 ReceiverTimeOffsetEstimatorImpl::BoundCalculator::BoundCalculator()
16 : has_bound_(false) {}
17 ReceiverTimeOffsetEstimatorImpl::BoundCalculator::~BoundCalculator() {}
19 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::SetSent(
24 uint64 key
= (static_cast<uint64
>(rtp
) << 32) | (packet_id
<< 1) |
25 static_cast<uint64
>(audio
);
26 events_
[key
].first
= t
;
30 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::SetReceived(
35 uint64 key
= (static_cast<uint64
>(rtp
) << 32) | (packet_id
<< 1) |
36 static_cast<uint64
>(audio
);
37 events_
[key
].second
= t
;
41 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::UpdateBound(
42 base::TimeTicks sent
, base::TimeTicks received
) {
43 base::TimeDelta delta
= received
- sent
;
48 bound_
+= (delta
- bound_
) / kClockDriftSpeed
;
56 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::CheckUpdate(
58 const TimeTickPair
& ticks
= events_
[key
];
59 if (!ticks
.first
.is_null() && !ticks
.second
.is_null()) {
60 UpdateBound(ticks
.first
, ticks
.second
);
65 if (events_
.size() > kMaxEventTimesMapSize
) {
66 EventMap::iterator i
= ModMapOldest(&events_
);
67 if (i
!= events_
.end()) {
73 ReceiverTimeOffsetEstimatorImpl::ReceiverTimeOffsetEstimatorImpl() {
76 ReceiverTimeOffsetEstimatorImpl::~ReceiverTimeOffsetEstimatorImpl() {
77 DCHECK(thread_checker_
.CalledOnValidThread());
81 void ReceiverTimeOffsetEstimatorImpl::OnReceiveFrameEvent(
82 const FrameEvent
& frame_event
) {
83 DCHECK(thread_checker_
.CalledOnValidThread());
84 switch (frame_event
.type
) {
86 lower_bound_
.SetSent(frame_event
.rtp_timestamp
,
88 frame_event
.media_type
== AUDIO_EVENT
,
89 frame_event
.timestamp
);
91 case FRAME_ACK_RECEIVED
:
92 lower_bound_
.SetReceived(frame_event
.rtp_timestamp
,
94 frame_event
.media_type
== AUDIO_EVENT
,
95 frame_event
.timestamp
);
103 bool ReceiverTimeOffsetEstimatorImpl::GetReceiverOffsetBounds(
104 base::TimeDelta
* lower_bound
,
105 base::TimeDelta
* upper_bound
) {
106 if (!lower_bound_
.has_bound() || !upper_bound_
.has_bound())
109 *lower_bound
= -lower_bound_
.bound();
110 *upper_bound
= upper_bound_
.bound();
112 // Sanitize the output, we don't want the upper bound to be
113 // lower than the lower bound, make them the same.
114 if (upper_bound
< lower_bound
) {
115 lower_bound
+= (lower_bound
- upper_bound
) / 2;
116 upper_bound
= lower_bound
;
121 void ReceiverTimeOffsetEstimatorImpl::OnReceivePacketEvent(
122 const PacketEvent
& packet_event
) {
123 DCHECK(thread_checker_
.CalledOnValidThread());
124 switch (packet_event
.type
) {
125 case PACKET_SENT_TO_NETWORK
:
126 upper_bound_
.SetSent(packet_event
.rtp_timestamp
,
127 packet_event
.packet_id
,
128 packet_event
.media_type
== AUDIO_EVENT
,
129 packet_event
.timestamp
);
131 case PACKET_RECEIVED
:
132 upper_bound_
.SetReceived(packet_event
.rtp_timestamp
,
133 packet_event
.packet_id
,
134 packet_event
.media_type
== AUDIO_EVENT
,
135 packet_event
.timestamp
);