11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifndef CHROMECAST_MEDIA_CMA_BASE_BUFFERING_STATE_H_
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define CHROMECAST_MEDIA_CMA_BASE_BUFFERING_STATE_H_
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string>
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/ref_counted.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromecast {
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media {
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass BufferingConfig : public base::RefCountedThreadSafe<BufferingConfig> {
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BufferingConfig(base::TimeDelta low_level_threshold,
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  base::TimeDelta high_level_threshold);
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta low_level() const { return low_level_threshold_; }
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta high_level() const { return high_level_threshold_; }
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void set_low_level(base::TimeDelta low_level) {
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    low_level_threshold_ = low_level;
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void set_high_level(base::TimeDelta high_level) {
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    high_level_threshold_ = high_level;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  friend class base::RefCountedThreadSafe<BufferingConfig>;
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~BufferingConfig();
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta low_level_threshold_;
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta high_level_threshold_;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(BufferingConfig);
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass BufferingState
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : public base::RefCountedThreadSafe<BufferingState> {
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef base::Callback<void(base::TimeDelta)> HighLevelBufferCB;
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  enum State {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    kLowLevel,
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    kMediumLevel,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    kHighLevel,
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    kEosReached,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a new buffering state. The initial state is |kLowLevel|.
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |state_changed_cb| is used to notify about possible state changes.
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |high_level_buffer_cb| is used to adjust the high buffer threshold
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // when the underlying buffer is not large enough to accomodate
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the current high buffer level.
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BufferingState(const scoped_refptr<BufferingConfig>& config,
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 const base::Closure& state_changed_cb,
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 const HighLevelBufferCB& high_level_buffer_cb);
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns the buffering state.
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  State GetState() const { return state_; }
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Invoked when the buffering configuration has changed.
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Based on the new configuration, the buffering state might change.
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // However, |state_changed_cb_| is not triggered in that case.
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnConfigChanged();
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Sets the current rendering time for this stream.
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetMediaTime(base::TimeDelta media_time);
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Sets/gets the maximum rendering media time for this stream.
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The maximum rendering time is always lower than the buffered time.
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetMaxRenderingTime(base::TimeDelta max_rendering_time);
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta GetMaxRenderingTime() const;
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Sets the buffered time.
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetBufferedTime(base::TimeDelta buffered_time);
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Notifies the buffering state that all the frames for this stream have been
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // buffered, i.e. the end of stream has been reached.
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void NotifyEos();
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Notifies the buffering state the underlying buffer has reached
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // its maximum capacity.
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The maximum frame timestamp in the buffer is given by |buffered_time|.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: this timestamp can be different from the one provided through
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // SetBufferedTime since SetBufferedTime takes the timestamp of a playable
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // frame which is not necessarily the case here (e.g. missing key id).
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void NotifyMaxCapacity(base::TimeDelta buffered_time);
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Buffering state as a human readable string, for debugging.
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string ToString() const;
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  friend class base::RefCountedThreadSafe<BufferingState>;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~BufferingState();
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns the state solely based on the buffered time.
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  State GetBufferLevelState() const;
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Updates the state to |new_state|.
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void UpdateState(State new_state);
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<BufferingConfig> const config_;
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Callback invoked each time there is a change of state.
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Closure state_changed_cb_;
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Callback invoked to adjust the high buffer level.
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HighLevelBufferCB high_level_buffer_cb_;
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // State.
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  State state_;
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Playback media time.
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Equal to kNoTimestamp() when not known.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta media_time_;
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Maximum rendering media time.
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This corresponds to the timestamp of the last frame sent to the hardware
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // decoder/renderer.
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta max_rendering_time_;
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Buffered media time.
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Equal to kNoTimestamp() when not known.
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta buffered_time_;
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(BufferingState);
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace media
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace chromecast
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // CHROMECAST_MEDIA_CMA_BASE_BUFFERING_STATE_H_
139