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.
5 #ifndef CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_
6 #define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_
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/time/time.h"
16 #include "media/base/decryptor.h"
17 #include "media/base/demuxer.h"
18 #include "media/base/media_keys.h"
19 #include "media/base/pipeline_status.h"
20 #include "media/base/ranges.h"
21 #include "media/base/text_track.h"
22 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
25 class SingleThreadTaskRunner
;
31 class DecryptingDemuxerStream
;
34 struct DemuxerConfigs
;
40 class RendererDemuxerAndroid
;
42 class MediaSourceDelegate
: public media::DemuxerHost
{
44 typedef base::Callback
<void(blink::WebMediaSource
*)>
46 typedef base::Callback
<void(blink::WebMediaPlayer::NetworkState
)>
48 typedef base::Callback
<void(const base::TimeDelta
&)> DurationChangeCB
;
50 // Helper class used by scoped_ptr to destroy an instance of
51 // MediaSourceDelegate.
54 inline void operator()(void* media_source_delegate
) const {
55 static_cast<MediaSourceDelegate
*>(media_source_delegate
)->Destroy();
60 RendererDemuxerAndroid
* demuxer_client
,
61 int demuxer_client_id
,
62 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
63 const scoped_refptr
<media::MediaLog
> media_log
);
65 // Initialize the MediaSourceDelegate. |media_source| will be owned by
66 // this object after this call.
67 void InitializeMediaSource(
68 const MediaSourceOpenedCB
& media_source_opened_cb
,
69 const media::Demuxer::NeedKeyCB
& need_key_cb
,
70 const media::SetDecryptorReadyCB
& set_decryptor_ready_cb
,
71 const UpdateNetworkStateCB
& update_network_state_cb
,
72 const DurationChangeCB
& duration_change_cb
);
74 blink::WebTimeRanges
Buffered() const;
75 size_t DecodedFrameCount() const;
76 size_t DroppedFrameCount() const;
77 size_t AudioDecodedByteCount() const;
78 size_t VideoDecodedByteCount() const;
80 // In MSE case, calls ChunkDemuxer::CancelPendingSeek(). Also sets the
81 // expectation that a regular seek will be arriving and to trivially finish
82 // any browser seeks that may be requested prior to the regular seek.
83 void CancelPendingSeek(const base::TimeDelta
& seek_time
);
85 // In MSE case, calls ChunkDemuxer::StartWaitingForSeek(), first calling
86 // ChunkDemuxer::CancelPendingSeek() if a browser seek is in progress.
87 // Also sets the expectation that a regular seek will be arriving and to
88 // trivially finish any browser seeks that may be requested prior to the
90 void StartWaitingForSeek(const base::TimeDelta
& seek_time
);
92 // Seeks the demuxer and later calls OnDemuxerSeekDone() after the seek has
93 // been completed. There must be no other seek of the demuxer currently in
94 // process when this method is called.
95 // If |is_browser_seek| is true, then this is a short-term hack browser
97 // TODO(wolenetz): Instead of doing browser seek, browser player should replay
98 // cached data since last keyframe. See http://crbug.com/304234.
99 void Seek(const base::TimeDelta
& seek_time
, bool is_browser_seek
);
101 // Called when DemuxerStreamPlayer needs to read data from ChunkDemuxer.
102 void OnReadFromDemuxer(media::DemuxerStream::Type type
);
104 // Called by the Destroyer to destroy an instance of this object.
107 // Called on the main thread to check whether the video stream is encrypted.
108 bool IsVideoEncrypted();
110 // Gets the ChunkDemuxer timeline offset.
111 base::Time
GetTimelineOffset() const;
114 // This is private to enforce use of the Destroyer.
115 virtual ~MediaSourceDelegate();
117 // Methods inherited from DemuxerHost.
118 virtual void AddBufferedTimeRange(base::TimeDelta start
,
119 base::TimeDelta end
) OVERRIDE
;
120 virtual void SetDuration(base::TimeDelta duration
) OVERRIDE
;
121 virtual void OnDemuxerError(media::PipelineStatus status
) OVERRIDE
;
122 virtual void AddTextStream(media::DemuxerStream
* text_stream
,
123 const media::TextTrackConfig
& config
) OVERRIDE
;
124 virtual void RemoveTextStream(media::DemuxerStream
* text_stream
) OVERRIDE
;
126 // Notifies |demuxer_client_| and fires |duration_changed_cb_|.
127 void OnDurationChanged(const base::TimeDelta
& duration
);
129 // Callback for ChunkDemuxer initialization.
130 void OnDemuxerInitDone(media::PipelineStatus status
);
132 // Initializes DecryptingDemuxerStreams if audio/video stream is encrypted.
133 void InitAudioDecryptingDemuxerStream();
134 void InitVideoDecryptingDemuxerStream();
136 // Callbacks for DecryptingDemuxerStream::Initialize().
137 void OnAudioDecryptingDemuxerStreamInitDone(media::PipelineStatus status
);
138 void OnVideoDecryptingDemuxerStreamInitDone(media::PipelineStatus status
);
140 // Callback for ChunkDemuxer::Seek() and callback chain for resetting
141 // decrypted audio/video streams if present.
143 // Runs on the media thread.
144 void OnDemuxerSeekDone(media::PipelineStatus status
);
145 void ResetAudioDecryptingDemuxerStream();
146 void ResetVideoDecryptingDemuxerStream();
147 void FinishResettingDecryptingDemuxerStreams();
149 // Callback for ChunkDemuxer::Stop() and helper for deleting |this| on the
151 void OnDemuxerStopDone();
154 void OnDemuxerOpened();
155 void OnNeedKey(const std::string
& type
,
156 const std::vector
<uint8
>& init_data
);
157 void NotifyDemuxerReady();
160 void InitializeDemuxer();
161 void SeekInternal(const base::TimeDelta
& seek_time
);
162 // Reads an access unit from the demuxer stream |stream| and stores it in
163 // the |index|th access unit in |params|.
164 void ReadFromDemuxerStream(media::DemuxerStream::Type type
,
165 scoped_ptr
<media::DemuxerData
> data
,
167 void OnBufferReady(media::DemuxerStream::Type type
,
168 scoped_ptr
<media::DemuxerData
> data
,
170 media::DemuxerStream::Status status
,
171 const scoped_refptr
<media::DecoderBuffer
>& buffer
);
173 // Helper function for calculating duration.
174 base::TimeDelta
GetDuration() const;
176 bool IsSeeking() const;
178 // Returns |seek_time| if it is still buffered or if there is no currently
179 // buffered range including or soon after |seek_time|. If |seek_time| is not
180 // buffered, but there is a later range buffered near to |seek_time|, returns
181 // next buffered range's start time instead. Only call this for browser seeks.
182 // |seeking_lock_| must be held by caller.
183 base::TimeDelta
FindBufferedBrowserSeekTime_Locked(
184 const base::TimeDelta
& seek_time
) const;
186 // Get the demuxer configs for a particular stream identified by |is_audio|.
187 // Returns true on success, of false otherwise.
188 bool GetDemuxerConfigFromStream(media::DemuxerConfigs
* configs
,
191 RendererDemuxerAndroid
* demuxer_client_
;
192 int demuxer_client_id_
;
194 scoped_refptr
<media::MediaLog
> media_log_
;
195 UpdateNetworkStateCB update_network_state_cb_
;
196 DurationChangeCB duration_change_cb_
;
198 scoped_ptr
<media::ChunkDemuxer
> chunk_demuxer_
;
199 bool is_demuxer_ready_
;
201 media::SetDecryptorReadyCB set_decryptor_ready_cb_
;
203 scoped_ptr
<media::DecryptingDemuxerStream
> audio_decrypting_demuxer_stream_
;
204 scoped_ptr
<media::DecryptingDemuxerStream
> video_decrypting_demuxer_stream_
;
206 media::DemuxerStream
* audio_stream_
;
207 media::DemuxerStream
* video_stream_
;
209 media::PipelineStatistics statistics_
;
210 media::Ranges
<base::TimeDelta
> buffered_time_ranges_
;
212 MediaSourceOpenedCB media_source_opened_cb_
;
213 media::Demuxer::NeedKeyCB need_key_cb_
;
215 // Temporary for EME v0.1. In the future the init data type should be passed
216 // through GenerateKeyRequest() directly from WebKit.
217 std::string init_data_type_
;
219 // Lock used to serialize access for |seeking_|.
220 mutable base::Lock seeking_lock_
;
223 // Lock used to serialize access for |is_video_encrypted_|.
224 mutable base::Lock is_video_encrypted_lock_
;
225 bool is_video_encrypted_
;
227 // Track if we are currently performing a browser seek, and track whether or
228 // not a regular seek is expected soon. If a regular seek is expected soon,
229 // then any in-progress browser seek will be canceled pending the
230 // regular seek, if using |chunk_demuxer_|, and any requested browser seek
231 // will be trivially finished. Access is serialized by |seeking_lock_|.
232 bool doing_browser_seek_
;
233 base::TimeDelta browser_seek_time_
;
234 bool expecting_regular_seek_
;
236 size_t access_unit_size_
;
238 // Task runner for main renderer and media threads.
239 const scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner_
;
240 const scoped_refptr
<base::SingleThreadTaskRunner
> media_task_runner_
;
242 // NOTE: Weak pointers must be invalidated before all other member variables.
243 base::WeakPtrFactory
<MediaSourceDelegate
> main_weak_factory_
;
244 base::WeakPtrFactory
<MediaSourceDelegate
> media_weak_factory_
;
245 base::WeakPtr
<MediaSourceDelegate
> main_weak_this_
;
247 DISALLOW_COPY_AND_ASSIGN(MediaSourceDelegate
);
250 } // namespace content
252 #endif // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_