| OLD | NEW |
| (Empty) |
| 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 <stddef.h> | |
| 9 #include <stdint.h> | |
| 10 | |
| 11 #include <memory> | |
| 12 #include <string> | |
| 13 #include <vector> | |
| 14 | |
| 15 #include "base/callback.h" | |
| 16 #include "base/macros.h" | |
| 17 #include "base/memory/ref_counted.h" | |
| 18 #include "base/memory/weak_ptr.h" | |
| 19 #include "base/time/time.h" | |
| 20 #include "media/base/cdm_context.h" | |
| 21 #include "media/base/demuxer.h" | |
| 22 #include "media/base/media_keys.h" | |
| 23 #include "media/base/pipeline_status.h" | |
| 24 #include "media/base/ranges.h" | |
| 25 #include "media/base/text_track.h" | |
| 26 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" | |
| 27 | |
| 28 namespace base { | |
| 29 class SingleThreadTaskRunner; | |
| 30 } | |
| 31 | |
| 32 namespace media { | |
| 33 class ChunkDemuxer; | |
| 34 class DecoderBuffer; | |
| 35 class DecryptingDemuxerStream; | |
| 36 class DemuxerStream; | |
| 37 class MediaLog; | |
| 38 struct DemuxerConfigs; | |
| 39 struct DemuxerData; | |
| 40 } | |
| 41 | |
| 42 namespace content { | |
| 43 | |
| 44 class RendererDemuxerAndroid; | |
| 45 | |
| 46 class MediaSourceDelegate : public media::DemuxerHost { | |
| 47 public: | |
| 48 typedef base::Callback<void(blink::WebMediaSource*)> | |
| 49 MediaSourceOpenedCB; | |
| 50 typedef base::Callback<void(blink::WebMediaPlayer::NetworkState)> | |
| 51 UpdateNetworkStateCB; | |
| 52 typedef base::Callback<void(const base::TimeDelta&)> DurationChangeCB; | |
| 53 | |
| 54 // Callback to notify that a CDM is ready. CdmAttachedCB is called when the | |
| 55 // CDM has been completely attached to the media pipeline. | |
| 56 typedef base::Callback<void(media::CdmContext*, const media::CdmAttachedCB&)> | |
| 57 CdmReadyCB; | |
| 58 | |
| 59 // Callback to set a CdmReadyCB, which will be called when a CDM is ready. | |
| 60 typedef base::Callback<void(const CdmReadyCB&)> SetCdmReadyCB; | |
| 61 | |
| 62 MediaSourceDelegate( | |
| 63 RendererDemuxerAndroid* demuxer_client, | |
| 64 int demuxer_client_id, | |
| 65 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
| 66 const scoped_refptr<media::MediaLog> media_log); | |
| 67 ~MediaSourceDelegate() override; | |
| 68 | |
| 69 // Initialize the MediaSourceDelegate. |media_source| will be owned by | |
| 70 // this object after this call. | |
| 71 void InitializeMediaSource( | |
| 72 const MediaSourceOpenedCB& media_source_opened_cb, | |
| 73 const media::Demuxer::EncryptedMediaInitDataCB& | |
| 74 encrypted_media_init_data_cb, | |
| 75 const SetCdmReadyCB& set_cdm_ready_cb, | |
| 76 const UpdateNetworkStateCB& update_network_state_cb, | |
| 77 const DurationChangeCB& duration_change_cb, | |
| 78 const base::Closure& waiting_for_decryption_key_cb); | |
| 79 | |
| 80 blink::WebTimeRanges Buffered() const; | |
| 81 size_t DecodedFrameCount() const; | |
| 82 size_t DroppedFrameCount() const; | |
| 83 size_t AudioDecodedByteCount() const; | |
| 84 size_t VideoDecodedByteCount() const; | |
| 85 | |
| 86 // In MSE case, calls ChunkDemuxer::CancelPendingSeek(). Also sets the | |
| 87 // expectation that a regular seek will be arriving and to trivially finish | |
| 88 // any browser seeks that may be requested prior to the regular seek. | |
| 89 void CancelPendingSeek(const base::TimeDelta& seek_time); | |
| 90 | |
| 91 // In MSE case, calls ChunkDemuxer::StartWaitingForSeek(), first calling | |
| 92 // ChunkDemuxer::CancelPendingSeek() if a browser seek is in progress. | |
| 93 // Also sets the expectation that a regular seek will be arriving and to | |
| 94 // trivially finish any browser seeks that may be requested prior to the | |
| 95 // regular seek. | |
| 96 void StartWaitingForSeek(const base::TimeDelta& seek_time); | |
| 97 | |
| 98 // Seeks the demuxer and later calls OnDemuxerSeekDone() after the seek has | |
| 99 // been completed. There must be no other seek of the demuxer currently in | |
| 100 // process when this method is called. | |
| 101 // If |is_browser_seek| is true, then this is a short-term hack browser | |
| 102 // seek. | |
| 103 // TODO(wolenetz): Instead of doing browser seek, browser player should replay | |
| 104 // cached data since last keyframe. See http://crbug.com/304234. | |
| 105 void Seek(const base::TimeDelta& seek_time, bool is_browser_seek); | |
| 106 | |
| 107 // Called when DemuxerStreamPlayer needs to read data from ChunkDemuxer. | |
| 108 void OnReadFromDemuxer(media::DemuxerStream::Type type); | |
| 109 | |
| 110 // Must be called explicitly before |this| can be destroyed. | |
| 111 void Stop(const base::Closure& stop_cb); | |
| 112 | |
| 113 // Called on the main thread to check whether the video stream is encrypted. | |
| 114 bool IsVideoEncrypted(); | |
| 115 | |
| 116 // Gets the ChunkDemuxer timeline offset. | |
| 117 base::Time GetTimelineOffset() const; | |
| 118 | |
| 119 private: | |
| 120 // Methods inherited from DemuxerHost. | |
| 121 void OnBufferedTimeRangesChanged( | |
| 122 const media::Ranges<base::TimeDelta>& ranges) override; | |
| 123 void SetDuration(base::TimeDelta duration) override; | |
| 124 void OnDemuxerError(media::PipelineStatus status) override; | |
| 125 void AddTextStream(media::DemuxerStream* text_stream, | |
| 126 const media::TextTrackConfig& config) override; | |
| 127 void RemoveTextStream(media::DemuxerStream* text_stream) override; | |
| 128 | |
| 129 // Notifies |demuxer_client_| and fires |duration_changed_cb_|. | |
| 130 void OnDurationChanged(const base::TimeDelta& duration); | |
| 131 | |
| 132 // Callback for ChunkDemuxer initialization. | |
| 133 void OnDemuxerInitDone(media::PipelineStatus status); | |
| 134 | |
| 135 bool HasEncryptedStream(); | |
| 136 | |
| 137 // Callback to set CDM and fires |cdm_attached_cb| with the result. | |
| 138 void SetCdm(media::CdmContext* cdm_context, | |
| 139 const media::CdmAttachedCB& cdm_attached_cb); | |
| 140 | |
| 141 // Initializes DecryptingDemuxerStreams if audio/video stream is encrypted. | |
| 142 void InitAudioDecryptingDemuxerStream(); | |
| 143 void InitVideoDecryptingDemuxerStream(); | |
| 144 | |
| 145 // Callbacks for DecryptingDemuxerStream::Initialize(). | |
| 146 void OnAudioDecryptingDemuxerStreamInitDone(media::PipelineStatus status); | |
| 147 void OnVideoDecryptingDemuxerStreamInitDone(media::PipelineStatus status); | |
| 148 | |
| 149 // Callback for ChunkDemuxer::Seek() and callback chain for resetting | |
| 150 // decrypted audio/video streams if present. | |
| 151 // | |
| 152 // Runs on the media thread. | |
| 153 void OnDemuxerSeekDone(media::PipelineStatus status); | |
| 154 void ResetAudioDecryptingDemuxerStream(); | |
| 155 void ResetVideoDecryptingDemuxerStream(); | |
| 156 void FinishResettingDecryptingDemuxerStreams(); | |
| 157 | |
| 158 void OnDemuxerOpened(); | |
| 159 void OnEncryptedMediaInitData(media::EmeInitDataType init_data_type, | |
| 160 const std::vector<uint8_t>& init_data); | |
| 161 void NotifyDemuxerReady(bool is_cdm_attached); | |
| 162 | |
| 163 // Stops and clears objects on the media thread. | |
| 164 void StopDemuxer(const base::Closure& stop_cb); | |
| 165 | |
| 166 void InitializeDemuxer(); | |
| 167 void SeekInternal(const base::TimeDelta& seek_time); | |
| 168 // Reads an access unit from the demuxer stream |stream| and stores it in | |
| 169 // the |index|th access unit in |params|. | |
| 170 void ReadFromDemuxerStream(media::DemuxerStream::Type type, | |
| 171 std::unique_ptr<media::DemuxerData> data, | |
| 172 size_t index); | |
| 173 void OnBufferReady(media::DemuxerStream::Type type, | |
| 174 std::unique_ptr<media::DemuxerData> data, | |
| 175 size_t index, | |
| 176 media::DemuxerStream::Status status, | |
| 177 const scoped_refptr<media::DecoderBuffer>& buffer); | |
| 178 | |
| 179 // Helper function for calculating duration. | |
| 180 base::TimeDelta GetDuration() const; | |
| 181 | |
| 182 bool IsSeeking() const; | |
| 183 | |
| 184 // Returns |seek_time| if it is still buffered or if there is no currently | |
| 185 // buffered range including or soon after |seek_time|. If |seek_time| is not | |
| 186 // buffered, but there is a later range buffered near to |seek_time|, returns | |
| 187 // next buffered range's start time instead. Only call this for browser seeks. | |
| 188 // |seeking_lock_| must be held by caller. | |
| 189 base::TimeDelta FindBufferedBrowserSeekTime_Locked( | |
| 190 const base::TimeDelta& seek_time) const; | |
| 191 | |
| 192 // Get the demuxer configs for a particular stream identified by |is_audio|. | |
| 193 // Returns true on success, of false otherwise. | |
| 194 bool GetDemuxerConfigFromStream(media::DemuxerConfigs* configs, | |
| 195 bool is_audio); | |
| 196 | |
| 197 RendererDemuxerAndroid* demuxer_client_; | |
| 198 int demuxer_client_id_; | |
| 199 | |
| 200 scoped_refptr<media::MediaLog> media_log_; | |
| 201 UpdateNetworkStateCB update_network_state_cb_; | |
| 202 DurationChangeCB duration_change_cb_; | |
| 203 | |
| 204 std::unique_ptr<media::ChunkDemuxer> chunk_demuxer_; | |
| 205 bool is_demuxer_ready_; | |
| 206 | |
| 207 SetCdmReadyCB set_cdm_ready_cb_; | |
| 208 media::CdmContext* cdm_context_; | |
| 209 media::CdmAttachedCB pending_cdm_attached_cb_; | |
| 210 | |
| 211 std::unique_ptr<media::DecryptingDemuxerStream> | |
| 212 audio_decrypting_demuxer_stream_; | |
| 213 std::unique_ptr<media::DecryptingDemuxerStream> | |
| 214 video_decrypting_demuxer_stream_; | |
| 215 | |
| 216 media::DemuxerStream* audio_stream_; | |
| 217 media::DemuxerStream* video_stream_; | |
| 218 | |
| 219 media::PipelineStatistics statistics_; | |
| 220 media::Ranges<base::TimeDelta> buffered_time_ranges_; | |
| 221 | |
| 222 MediaSourceOpenedCB media_source_opened_cb_; | |
| 223 media::Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_; | |
| 224 base::Closure waiting_for_decryption_key_cb_; | |
| 225 | |
| 226 // Lock used to serialize access for |seeking_|. | |
| 227 mutable base::Lock seeking_lock_; | |
| 228 bool seeking_; | |
| 229 | |
| 230 // Lock used to serialize access for |is_video_encrypted_|. | |
| 231 mutable base::Lock is_video_encrypted_lock_; | |
| 232 bool is_video_encrypted_; | |
| 233 | |
| 234 // Track if we are currently performing a browser seek, and track whether or | |
| 235 // not a regular seek is expected soon. If a regular seek is expected soon, | |
| 236 // then any in-progress browser seek will be canceled pending the | |
| 237 // regular seek, if using |chunk_demuxer_|, and any requested browser seek | |
| 238 // will be trivially finished. Access is serialized by |seeking_lock_|. | |
| 239 bool doing_browser_seek_; | |
| 240 base::TimeDelta browser_seek_time_; | |
| 241 bool expecting_regular_seek_; | |
| 242 | |
| 243 size_t access_unit_size_; | |
| 244 | |
| 245 // Task runner for main renderer and media threads. | |
| 246 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | |
| 247 const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; | |
| 248 | |
| 249 // NOTE: Weak pointers must be invalidated before all other member variables. | |
| 250 base::WeakPtr<MediaSourceDelegate> main_weak_this_; | |
| 251 base::WeakPtrFactory<MediaSourceDelegate> main_weak_factory_; | |
| 252 base::WeakPtrFactory<MediaSourceDelegate> media_weak_factory_; | |
| 253 | |
| 254 DISALLOW_COPY_AND_ASSIGN(MediaSourceDelegate); | |
| 255 }; | |
| 256 | |
| 257 } // namespace content | |
| 258 | |
| 259 #endif // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_ | |
| OLD | NEW |