Home | History | Annotate | Download | only in base
      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 CHROMECAST_MEDIA_CMA_BASE_BUFFERING_STATE_H_
      6 #define CHROMECAST_MEDIA_CMA_BASE_BUFFERING_STATE_H_
      7 
      8 #include <string>
      9 
     10 #include "base/callback.h"
     11 #include "base/macros.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/time/time.h"
     14 
     15 namespace chromecast {
     16 namespace media {
     17 
     18 class BufferingConfig : public base::RefCountedThreadSafe<BufferingConfig> {
     19  public:
     20   BufferingConfig(base::TimeDelta low_level_threshold,
     21                   base::TimeDelta high_level_threshold);
     22 
     23   base::TimeDelta low_level() const { return low_level_threshold_; }
     24   base::TimeDelta high_level() const { return high_level_threshold_; }
     25 
     26   void set_low_level(base::TimeDelta low_level) {
     27     low_level_threshold_ = low_level;
     28   }
     29   void set_high_level(base::TimeDelta high_level) {
     30     high_level_threshold_ = high_level;
     31   }
     32 
     33  private:
     34   friend class base::RefCountedThreadSafe<BufferingConfig>;
     35   virtual ~BufferingConfig();
     36 
     37   base::TimeDelta low_level_threshold_;
     38   base::TimeDelta high_level_threshold_;
     39 
     40   DISALLOW_COPY_AND_ASSIGN(BufferingConfig);
     41 };
     42 
     43 class BufferingState
     44     : public base::RefCountedThreadSafe<BufferingState> {
     45  public:
     46   typedef base::Callback<void(base::TimeDelta)> HighLevelBufferCB;
     47 
     48   enum State {
     49     kLowLevel,
     50     kMediumLevel,
     51     kHighLevel,
     52     kEosReached,
     53   };
     54 
     55   // Creates a new buffering state. The initial state is |kLowLevel|.
     56   // |state_changed_cb| is used to notify about possible state changes.
     57   // |high_level_buffer_cb| is used to adjust the high buffer threshold
     58   // when the underlying buffer is not large enough to accomodate
     59   // the current high buffer level.
     60   BufferingState(const scoped_refptr<BufferingConfig>& config,
     61                  const base::Closure& state_changed_cb,
     62                  const HighLevelBufferCB& high_level_buffer_cb);
     63 
     64   // Returns the buffering state.
     65   State GetState() const { return state_; }
     66 
     67   // Invoked when the buffering configuration has changed.
     68   // Based on the new configuration, the buffering state might change.
     69   // However, |state_changed_cb_| is not triggered in that case.
     70   void OnConfigChanged();
     71 
     72   // Sets the current rendering time for this stream.
     73   void SetMediaTime(base::TimeDelta media_time);
     74 
     75   // Sets/gets the maximum rendering media time for this stream.
     76   // The maximum rendering time is always lower than the buffered time.
     77   void SetMaxRenderingTime(base::TimeDelta max_rendering_time);
     78   base::TimeDelta GetMaxRenderingTime() const;
     79 
     80   // Sets the buffered time.
     81   void SetBufferedTime(base::TimeDelta buffered_time);
     82 
     83   // Notifies the buffering state that all the frames for this stream have been
     84   // buffered, i.e. the end of stream has been reached.
     85   void NotifyEos();
     86 
     87   // Notifies the buffering state the underlying buffer has reached
     88   // its maximum capacity.
     89   // The maximum frame timestamp in the buffer is given by |buffered_time|.
     90   // Note: this timestamp can be different from the one provided through
     91   // SetBufferedTime since SetBufferedTime takes the timestamp of a playable
     92   // frame which is not necessarily the case here (e.g. missing key id).
     93   void NotifyMaxCapacity(base::TimeDelta buffered_time);
     94 
     95   // Buffering state as a human readable string, for debugging.
     96   std::string ToString() const;
     97 
     98  private:
     99   friend class base::RefCountedThreadSafe<BufferingState>;
    100   virtual ~BufferingState();
    101 
    102   // Returns the state solely based on the buffered time.
    103   State GetBufferLevelState() const;
    104 
    105   // Updates the state to |new_state|.
    106   void UpdateState(State new_state);
    107 
    108   scoped_refptr<BufferingConfig> const config_;
    109 
    110   // Callback invoked each time there is a change of state.
    111   base::Closure state_changed_cb_;
    112 
    113   // Callback invoked to adjust the high buffer level.
    114   HighLevelBufferCB high_level_buffer_cb_;
    115 
    116   // State.
    117   State state_;
    118 
    119   // Playback media time.
    120   // Equal to kNoTimestamp() when not known.
    121   base::TimeDelta media_time_;
    122 
    123   // Maximum rendering media time.
    124   // This corresponds to the timestamp of the last frame sent to the hardware
    125   // decoder/renderer.
    126   base::TimeDelta max_rendering_time_;
    127 
    128   // Buffered media time.
    129   // Equal to kNoTimestamp() when not known.
    130   base::TimeDelta buffered_time_;
    131 
    132   DISALLOW_COPY_AND_ASSIGN(BufferingState);
    133 };
    134 
    135 }  // namespace media
    136 }  // namespace chromecast
    137 
    138 #endif  // CHROMECAST_MEDIA_CMA_BASE_BUFFERING_STATE_H_
    139