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_stream_player_params.h" 22 #include "media/base/android/media_codec_bridge.h" 23 #include "media/base/android/media_player_android.h" 24 #include "media/base/clock.h" 25 #include "media/base/media_export.h" 26 27 namespace base { 28 class MessageLoopProxy; 29 } 30 31 namespace media { 32 33 class AudioDecoderJob; 34 class AudioTimestampHelper; 35 class VideoDecoderJob; 36 37 // Class for managing all the decoding tasks. Each decoding task will be posted 38 // onto the same thread. The thread will be stopped once Stop() is called. 39 class MediaDecoderJob { 40 public: 41 enum DecodeStatus { 42 DECODE_SUCCEEDED, 43 DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER, 44 DECODE_TRY_DEQUEUE_OUTPUT_AGAIN_LATER, 45 DECODE_FORMAT_CHANGED, 46 DECODE_INPUT_END_OF_STREAM, 47 DECODE_OUTPUT_END_OF_STREAM, 48 DECODE_FAILED, 49 }; 50 51 virtual ~MediaDecoderJob(); 52 53 // Callback when a decoder job finishes its work. Args: whether decode 54 // finished successfully, presentation time, audio output bytes. 55 typedef base::Callback<void(DecodeStatus, const base::TimeDelta&, 56 size_t)> DecoderCallback; 57 58 // Called by MediaSourcePlayer to decode some data. 59 void Decode(const AccessUnit& unit, 60 const base::TimeTicks& start_time_ticks, 61 const base::TimeDelta& start_presentation_timestamp, 62 const MediaDecoderJob::DecoderCallback& callback); 63 64 // Flush the decoder. 65 void Flush(); 66 67 // Causes this instance to be deleted on the thread it is bound to. 68 void Release(); 69 70 // Called on the UI thread to indicate that one decode cycle has completed. 71 void OnDecodeCompleted(); 72 73 bool is_decoding() const { return is_decoding_; } 74 75 protected: 76 MediaDecoderJob(const scoped_refptr<base::MessageLoopProxy>& decoder_loop, 77 MediaCodecBridge* media_codec_bridge, 78 bool is_audio); 79 80 // Release the output buffer and render it. 81 void ReleaseOutputBuffer( 82 int outputBufferIndex, size_t size, 83 const base::TimeDelta& presentation_timestamp, 84 const MediaDecoderJob::DecoderCallback& callback, DecodeStatus status); 85 86 DecodeStatus QueueInputBuffer(const AccessUnit& unit); 87 88 // Helper function to decoder data on |thread_|. |unit| contains all the data 89 // to be decoded. |start_time_ticks| and |start_presentation_timestamp| 90 // represent the system time and the presentation timestamp when the first 91 // frame is rendered. We use these information to estimate when the current 92 // frame should be rendered. If |needs_flush| is true, codec needs to be 93 // flushed at the beginning of this call. 94 void DecodeInternal(const AccessUnit& unit, 95 const base::TimeTicks& start_time_ticks, 96 const base::TimeDelta& start_presentation_timestamp, 97 bool needs_flush, 98 const MediaDecoderJob::DecoderCallback& callback); 99 100 // The UI message loop where callbacks should be dispatched. 101 scoped_refptr<base::MessageLoopProxy> ui_loop_; 102 103 // The message loop that decoder job runs on. 104 scoped_refptr<base::MessageLoopProxy> decoder_loop_; 105 106 // The media codec bridge used for decoding. 107 scoped_ptr<MediaCodecBridge> media_codec_bridge_; 108 109 // Whether the decoder needs to be flushed. 110 bool needs_flush_; 111 112 // Whether this is an audio decoder. 113 bool is_audio_; 114 115 // Whether input EOS is encountered. 116 bool input_eos_encountered_; 117 118 // Weak pointer passed to media decoder jobs for callbacks. It is bounded to 119 // the decoder thread. 120 base::WeakPtrFactory<MediaDecoderJob> weak_this_; 121 122 // Whether the decoder is actively decoding data. 123 bool is_decoding_; 124 }; 125 126 struct DecoderJobDeleter { 127 inline void operator()(MediaDecoderJob* ptr) const { ptr->Release(); } 128 }; 129 130 // This class handles media source extensions on Android. It uses Android 131 // MediaCodec to decode audio and video streams in two separate threads. 132 // IPC is being used to send data from the render process to this object. 133 // TODO(qinmin): use shared memory to send data between processes. 134 class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { 135 public: 136 // Construct a MediaSourcePlayer object with all the needed media player 137 // callbacks. 138 MediaSourcePlayer(int player_id, MediaPlayerManager* manager); 139 virtual ~MediaSourcePlayer(); 140 141 // MediaPlayerAndroid implementation. 142 virtual void SetVideoSurface(gfx::ScopedJavaSurface surface) OVERRIDE; 143 virtual void Start() OVERRIDE; 144 virtual void Pause() OVERRIDE; 145 virtual void SeekTo(base::TimeDelta timestamp) OVERRIDE; 146 virtual void Release() OVERRIDE; 147 virtual void SetVolume(double volume) OVERRIDE; 148 virtual int GetVideoWidth() OVERRIDE; 149 virtual int GetVideoHeight() OVERRIDE; 150 virtual base::TimeDelta GetCurrentTime() OVERRIDE; 151 virtual base::TimeDelta GetDuration() OVERRIDE; 152 virtual bool IsPlaying() OVERRIDE; 153 virtual bool CanPause() OVERRIDE; 154 virtual bool CanSeekForward() OVERRIDE; 155 virtual bool CanSeekBackward() OVERRIDE; 156 virtual bool IsPlayerReady() OVERRIDE; 157 virtual void OnSeekRequestAck(unsigned seek_request_id) OVERRIDE; 158 virtual void DemuxerReady( 159 const MediaPlayerHostMsg_DemuxerReady_Params& params) OVERRIDE; 160 virtual void ReadFromDemuxerAck( 161 const MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) OVERRIDE; 162 virtual void DurationChanged(const base::TimeDelta& duration) OVERRIDE; 163 virtual void SetDrmBridge(MediaDrmBridge* drm_bridge) OVERRIDE; 164 165 private: 166 // Update the current timestamp. 167 void UpdateTimestamps(const base::TimeDelta& presentation_timestamp, 168 size_t audio_output_bytes); 169 170 // Helper function for starting media playback. 171 void StartInternal(); 172 173 // Playback is completed for one channel. 174 void PlaybackCompleted(bool is_audio); 175 176 // Called when the decoder finishes its task. 177 void MediaDecoderCallback( 178 bool is_audio, MediaDecoderJob::DecodeStatus decode_status, 179 const base::TimeDelta& presentation_timestamp, 180 size_t audio_output_bytes); 181 182 // Handle pending events when all the decoder jobs finished. 183 void ProcessPendingEvents(); 184 185 // Helper method to configure the decoder jobs. 186 void ConfigureVideoDecoderJob(); 187 void ConfigureAudioDecoderJob(); 188 189 // Flush the decoders and clean up all the data needs to be decoded. 190 void ClearDecodingData(); 191 192 // Called to decoder more data. 193 void DecodeMoreAudio(); 194 void DecodeMoreVideo(); 195 196 // Functions check whether audio/video is present. 197 bool HasVideo(); 198 bool HasAudio(); 199 200 // Determine seekability based on duration. 201 bool Seekable(); 202 203 // Called when the |decoder_starvation_callback_| times out. 204 void OnDecoderStarved(); 205 206 // Starts the |decoder_starvation_callback_| task with the timeout value. 207 void StartStarvationCallback(const base::TimeDelta& timeout); 208 209 // Called to sync decoder jobs. This call requests data from chunk demuxer 210 // first. Then it updates |start_time_ticks_| and 211 // |start_presentation_timestamp_| so that video can resync with audio. 212 void SyncAndStartDecoderJobs(); 213 214 // Functions that send IPC requests to the renderer process for more 215 // audio/video data. Returns true if a request has been sent and the decoder 216 // needs to wait, or false otherwise. 217 void RequestAudioData(); 218 void RequestVideoData(); 219 220 // Check whether audio or video data is available for decoders to consume. 221 bool HasAudioData() const; 222 bool HasVideoData() const; 223 224 // Helper function to set the volume. 225 void SetVolumeInternal(); 226 227 enum PendingEventFlags { 228 NO_EVENT_PENDING = 0, 229 SEEK_EVENT_PENDING = 1 << 0, 230 SURFACE_CHANGE_EVENT_PENDING = 1 << 1, 231 CONFIG_CHANGE_EVENT_PENDING = 1 << 2, 232 }; 233 // Pending event that the player needs to do. 234 unsigned pending_event_; 235 236 // ID to keep track of whether all the seek requests are acked. 237 unsigned seek_request_id_; 238 239 // Stats about the media. 240 base::TimeDelta duration_; 241 int width_; 242 int height_; 243 AudioCodec audio_codec_; 244 VideoCodec video_codec_; 245 int num_channels_; 246 int sampling_rate_; 247 // TODO(xhwang/qinmin): Add |video_extra_data_|. 248 std::vector<uint8> audio_extra_data_; 249 bool audio_finished_; 250 bool video_finished_; 251 bool playing_; 252 bool is_audio_encrypted_; 253 bool is_video_encrypted_; 254 double volume_; 255 256 // base::TickClock used by |clock_|. 257 base::DefaultTickClock default_tick_clock_; 258 259 // Reference clock. Keeps track of current playback time. 260 Clock clock_; 261 262 // Timestamps for providing simple A/V sync. When start decoding an audio 263 // chunk, we record its presentation timestamp and the current system time. 264 // Then we use this information to estimate when the next audio/video frame 265 // should be rendered. 266 // TODO(qinmin): Need to fix the problem if audio/video lagged too far behind 267 // due to network or decoding problem. 268 base::TimeTicks start_time_ticks_; 269 base::TimeDelta start_presentation_timestamp_; 270 271 // The surface object currently owned by the player. 272 gfx::ScopedJavaSurface surface_; 273 274 // Decoder jobs 275 scoped_ptr<AudioDecoderJob, DecoderJobDeleter> audio_decoder_job_; 276 scoped_ptr<VideoDecoderJob, DecoderJobDeleter> video_decoder_job_; 277 278 bool reconfig_audio_decoder_; 279 bool reconfig_video_decoder_; 280 281 // These variables keep track of the current decoding data. 282 // TODO(qinmin): remove these variables when we no longer relies on IPC for 283 // data passing. 284 size_t audio_access_unit_index_; 285 size_t video_access_unit_index_; 286 bool waiting_for_audio_data_; 287 bool waiting_for_video_data_; 288 MediaPlayerHostMsg_ReadFromDemuxerAck_Params received_audio_; 289 MediaPlayerHostMsg_ReadFromDemuxerAck_Params received_video_; 290 291 // A cancelable task that is posted when the audio decoder starts requesting 292 // new data. This callback runs if no data arrives before the timeout period 293 // elapses. 294 base::CancelableClosure decoder_starvation_callback_; 295 296 // Whether the audio and video decoder jobs should resync with each other. 297 bool sync_decoder_jobs_; 298 299 // Object to calculate the current audio timestamp for A/V sync. 300 scoped_ptr<AudioTimestampHelper> audio_timestamp_helper_; 301 302 // Weak pointer passed to media decoder jobs for callbacks. 303 base::WeakPtrFactory<MediaSourcePlayer> weak_this_; 304 305 MediaDrmBridge* drm_bridge_; 306 307 friend class MediaSourcePlayerTest; 308 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayer); 309 }; 310 311 } // namespace media 312 313 #endif // MEDIA_BASE_ANDROID_MEDIA_SOURCE_PLAYER_H_ 314