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 |