Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / cast / logging / receiver_time_offset_estimator_impl.cc
blobd5116542d6bfbc08bfd4eceab9de1ab0d4f1bf63
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 <algorithm>
6 #include <utility>
8 #include "base/logging.h"
9 #include "base/time/tick_clock.h"
10 #include "media/cast/logging/receiver_time_offset_estimator_impl.h"
12 namespace media {
13 namespace cast {
15 ReceiverTimeOffsetEstimatorImpl::BoundCalculator::BoundCalculator()
16 : has_bound_(false) {}
17 ReceiverTimeOffsetEstimatorImpl::BoundCalculator::~BoundCalculator() {}
19 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::SetSent(
20 uint32 rtp,
21 uint32 packet_id,
22 bool audio,
23 base::TimeTicks t) {
24 uint64 key = (static_cast<uint64>(rtp) << 32) | (packet_id << 1) |
25 static_cast<uint64>(audio);
26 events_[key].first = t;
27 CheckUpdate(key);
30 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::SetReceived(
31 uint32 rtp,
32 uint16 packet_id,
33 bool audio,
34 base::TimeTicks t) {
35 uint64 key = (static_cast<uint64>(rtp) << 32) | (packet_id << 1) |
36 static_cast<uint64>(audio);
37 events_[key].second = t;
38 CheckUpdate(key);
41 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::UpdateBound(
42 base::TimeTicks sent, base::TimeTicks received) {
43 base::TimeDelta delta = received - sent;
44 if (has_bound_) {
45 if (delta < bound_) {
46 bound_ = delta;
47 } else {
48 bound_ += (delta - bound_) / kClockDriftSpeed;
50 } else {
51 bound_ = delta;
53 has_bound_ = true;
56 void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::CheckUpdate(
57 uint64 key) {
58 const TimeTickPair& ticks = events_[key];
59 if (!ticks.first.is_null() && !ticks.second.is_null()) {
60 UpdateBound(ticks.first, ticks.second);
61 events_.erase(key);
62 return;
65 if (events_.size() > kMaxEventTimesMapSize) {
66 EventMap::iterator i = ModMapOldest(&events_);
67 if (i != events_.end()) {
68 events_.erase(i);
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) {
85 case FRAME_ACK_SENT:
86 lower_bound_.SetSent(frame_event.rtp_timestamp,
88 frame_event.media_type == AUDIO_EVENT,
89 frame_event.timestamp);
90 break;
91 case FRAME_ACK_RECEIVED:
92 lower_bound_.SetReceived(frame_event.rtp_timestamp,
94 frame_event.media_type == AUDIO_EVENT,
95 frame_event.timestamp);
96 break;
97 default:
98 // Ignored
99 break;
103 bool ReceiverTimeOffsetEstimatorImpl::GetReceiverOffsetBounds(
104 base::TimeDelta* lower_bound,
105 base::TimeDelta* upper_bound) {
106 if (!lower_bound_.has_bound() || !upper_bound_.has_bound())
107 return false;
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;
118 return true;
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);
130 break;
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);
136 break;
137 default:
138 // Ignored
139 break;
144 } // namespace cast
145 } // namespace media