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