1f10a79a21002a38e6ebc4ed01dec31872f39aed6Richard Smith// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Use of this source code is governed by a BSD-style license that can be
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// found in the LICENSE file.
42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
5b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith#ifndef MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_
6b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith#define MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_
77cbd7e502e993320a3a1578179d336c268b80604Will Dietz
87cbd7e502e993320a3a1578179d336c268b80604Will Dietz#include <jni.h>
9b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith#include <map>
10b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith#include <string>
11b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith#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/media_export.h"
27#include "media/base/time_delta_interpolator.h"
28
29namespace media {
30
31class AudioDecoderJob;
32class 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.
36class 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                    scoped_ptr<DemuxerAndroid> demuxer,
45                    const GURL& frame_url);
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 SetCdm(BrowserCdm* cdm) OVERRIDE;
65
66  // DemuxerAndroidClient implementation.
67  virtual void OnDemuxerConfigsAvailable(const DemuxerConfigs& params) OVERRIDE;
68  virtual void OnDemuxerDataAvailable(const DemuxerData& params) OVERRIDE;
69  virtual void OnDemuxerSeekDone(
70      base::TimeDelta actual_browser_seek_time) OVERRIDE;
71  virtual void OnDemuxerDurationChanged(base::TimeDelta duration) OVERRIDE;
72
73 private:
74  friend class MediaSourcePlayerTest;
75
76  // Update the current timestamp.
77  void UpdateTimestamps(base::TimeDelta current_presentation_timestamp,
78                        base::TimeDelta max_presentation_timestamp);
79
80  // Helper function for starting media playback.
81  void StartInternal();
82
83  // Playback is completed for one channel.
84  void PlaybackCompleted(bool is_audio);
85
86  // Called when the decoder finishes its task.
87  void MediaDecoderCallback(
88        bool is_audio, MediaCodecStatus status,
89        base::TimeDelta current_presentation_timestamp,
90        base::TimeDelta max_presentation_timestamp);
91
92  bool IsPrerollFinished(bool is_audio) const;
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  // Flush the decoders and clean up all the data needs to be decoded.
104  void ClearDecodingData();
105
106  // Called to decode more data.
107  void DecodeMoreAudio();
108  void DecodeMoreVideo();
109
110  // Functions check whether audio/video is present.
111  bool HasVideo() const;
112  bool HasAudio() const;
113
114  // Functions that check whether audio/video stream has reached end of output
115  // or are not present in player configuration.
116  bool AudioFinished();
117  bool VideoFinished();
118
119  // Determine seekability based on duration.
120  bool Seekable();
121
122  // Called when the |decoder_starvation_callback_| times out.
123  void OnDecoderStarved();
124
125  // Starts the |decoder_starvation_callback_| task with the timeout value.
126  // |current_presentation_timestamp| - The presentation timestamp used for
127  // starvation timeout computations. It represents the current timestamp of
128  // rendered data.
129  // |max_presentation_timestamp| - The presentation timestamp if all the
130  // decoded data are rendered.
131  void StartStarvationCallback(
132      base::TimeDelta current_presentation_timestamp,
133      base::TimeDelta max_presentation_timestamp);
134
135  // Schedules a seek event in |pending_events_| and calls StopDecode() on all
136  // the MediaDecoderJobs. Sets clock to |seek_time|, and resets
137  // |pending_seek_|. There must not already be a seek event in
138  // |pending_events_|.
139  void ScheduleSeekEventAndStopDecoding(base::TimeDelta seek_time);
140
141  // Schedules a browser seek event. We must not currently be processing any
142  // seek. Note that there is possibility that browser seek of renderer demuxer
143  // may unexpectedly stall due to lack of buffered data at or after the browser
144  // seek time.
145  // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
146  // since last keyframe. See http://crbug.com/304234.
147  void BrowserSeekToCurrentTime();
148
149  // Helper function to determine whether a protected surface is needed for
150  // video playback.
151  bool IsProtectedSurfaceRequired();
152
153  // Called when a MediaDecoderJob finishes prefetching data. Once all
154  // MediaDecoderJobs have prefetched data, then this method updates
155  // |start_time_ticks_| and |start_presentation_timestamp_| so that video can
156  // resync with audio and starts decoding.
157  void OnPrefetchDone();
158
159  // Called when the demuxer config changes.
160  void OnDemuxerConfigsChanged();
161
162  // Called when new decryption key becomes available.
163  void OnKeyAdded();
164
165  // Called when the CDM is detached.
166  void OnCdmUnset();
167
168  // Test-only method to setup hook for the completion of the next decode cycle.
169  // This callback state is cleared when it is next run.
170  // Prevent usage creep by only calling this from the
171  // ReleaseWithOnPrefetchDoneAlreadyPosted MediaSourcePlayerTest.
172  void set_decode_callback_for_testing(const base::Closure& test_decode_cb) {
173    decode_callback_for_testing_ = test_decode_cb;
174  }
175
176  // Please keep this in sync with |kPendingEventNames| in GetEventName().
177  enum PendingEventFlags {
178    NO_EVENT_PENDING = 0,
179    PREFETCH_DONE_EVENT_PENDING = 1 << 0,
180    SEEK_EVENT_PENDING = 1 << 1,
181    DECODER_CREATION_EVENT_PENDING = 1 << 2,
182    PREFETCH_REQUEST_EVENT_PENDING = 1 << 3,
183  };
184
185  static const char* GetEventName(PendingEventFlags event);
186  bool IsEventPending(PendingEventFlags event) const;
187  void SetPendingEvent(PendingEventFlags event);
188  void ClearPendingEvent(PendingEventFlags event);
189
190  // If the player is previously waiting for audio or video decoder job, retry
191  // creating the decoders identified by |audio| and |video|.
192  void RetryDecoderCreation(bool audio, bool video);
193
194  scoped_ptr<DemuxerAndroid> demuxer_;
195
196  // Pending event that the player needs to do.
197  unsigned pending_event_;
198
199  // Stats about the media.
200  base::TimeDelta duration_;
201  bool playing_;
202
203  // base::TickClock used by |interpolator_|.
204  base::DefaultTickClock default_tick_clock_;
205
206  // Tracks the most recent media time update and provides interpolated values
207  // as playback progresses.
208  TimeDeltaInterpolator interpolator_;
209
210  // Timestamps for providing simple A/V sync. When start decoding an audio
211  // chunk, we record its presentation timestamp and the current system time.
212  // Then we use this information to estimate when the next audio/video frame
213  // should be rendered.
214  // TODO(qinmin): Need to fix the problem if audio/video lagged too far behind
215  // due to network or decoding problem.
216  base::TimeTicks start_time_ticks_;
217  base::TimeDelta start_presentation_timestamp_;
218
219  // Flag that is true if doing a hack browser seek or false if doing a
220  // regular seek. Only valid when |SEEK_EVENT_PENDING| is pending.
221  // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
222  // since last keyframe. See http://crbug.com/304234.
223  bool doing_browser_seek_;
224
225  // If already doing a browser seek when a regular seek request arrives,
226  // these fields remember the regular seek so OnDemuxerSeekDone() can trigger
227  // it when the browser seek is done. These are only valid when
228  // |SEEK_EVENT_PENDING| is pending.
229  bool pending_seek_;
230  base::TimeDelta pending_seek_time_;
231
232  // Decoder jobs.
233  scoped_ptr<AudioDecoderJob, MediaDecoderJob::Deleter> audio_decoder_job_;
234  scoped_ptr<VideoDecoderJob, MediaDecoderJob::Deleter> video_decoder_job_;
235
236  // Track the most recent preroll target. Decoder re-creation needs this to
237  // resume any in-progress preroll.
238  base::TimeDelta preroll_timestamp_;
239
240  // A cancelable task that is posted when the audio decoder starts requesting
241  // new data. This callback runs if no data arrives before the timeout period
242  // elapses.
243  base::CancelableClosure decoder_starvation_callback_;
244
245  MediaDrmBridge* drm_bridge_;
246  int cdm_registration_id_;
247
248  // No decryption key available to decrypt the encrypted buffer. In this case,
249  // the player should pause. When a new key is added (OnKeyAdded()), we should
250  // try to start playback again.
251  bool is_waiting_for_key_;
252
253  // Indicates whether the player is waiting for audio or video decoder to be
254  // created. This could happen if video surface is not available or key is
255  // not added.
256  bool is_waiting_for_audio_decoder_;
257  bool is_waiting_for_video_decoder_;
258
259  // Test-only callback for hooking the completion of the next decode cycle.
260  base::Closure decode_callback_for_testing_;
261
262  // Whether audio or video decoder is in the process of prerolling.
263  bool prerolling_;
264
265  // Weak pointer passed to media decoder jobs for callbacks.
266  // NOTE: Weak pointers must be invalidated before all other member variables.
267  base::WeakPtrFactory<MediaSourcePlayer> weak_factory_;
268  base::WeakPtr<MediaSourcePlayer> weak_this_;
269
270  DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayer);
271};
272
273}  // namespace media
274
275#endif  // MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_
276