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