Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / base / android / media_source_player.h
1 // Copyright (c) 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 MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_
6 #define MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_
7
8 #include <jni.h>
9 #include <map>
10 #include <string>
11 #include <vector>
12
13 #include "base/android/scoped_java_ref.h"
14 #include "base/callback.h"
15 #include "base/cancelable_callback.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/threading/thread.h"
19 #include "base/time/default_tick_clock.h"
20 #include "base/time/time.h"
21 #include "media/base/android/demuxer_android.h"
22 #include "media/base/android/media_codec_bridge.h"
23 #include "media/base/android/media_decoder_job.h"
24 #include "media/base/android/media_drm_bridge.h"
25 #include "media/base/android/media_player_android.h"
26 #include "media/base/clock.h"
27 #include "media/base/media_export.h"
28
29 namespace media {
30
31 class AudioDecoderJob;
32 class VideoDecoderJob;
33
34 // This class handles media source extensions on Android. It uses Android
35 // MediaCodec to decode audio and video streams in two separate threads.
36 class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid,
37                                        public DemuxerAndroidClient {
38  public:
39   // Constructs a player with the given ID and demuxer. |manager| must outlive
40   // the lifetime of this object.
41   MediaSourcePlayer(int player_id,
42                     MediaPlayerManager* manager,
43                     const RequestMediaResourcesCB& request_media_resources_cb,
44                     const ReleaseMediaResourcesCB& release_media_resources_cb,
45                     scoped_ptr<DemuxerAndroid> demuxer);
46   virtual ~MediaSourcePlayer();
47
48   // MediaPlayerAndroid implementation.
49   virtual void SetVideoSurface(gfx::ScopedJavaSurface surface) OVERRIDE;
50   virtual void Start() OVERRIDE;
51   virtual void Pause(bool is_media_related_action ALLOW_UNUSED) OVERRIDE;
52   virtual void SeekTo(base::TimeDelta timestamp) OVERRIDE;
53   virtual void Release() OVERRIDE;
54   virtual void SetVolume(double volume) OVERRIDE;
55   virtual int GetVideoWidth() OVERRIDE;
56   virtual int GetVideoHeight() OVERRIDE;
57   virtual base::TimeDelta GetCurrentTime() OVERRIDE;
58   virtual base::TimeDelta GetDuration() OVERRIDE;
59   virtual bool IsPlaying() OVERRIDE;
60   virtual bool CanPause() OVERRIDE;
61   virtual bool CanSeekForward() OVERRIDE;
62   virtual bool CanSeekBackward() OVERRIDE;
63   virtual bool IsPlayerReady() OVERRIDE;
64   virtual void SetDrmBridge(MediaDrmBridge* drm_bridge) OVERRIDE;
65   virtual void OnKeyAdded() OVERRIDE;
66   virtual bool IsSurfaceInUse() const OVERRIDE;
67
68   // DemuxerAndroidClient implementation.
69   virtual void OnDemuxerConfigsAvailable(const DemuxerConfigs& params) OVERRIDE;
70   virtual void OnDemuxerDataAvailable(const DemuxerData& params) OVERRIDE;
71   virtual void OnDemuxerSeekDone(
72       base::TimeDelta actual_browser_seek_time) OVERRIDE;
73   virtual void OnDemuxerDurationChanged(base::TimeDelta duration) OVERRIDE;
74
75  private:
76   friend class MediaSourcePlayerTest;
77
78   // Update the current timestamp.
79   void UpdateTimestamps(base::TimeDelta current_presentation_timestamp,
80                         base::TimeDelta max_presentation_timestamp);
81
82   // Helper function for starting media playback.
83   void StartInternal();
84
85   // Playback is completed for one channel.
86   void PlaybackCompleted(bool is_audio);
87
88   // Called when the decoder finishes its task.
89   void MediaDecoderCallback(
90         bool is_audio, MediaCodecStatus status,
91         base::TimeDelta current_presentation_timestamp,
92         base::TimeDelta max_presentation_timestamp);
93
94   // Gets MediaCrypto object from |drm_bridge_|.
95   base::android::ScopedJavaLocalRef<jobject> GetMediaCrypto();
96
97   // Callback to notify that MediaCrypto is ready in |drm_bridge_|.
98   void OnMediaCryptoReady();
99
100   // Handle pending events if all the decoder jobs are not currently decoding.
101   void ProcessPendingEvents();
102
103   // Helper method to clear any pending |SURFACE_CHANGE_EVENT_PENDING|
104   // and reset |video_decoder_job_| to null.
105   void ResetVideoDecoderJob();
106   void ResetAudioDecoderJob();
107
108   // Helper methods to configure the decoder jobs.
109   void ConfigureVideoDecoderJob();
110   void ConfigureAudioDecoderJob();
111
112   // Flush the decoders and clean up all the data needs to be decoded.
113   void ClearDecodingData();
114
115   // Called to decode more data.
116   void DecodeMoreAudio();
117   void DecodeMoreVideo();
118
119   // Functions check whether audio/video is present.
120   bool HasVideo();
121   bool HasAudio();
122
123   // Functions that check whether audio/video stream has reached end of output
124   // or are not present in player configuration.
125   bool AudioFinished();
126   bool VideoFinished();
127
128   // Determine seekability based on duration.
129   bool Seekable();
130
131   // Called when the |decoder_starvation_callback_| times out.
132   void OnDecoderStarved();
133
134   // Starts the |decoder_starvation_callback_| task with the timeout value.
135   // |current_presentation_timestamp| - The presentation timestamp used for
136   // starvation timeout computations. It represents the current timestamp of
137   // rendered data.
138   // |max_presentation_timestamp| - The presentation timestamp if all the
139   // decoded data are rendered.
140   void StartStarvationCallback(
141       base::TimeDelta current_presentation_timestamp,
142       base::TimeDelta max_presentation_timestamp);
143
144   // Schedules a seek event in |pending_events_| and calls StopDecode() on all
145   // the MediaDecoderJobs. Sets clock to |seek_time|, and resets
146   // |pending_seek_|. There must not already be a seek event in
147   // |pending_events_|.
148   void ScheduleSeekEventAndStopDecoding(base::TimeDelta seek_time);
149
150   // Schedules a browser seek event. We must not currently be processing any
151   // seek. Note that there is possibility that browser seek of renderer demuxer
152   // may unexpectedly stall due to lack of buffered data at or after the browser
153   // seek time.
154   // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
155   // since last keyframe. See http://crbug.com/304234.
156   void BrowserSeekToCurrentTime();
157
158   // Helper function to set the volume.
159   void SetVolumeInternal();
160
161   // Helper function to determine whether a protected surface is needed for
162   // video playback.
163   bool IsProtectedSurfaceRequired();
164
165   // Called when a MediaDecoderJob finishes prefetching data. Once all
166   // MediaDecoderJobs have prefetched data, then this method updates
167   // |start_time_ticks_| and |start_presentation_timestamp_| so that video can
168   // resync with audio and starts decoding.
169   void OnPrefetchDone();
170
171   // Test-only method to setup hook for the completion of the next decode cycle.
172   // This callback state is cleared when it is next run.
173   // Prevent usage creep by only calling this from the
174   // ReleaseWithOnPrefetchDoneAlreadyPosted MediaSourcePlayerTest.
175   void set_decode_callback_for_testing(const base::Closure& test_decode_cb) {
176     decode_callback_for_testing_ = test_decode_cb;
177   }
178
179   // TODO(qinmin/wolenetz): Reorder these based on their priority from
180   // ProcessPendingEvents(). Release() and other routines are dependent upon
181   // priority consistency.
182   enum PendingEventFlags {
183     NO_EVENT_PENDING = 0,
184     SEEK_EVENT_PENDING = 1 << 0,
185     SURFACE_CHANGE_EVENT_PENDING = 1 << 1,
186     CONFIG_CHANGE_EVENT_PENDING = 1 << 2,
187     PREFETCH_REQUEST_EVENT_PENDING = 1 << 3,
188     PREFETCH_DONE_EVENT_PENDING = 1 << 4,
189   };
190
191   static const char* GetEventName(PendingEventFlags event);
192   bool IsEventPending(PendingEventFlags event) const;
193   void SetPendingEvent(PendingEventFlags event);
194   void ClearPendingEvent(PendingEventFlags event);
195
196   scoped_ptr<DemuxerAndroid> demuxer_;
197
198   // Pending event that the player needs to do.
199   unsigned pending_event_;
200
201   // Stats about the media.
202   base::TimeDelta duration_;
203   int width_;
204   int height_;
205   AudioCodec audio_codec_;
206   VideoCodec video_codec_;
207   int num_channels_;
208   int sampling_rate_;
209   // TODO(xhwang/qinmin): Add |video_extra_data_|.
210   std::vector<uint8> audio_extra_data_;
211   bool reached_audio_eos_;
212   bool reached_video_eos_;
213   bool playing_;
214   bool is_audio_encrypted_;
215   bool is_video_encrypted_;
216   double volume_;
217
218   // base::TickClock used by |clock_|.
219   base::DefaultTickClock default_tick_clock_;
220
221   // Reference clock. Keeps track of current playback time.
222   Clock clock_;
223
224   // Timestamps for providing simple A/V sync. When start decoding an audio
225   // chunk, we record its presentation timestamp and the current system time.
226   // Then we use this information to estimate when the next audio/video frame
227   // should be rendered.
228   // TODO(qinmin): Need to fix the problem if audio/video lagged too far behind
229   // due to network or decoding problem.
230   base::TimeTicks start_time_ticks_;
231   base::TimeDelta start_presentation_timestamp_;
232
233   // The surface object currently owned by the player.
234   gfx::ScopedJavaSurface surface_;
235
236   // Track whether or not the player has received any video data since the most
237   // recent of player construction, end of last seek, or receiving and
238   // detecting a |kConfigChanged| access unit from the demuxer.
239   // If no such video data has been received, the next video data begins with
240   // an I-frame. Otherwise, we have no such guarantee.
241   bool next_video_data_is_iframe_;
242
243   // Flag that is true if doing a hack browser seek or false if doing a
244   // regular seek. Only valid when |SEEK_EVENT_PENDING| is pending.
245   // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
246   // since last keyframe. See http://crbug.com/304234.
247   bool doing_browser_seek_;
248
249   // If already doing a browser seek when a regular seek request arrives,
250   // these fields remember the regular seek so OnDemuxerSeekDone() can trigger
251   // it when the browser seek is done. These are only valid when
252   // |SEEK_EVENT_PENDING| is pending.
253   bool pending_seek_;
254   base::TimeDelta pending_seek_time_;
255
256   // Decoder jobs.
257   scoped_ptr<AudioDecoderJob, MediaDecoderJob::Deleter> audio_decoder_job_;
258   scoped_ptr<VideoDecoderJob, MediaDecoderJob::Deleter> video_decoder_job_;
259
260   bool reconfig_audio_decoder_;
261   bool reconfig_video_decoder_;
262
263   // Track the most recent preroll target. Decoder re-creation needs this to
264   // resume any in-progress preroll.
265   base::TimeDelta preroll_timestamp_;
266
267   // A cancelable task that is posted when the audio decoder starts requesting
268   // new data. This callback runs if no data arrives before the timeout period
269   // elapses.
270   base::CancelableClosure decoder_starvation_callback_;
271
272   MediaDrmBridge* drm_bridge_;
273
274   // No decryption key available to decrypt the encrypted buffer. In this case,
275   // the player should pause. When a new key is added (OnKeyAdded()), we should
276   // try to start playback again.
277   bool is_waiting_for_key_;
278
279   // Test-only callback for hooking the completion of the next decode cycle.
280   base::Closure decode_callback_for_testing_;
281
282   // Whether |surface_| is currently used by the player.
283   bool is_surface_in_use_;
284
285   // Whether there are pending data requests by the decoder.
286   bool has_pending_audio_data_request_;
287   bool has_pending_video_data_request_;
288
289   // Weak pointer passed to media decoder jobs for callbacks.
290   // NOTE: Weak pointers must be invalidated before all other member variables.
291   base::WeakPtrFactory<MediaSourcePlayer> weak_factory_;
292
293   DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayer);
294 };
295
296 }  // namespace media
297
298 #endif  // MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_