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/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/web/WebMediaPlayer.h"
28 class DecryptingDemuxerStream;
31 struct DemuxerConfigs;
37 class RendererDemuxerAndroid;
39 class MediaSourceDelegate : public media::DemuxerHost {
41 typedef base::Callback<void(WebKit::WebMediaSource*)>
43 typedef base::Callback<void(WebKit::WebMediaPlayer::NetworkState)>
45 typedef base::Callback<void(const base::TimeDelta&)> DurationChangeCB;
47 // Helper class used by scoped_ptr to destroy an instance of
48 // MediaSourceDelegate.
51 inline void operator()(void* media_source_delegate) const {
52 static_cast<MediaSourceDelegate*>(media_source_delegate)->Destroy();
56 MediaSourceDelegate(RendererDemuxerAndroid* demuxer_client,
57 int demuxer_client_id,
58 const scoped_refptr<base::MessageLoopProxy>& media_loop,
59 media::MediaLog* media_log);
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);
70 #if defined(GOOGLE_TV)
71 void InitializeMediaStream(
72 media::Demuxer* demuxer,
73 const UpdateNetworkStateCB& update_network_state_cb);
76 const WebKit::WebTimeRanges& Buffered();
77 size_t DecodedFrameCount() const;
78 size_t DroppedFrameCount() const;
79 size_t AudioDecodedByteCount() const;
80 size_t VideoDecodedByteCount() const;
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);
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
92 void StartWaitingForSeek(const base::TimeDelta& seek_time);
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
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);
103 void NotifyKeyAdded(const std::string& key_system);
105 // Called when DemuxerStreamPlayer needs to read data from ChunkDemuxer.
106 void OnReadFromDemuxer(media::DemuxerStream::Type type);
108 // Called when the player needs the new config data from ChunkDemuxer.
109 void OnMediaConfigRequest();
111 // Called by the Destroyer to destroy an instance of this object.
115 typedef base::Callback<void(scoped_ptr<media::DemuxerData> data)>
116 ReadFromDemuxerAckCB;
117 typedef base::Callback<void(scoped_ptr<media::DemuxerConfigs> configs)>
120 // This is private to enforce use of the Destroyer.
121 virtual ~MediaSourceDelegate();
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;
131 // Notifies |demuxer_client_| and fires |duration_changed_cb_|.
132 void OnDurationChanged(const base::TimeDelta& duration);
134 // Callback for ChunkDemuxer initialization.
135 void OnDemuxerInitDone(media::PipelineStatus status);
137 // Initializes DecryptingDemuxerStreams if audio/video stream is encrypted.
138 void InitAudioDecryptingDemuxerStream();
139 void InitVideoDecryptingDemuxerStream();
141 // Callbacks for DecryptingDemuxerStream::Initialize().
142 void OnAudioDecryptingDemuxerStreamInitDone(media::PipelineStatus status);
143 void OnVideoDecryptingDemuxerStreamInitDone(media::PipelineStatus status);
145 // Callback for ChunkDemuxer::Seek() and callback chain for resetting
146 // decrypted audio/video streams if present.
148 // Runs on the media thread.
149 void OnDemuxerSeekDone(media::PipelineStatus status);
150 void ResetAudioDecryptingDemuxerStream();
151 void ResetVideoDecryptingDemuxerStream();
152 void FinishResettingDecryptingDemuxerStreams();
154 void OnDemuxerStopDone();
155 void OnDemuxerOpened();
156 void OnNeedKey(const std::string& type,
157 const std::vector<uint8>& init_data);
158 void NotifyDemuxerReady();
159 bool CanNotifyDemuxerReady();
162 void InitializeDemuxer();
163 void SeekInternal(const base::TimeDelta& seek_time);
164 // Reads an access unit from the demuxer stream |stream| and stores it in
165 // the |index|th access unit in |params|.
166 void ReadFromDemuxerStream(media::DemuxerStream::Type type,
167 scoped_ptr<media::DemuxerData> data,
169 void OnBufferReady(media::DemuxerStream::Type type,
170 scoped_ptr<media::DemuxerData> data,
172 media::DemuxerStream::Status status,
173 const scoped_refptr<media::DecoderBuffer>& buffer);
175 // Helper function for calculating duration.
178 bool HasEncryptedStream();
180 bool IsSeeking() const;
182 // Returns |seek_time| if it is still buffered or if there is no currently
183 // buffered range including or soon after |seek_time|. If |seek_time| is not
184 // buffered, but there is a later range buffered near to |seek_time|, returns
185 // next buffered range's start time instead. Only call this for browser seeks.
186 // |seeking_lock_| must be held by caller.
187 base::TimeDelta FindBufferedBrowserSeekTime_Locked(
188 const base::TimeDelta& seek_time) const;
190 // Message loop for main renderer thread and corresponding weak pointer.
191 const scoped_refptr<base::MessageLoopProxy> main_loop_;
192 base::WeakPtrFactory<MediaSourceDelegate> main_weak_factory_;
193 base::WeakPtr<MediaSourceDelegate> main_weak_this_;
195 // Message loop for media thread and corresponding weak pointer.
196 const scoped_refptr<base::MessageLoopProxy> media_loop_;
197 base::WeakPtrFactory<MediaSourceDelegate> media_weak_factory_;
199 RendererDemuxerAndroid* demuxer_client_;
200 int demuxer_client_id_;
202 scoped_refptr<media::MediaLog> media_log_;
203 UpdateNetworkStateCB update_network_state_cb_;
204 DurationChangeCB duration_change_cb_;
206 scoped_ptr<media::ChunkDemuxer> chunk_demuxer_;
207 media::Demuxer* demuxer_;
208 bool is_demuxer_ready_;
210 media::SetDecryptorReadyCB set_decryptor_ready_cb_;
212 scoped_ptr<media::DecryptingDemuxerStream> audio_decrypting_demuxer_stream_;
213 scoped_ptr<media::DecryptingDemuxerStream> video_decrypting_demuxer_stream_;
215 media::DemuxerStream* audio_stream_;
216 media::DemuxerStream* video_stream_;
218 media::PipelineStatistics statistics_;
219 media::Ranges<base::TimeDelta> buffered_time_ranges_;
220 // Keep a list of buffered time ranges.
221 WebKit::WebTimeRanges buffered_web_time_ranges_;
223 MediaSourceOpenedCB media_source_opened_cb_;
224 media::Demuxer::NeedKeyCB need_key_cb_;
226 // The currently selected key system. Empty string means that no key system
227 // has been selected.
228 WebKit::WebString current_key_system_;
230 // Temporary for EME v0.1. In the future the init data type should be passed
231 // through GenerateKeyRequest() directly from WebKit.
232 std::string init_data_type_;
234 // Lock used to serialize access for |seeking_|.
235 mutable base::Lock seeking_lock_;
238 // Track if we are currently performing a browser seek, and track whether or
239 // not a regular seek is expected soon. If a regular seek is expected soon,
240 // then any in-progress browser seek will be canceled pending the
241 // regular seek, if using |chunk_demuxer_|, and any requested browser seek
242 // will be trivially finished. Access is serialized by |seeking_lock_|.
243 bool doing_browser_seek_;
244 base::TimeDelta browser_seek_time_;
245 bool expecting_regular_seek_;
247 #if defined(GOOGLE_TV)
249 std::string key_system_;
250 #endif // defined(GOOGLE_TV)
252 size_t access_unit_size_;
254 DISALLOW_COPY_AND_ASSIGN(MediaSourceDelegate);
257 } // namespace content
259 #endif // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_SOURCE_DELEGATE_H_