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_CONTROLLER_H 6 #define CHROMECAST_MEDIA_CMA_BASE_BUFFERING_CONTROLLER_H 7 8 #include <list> 9 10 #include "base/callback.h" 11 #include "base/macros.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/threading/thread_checker.h" 15 #include "base/time/time.h" 16 17 namespace chromecast { 18 namespace media { 19 class BufferingConfig; 20 class BufferingState; 21 22 class BufferingController { 23 public: 24 typedef base::Callback<void(bool)> BufferingNotificationCB; 25 26 // Creates a buffering controller where the conditions to trigger rebuffering 27 // are given by |config|. The whole point of the buffering controller is to 28 // derive a single buffering state from the buffering state of various 29 // streams. 30 // |buffering_notification_cb| is a callback invoked to inform about possible 31 // changes of the buffering state. 32 BufferingController( 33 const scoped_refptr<BufferingConfig>& config, 34 const BufferingNotificationCB& buffering_notification_cb); 35 ~BufferingController(); 36 37 // Creates a buffering state for one stream. This state is added to the list 38 // of streams monitored by the buffering controller. 39 scoped_refptr<BufferingState> AddStream(); 40 41 // Sets the playback time. 42 void SetMediaTime(base::TimeDelta time); 43 44 // Returns the maximum media time available for rendering. 45 // Return kNoTimestamp() if unknown. 46 base::TimeDelta GetMaxRenderingTime() const; 47 48 // Returns whether there is an active buffering phase. 49 bool IsBuffering() const { return is_buffering_; } 50 51 // Resets the buffering controller. This includes removing all the streams 52 // that were previously added. 53 void Reset(); 54 55 private: 56 // Invoked each time the buffering state of one of the streams has changed. 57 // If |force_notification| is set, |buffering_notification_cb_| is invoked 58 // regardless whether the buffering state has changed or not. 59 // If |buffering_timeout| is set, then the condition to leave the buffering 60 // state is relaxed (we don't want to wait more). 61 void OnBufferingStateChanged(bool force_notification, 62 bool buffering_timeout); 63 64 // Updates the high buffer level threshold to |high_level_threshold| 65 // if needed. 66 // This condition is triggered when one of the stream reached its maximum 67 // capacity. In that case, to avoid possible race condition (the buffering 68 // controller waits for more data to come but the buffer is to small to 69 // accomodate additional data), the thresholds in |config_| are adjusted 70 // accordingly. 71 void UpdateHighLevelThreshold(base::TimeDelta high_level_threshold); 72 73 // Determines the overall buffer level based on the buffer level of each 74 // stream. 75 bool IsHighBufferLevel(); 76 bool IsLowBufferLevel(); 77 78 // Logs the state of the buffering controller. 79 void DumpState() const; 80 81 base::ThreadChecker thread_checker_; 82 83 // Settings used to determine when to start/stop buffering. 84 scoped_refptr<BufferingConfig> config_; 85 86 // Callback invoked each time there is a change of the buffering state. 87 BufferingNotificationCB buffering_notification_cb_; 88 89 // State of the buffering controller. 90 bool is_buffering_; 91 92 // Start time of a re-buffering phase. 93 base::Time begin_buffering_time_; 94 95 // Buffering level for each individual stream. 96 typedef std::list<scoped_refptr<BufferingState> > StreamList; 97 StreamList stream_list_; 98 99 base::WeakPtrFactory<BufferingController> weak_factory_; 100 base::WeakPtr<BufferingController> weak_this_; 101 102 DISALLOW_COPY_AND_ASSIGN(BufferingController); 103 }; 104 105 } // namespace media 106 } // namespace chromecast 107 108 #endif // CHROMECAST_MEDIA_CMA_BASE_BUFFERING_CONTROLLER_H 109