1 // Copyright 2013 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 CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_ 6 #define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/message_loop/message_loop.h" 16 #include "base/time/time.h" 17 #include "media/base/decryptor.h" 18 #include "media/base/demuxer.h" 19 #include "media/base/media_keys.h" 20 #include "media/base/pipeline_status.h" 21 #include "media/base/ranges.h" 22 #include "media/base/text_track.h" 23 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" 24 25 namespace media { 26 class ChunkDemuxer; 27 class DecoderBuffer; 28 class DecryptingDemuxerStream; 29 class DemuxerStream; 30 class MediaLog; 31 struct DemuxerConfigs; 32 struct DemuxerData; 33 } 34 35 namespace content { 36 37 class RendererDemuxerAndroid; 38 39 class MediaSourceDelegate : public media::DemuxerHost { 40 public: 41 typedef base::Callback<void(blink::WebMediaSource*)> 42 MediaSourceOpenedCB; 43 typedef base::Callback<void(blink::WebMediaPlayer::NetworkState)> 44 UpdateNetworkStateCB; 45 typedef base::Callback<void(const base::TimeDelta&)> DurationChangeCB; 46 47 // Helper class used by scoped_ptr to destroy an instance of 48 // MediaSourceDelegate. 49 class Destroyer { 50 public: 51 inline void operator()(void* media_source_delegate) const { 52 static_cast<MediaSourceDelegate*>(media_source_delegate)->Destroy(); 53 } 54 }; 55 56 MediaSourceDelegate(RendererDemuxerAndroid* demuxer_client, 57 int demuxer_client_id, 58 const scoped_refptr<base::MessageLoopProxy>& media_loop, 59 media::MediaLog* media_log); 60 61 // Initialize the MediaSourceDelegate. |media_source| will be owned by 62 // this object after this call. 63 void InitializeMediaSource( 64 const MediaSourceOpenedCB& media_source_opened_cb, 65 const media::Demuxer::NeedKeyCB& need_key_cb, 66 const media::SetDecryptorReadyCB& set_decryptor_ready_cb, 67 const UpdateNetworkStateCB& update_network_state_cb, 68 const DurationChangeCB& duration_change_cb); 69 70 #if defined(GOOGLE_TV) 71 void InitializeMediaStream( 72 media::Demuxer* demuxer, 73 const UpdateNetworkStateCB& update_network_state_cb); 74 #endif 75 76 const blink::WebTimeRanges& Buffered(); 77 size_t DecodedFrameCount() const; 78 size_t DroppedFrameCount() const; 79 size_t AudioDecodedByteCount() const; 80 size_t VideoDecodedByteCount() const; 81 82 // In MSE case, calls ChunkDemuxer::CancelPendingSeek(). Also sets the 83 // expectation that a regular seek will be arriving and to trivially finish 84 // any browser seeks that may be requested prior to the regular seek. 85 void CancelPendingSeek(const base::TimeDelta& seek_time); 86 87 // In MSE case, calls ChunkDemuxer::StartWaitingForSeek(), first calling 88 // ChunkDemuxer::CancelPendingSeek() if a browser seek is in progress. 89 // Also sets the expectation that a regular seek will be arriving and to 90 // trivially finish any browser seeks that may be requested prior to the 91 // regular seek. 92 void StartWaitingForSeek(const base::TimeDelta& seek_time); 93 94 // Seeks the demuxer and later calls OnDemuxerSeekDone() after the seek has 95 // been completed. There must be no other seek of the demuxer currently in 96 // process when this method is called. 97 // If |is_browser_seek| is true, then this is a short-term hack browser 98 // seek. 99 // TODO(wolenetz): Instead of doing browser seek, browser player should replay 100 // cached data since last keyframe. See http://crbug.com/304234. 101 void Seek(const base::TimeDelta& seek_time, bool is_browser_seek); 102 103 void NotifyKeyAdded(const std::string& key_system); 104 105 // Called when DemuxerStreamPlayer needs to read data from ChunkDemuxer. 106 void OnReadFromDemuxer(media::DemuxerStream::Type type); 107 108 // Called when the player needs the new config data from ChunkDemuxer. 109 void OnMediaConfigRequest(); 110 111 // Called by the Destroyer to destroy an instance of this object. 112 void Destroy(); 113 114 private: 115 typedef base::Callback<void(scoped_ptr<media::DemuxerData> data)> 116 ReadFromDemuxerAckCB; 117 typedef base::Callback<void(scoped_ptr<media::DemuxerConfigs> configs)> 118 DemuxerReadyCB; 119 120 // This is private to enforce use of the Destroyer. 121 virtual ~MediaSourceDelegate(); 122 123 // Methods inherited from DemuxerHost. 124 virtual void SetTotalBytes(int64 total_bytes) OVERRIDE; 125 virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE; 126 virtual void AddBufferedTimeRange(base::TimeDelta start, 127 base::TimeDelta end) OVERRIDE; 128 virtual void SetDuration(base::TimeDelta duration) OVERRIDE; 129 virtual void OnDemuxerError(media::PipelineStatus status) OVERRIDE; 130 virtual void AddTextStream(media::DemuxerStream* text_stream, 131 const media::TextTrackConfig& config) OVERRIDE; 132 virtual void RemoveTextStream(media::DemuxerStream* text_stream) OVERRIDE; 133 134 // Notifies |demuxer_client_| and fires |duration_changed_cb_|. 135 void OnDurationChanged(const base::TimeDelta& duration); 136 137 // Callback for ChunkDemuxer initialization. 138 void OnDemuxerInitDone(media::PipelineStatus status); 139 140 // Initializes DecryptingDemuxerStreams if audio/video stream is encrypted. 141 void InitAudioDecryptingDemuxerStream(); 142 void InitVideoDecryptingDemuxerStream(); 143 144 // Callbacks for DecryptingDemuxerStream::Initialize(). 145 void OnAudioDecryptingDemuxerStreamInitDone(media::PipelineStatus status); 146 void OnVideoDecryptingDemuxerStreamInitDone(media::PipelineStatus status); 147 148 // Callback for ChunkDemuxer::Seek() and callback chain for resetting 149 // decrypted audio/video streams if present. 150 // 151 // Runs on the media thread. 152 void OnDemuxerSeekDone(media::PipelineStatus status); 153 void ResetAudioDecryptingDemuxerStream(); 154 void ResetVideoDecryptingDemuxerStream(); 155 void FinishResettingDecryptingDemuxerStreams(); 156 157 void OnDemuxerStopDone(); 158 void OnDemuxerOpened(); 159 void OnNeedKey(const std::string& type, 160 const std::vector<uint8>& init_data); 161 void NotifyDemuxerReady(); 162 bool CanNotifyDemuxerReady(); 163 164 void StopDemuxer(); 165 void InitializeDemuxer(); 166 void SeekInternal(const base::TimeDelta& seek_time); 167 // Reads an access unit from the demuxer stream |stream| and stores it in 168 // the |index|th access unit in |params|. 169 void ReadFromDemuxerStream(media::DemuxerStream::Type type, 170 scoped_ptr<media::DemuxerData> data, 171 size_t index); 172 void OnBufferReady(media::DemuxerStream::Type type, 173 scoped_ptr<media::DemuxerData> data, 174 size_t index, 175 media::DemuxerStream::Status status, 176 const scoped_refptr<media::DecoderBuffer>& buffer); 177 178 // Helper function for calculating duration. 179 int GetDurationMs(); 180 181 bool HasEncryptedStream(); 182 183 bool IsSeeking() const; 184 185 // Returns |seek_time| if it is still buffered or if there is no currently 186 // buffered range including or soon after |seek_time|. If |seek_time| is not 187 // buffered, but there is a later range buffered near to |seek_time|, returns 188 // next buffered range's start time instead. Only call this for browser seeks. 189 // |seeking_lock_| must be held by caller. 190 base::TimeDelta FindBufferedBrowserSeekTime_Locked( 191 const base::TimeDelta& seek_time) const; 192 193 // Message loop for main renderer thread and corresponding weak pointer. 194 const scoped_refptr<base::MessageLoopProxy> main_loop_; 195 base::WeakPtrFactory<MediaSourceDelegate> main_weak_factory_; 196 base::WeakPtr<MediaSourceDelegate> main_weak_this_; 197 198 // Message loop for media thread and corresponding weak pointer. 199 const scoped_refptr<base::MessageLoopProxy> media_loop_; 200 base::WeakPtrFactory<MediaSourceDelegate> media_weak_factory_; 201 202 RendererDemuxerAndroid* demuxer_client_; 203 int demuxer_client_id_; 204 205 scoped_refptr<media::MediaLog> media_log_; 206 UpdateNetworkStateCB update_network_state_cb_; 207 DurationChangeCB duration_change_cb_; 208 209 scoped_ptr<media::ChunkDemuxer> chunk_demuxer_; 210 media::Demuxer* demuxer_; 211 bool is_demuxer_ready_; 212 213 media::SetDecryptorReadyCB set_decryptor_ready_cb_; 214 215 scoped_ptr<media::DecryptingDemuxerStream> audio_decrypting_demuxer_stream_; 216 scoped_ptr<media::DecryptingDemuxerStream> video_decrypting_demuxer_stream_; 217 218 media::DemuxerStream* audio_stream_; 219 media::DemuxerStream* video_stream_; 220 221 media::PipelineStatistics statistics_; 222 media::Ranges<base::TimeDelta> buffered_time_ranges_; 223 // Keep a list of buffered time ranges. 224 blink::WebTimeRanges buffered_web_time_ranges_; 225 226 MediaSourceOpenedCB media_source_opened_cb_; 227 media::Demuxer::NeedKeyCB need_key_cb_; 228 229 // The currently selected key system. Empty string means that no key system 230 // has been selected. 231 blink::WebString current_key_system_; 232 233 // Temporary for EME v0.1. In the future the init data type should be passed 234 // through GenerateKeyRequest() directly from WebKit. 235 std::string init_data_type_; 236 237 // Lock used to serialize access for |seeking_|. 238 mutable base::Lock seeking_lock_; 239 bool seeking_; 240 241 // Track if we are currently performing a browser seek, and track whether or 242 // not a regular seek is expected soon. If a regular seek is expected soon, 243 // then any in-progress browser seek will be canceled pending the 244 // regular seek, if using |chunk_demuxer_|, and any requested browser seek 245 // will be trivially finished. Access is serialized by |seeking_lock_|. 246 bool doing_browser_seek_; 247 base::TimeDelta browser_seek_time_; 248 bool expecting_regular_seek_; 249 250 #if defined(GOOGLE_TV) 251 bool key_added_; 252 std::string key_system_; 253 #endif // defined(GOOGLE_TV) 254 255 size_t access_unit_size_; 256 257 DISALLOW_COPY_AND_ASSIGN(MediaSourceDelegate); 258 }; 259 260 } // namespace content 261 262 #endif // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_ 263