Home | History | Annotate | Download | only in logging
      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.
      4 
      5 #ifndef MEDIA_CAST_LOGGING_RECEIVER_TIME_OFFSET_ESTIMATOR_IMPL_H_
      6 #define MEDIA_CAST_LOGGING_RECEIVER_TIME_OFFSET_ESTIMATOR_IMPL_H_
      7 
      8 #include <map>
      9 
     10 #include "base/time/time.h"
     11 #include "base/threading/thread_checker.h"
     12 #include "media/cast/common/mod_util.h"
     13 #include "media/cast/logging/logging_defines.h"
     14 #include "media/cast/logging/receiver_time_offset_estimator.h"
     15 
     16 namespace media {
     17 namespace cast {
     18 
     19 
     20 // This should be large enough so that we can collect all 3 events before
     21 // the entry gets removed from the map.
     22 const size_t kMaxEventTimesMapSize = 500;
     23 
     24 // The lower, this is, the faster we adjust to clock drift.
     25 // (But with more jitter.)
     26 const size_t kClockDriftSpeed = 500;
     27 
     28 
     29 // This implementation listens to two pair of events
     30 // 1. FRAME_ACK_SENT / FRAME_ACK_RECEIVED  (receiver->sender)
     31 // 2. PACKET_SENT_TO_NETWORK / PACKET_RECEIVED (sender->receiver)
     32 // There is a causal relationship between these events in that these events
     33 // must happen in order. This class obtains the lower and upper bounds for
     34 // the offset by taking the difference of timestamps.
     35 class ReceiverTimeOffsetEstimatorImpl : public ReceiverTimeOffsetEstimator {
     36  public:
     37   ReceiverTimeOffsetEstimatorImpl();
     38 
     39   virtual ~ReceiverTimeOffsetEstimatorImpl();
     40 
     41   // RawEventSubscriber implementations.
     42   virtual void OnReceiveFrameEvent(const FrameEvent& frame_event) OVERRIDE;
     43   virtual void OnReceivePacketEvent(const PacketEvent& packet_event) OVERRIDE;
     44 
     45   // ReceiverTimeOffsetEstimator implementation.
     46   virtual bool GetReceiverOffsetBounds(base::TimeDelta* lower_bound,
     47                                        base::TimeDelta* upper_bound) OVERRIDE;
     48 
     49  private:
     50   // This helper uses the difference between sent and recived event
     51   // to calculate an upper bound on the difference between the clocks
     52   // on the sender and receiver. Note that this difference can take
     53   // very large positive or negative values, but the smaller value is
     54   // always the better estimate, since a receive event cannot possibly
     55   // happen before a send event.  Note that we use this to calculate
     56   // both upper and lower bounds by reversing the sender/receiver
     57   // relationship.
     58   class BoundCalculator {
     59    public:
     60     typedef std::pair<base::TimeTicks, base::TimeTicks> TimeTickPair;
     61     typedef std::map<uint64, TimeTickPair> EventMap;
     62 
     63     BoundCalculator();
     64     ~BoundCalculator();
     65     bool has_bound() const { return has_bound_; }
     66     base::TimeDelta bound() const { return bound_; }
     67 
     68     void SetSent(uint32 rtp,
     69                  uint32 packet_id,
     70                  bool audio,
     71                  base::TimeTicks t);
     72 
     73     void SetReceived(uint32 rtp,
     74                      uint16 packet_id,
     75                      bool audio,
     76                      base::TimeTicks t);
     77 
     78    private:
     79     void UpdateBound(base::TimeTicks a, base::TimeTicks b);
     80     void CheckUpdate(uint64 key);
     81 
     82    private:
     83     EventMap events_;
     84     bool has_bound_;
     85     base::TimeDelta bound_;
     86   };
     87 
     88   // Fixed size storage to store event times for recent frames.
     89   BoundCalculator upper_bound_;
     90   BoundCalculator lower_bound_;
     91 
     92   base::ThreadChecker thread_checker_;
     93   DISALLOW_COPY_AND_ASSIGN(ReceiverTimeOffsetEstimatorImpl);
     94 };
     95 
     96 }  // namespace cast
     97 }  // namespace media
     98 
     99 #endif  // MEDIA_CAST_LOGGING_RECEIVER_TIME_OFFSET_ESTIMATOR_IMPL_H_
    100