media_source_player.cc revision bffa56837bb88af19413f59d410b5854f3dd01c3
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#include "media/base/android/media_source_player.h"
6
7#include "base/android/jni_android.h"
8#include "base/android/jni_string.h"
9#include "base/basictypes.h"
10#include "base/bind.h"
11#include "base/lazy_instance.h"
12#include "base/logging.h"
13#include "base/message_loop/message_loop.h"
14#include "base/threading/thread.h"
15#include "media/base/android/media_codec_bridge.h"
16#include "media/base/android/media_drm_bridge.h"
17#include "media/base/android/media_player_manager.h"
18#include "media/base/audio_timestamp_helper.h"
19
20namespace {
21
22// Timeout value for media codec operations. Because the first
23// DequeInputBuffer() can take about 150 milliseconds, use 250 milliseconds
24// here. See b/9357571.
25const int kMediaCodecTimeoutInMilliseconds = 250;
26
27// Use 16bit PCM for audio output. Keep this value in sync with the output
28// format we passed to AudioTrack in MediaCodecBridge.
29const int kBytesPerAudioOutputSample = 2;
30
31class DecoderThread : public base::Thread {
32 public:
33  virtual ~DecoderThread() {}
34 protected:
35  DecoderThread(const char* name) : base::Thread(name) { Start(); }
36};
37
38class AudioDecoderThread : public DecoderThread {
39 public:
40  AudioDecoderThread() : DecoderThread("MediaSource_AudioDecoderThread") {}
41};
42
43class VideoDecoderThread : public DecoderThread {
44 public:
45  VideoDecoderThread() : DecoderThread("MediaSource_VideoDecoderThread") {}
46};
47
48// TODO(qinmin): Check if it is tolerable to use worker pool to handle all the
49// decoding tasks so that we don't need the global threads here.
50// http://crbug.com/245750
51base::LazyInstance<AudioDecoderThread>::Leaky
52    g_audio_decoder_thread = LAZY_INSTANCE_INITIALIZER;
53
54base::LazyInstance<VideoDecoderThread>::Leaky
55    g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER;
56
57}
58
59namespace media {
60
61MediaDecoderJob::MediaDecoderJob(
62    const scoped_refptr<base::MessageLoopProxy>& decoder_loop,
63    MediaCodecBridge* media_codec_bridge,
64    bool is_audio)
65    : ui_loop_(base::MessageLoopProxy::current()),
66      decoder_loop_(decoder_loop),
67      media_codec_bridge_(media_codec_bridge),
68      needs_flush_(false),
69      is_audio_(is_audio),
70      input_eos_encountered_(false),
71      weak_this_(this),
72      is_decoding_(false) {
73}
74
75MediaDecoderJob::~MediaDecoderJob() {}
76
77// Class for managing audio decoding jobs.
78class AudioDecoderJob : public MediaDecoderJob {
79 public:
80  virtual ~AudioDecoderJob() {}
81
82  static AudioDecoderJob* Create(
83      const AudioCodec audio_codec, int sample_rate, int channel_count,
84      const uint8* extra_data, size_t extra_data_size, jobject media_crypto);
85
86  void SetVolume(double volume);
87
88 private:
89  AudioDecoderJob(MediaCodecBridge* media_codec_bridge);
90};
91
92// Class for managing video decoding jobs.
93class VideoDecoderJob : public MediaDecoderJob {
94 public:
95  virtual ~VideoDecoderJob() {}
96
97  static VideoDecoderJob* Create(
98      const VideoCodec video_codec, const gfx::Size& size, jobject surface,
99      jobject media_crypto);
100
101 private:
102  VideoDecoderJob(MediaCodecBridge* media_codec_bridge);
103};
104
105void MediaDecoderJob::Decode(
106    const AccessUnit& unit,
107    const base::TimeTicks& start_time_ticks,
108    const base::TimeDelta& start_presentation_timestamp,
109    const MediaDecoderJob::DecoderCallback& callback) {
110  DCHECK(!is_decoding_);
111  DCHECK(ui_loop_->BelongsToCurrentThread());
112  is_decoding_ = true;
113  decoder_loop_->PostTask(FROM_HERE, base::Bind(
114      &MediaDecoderJob::DecodeInternal, base::Unretained(this), unit,
115      start_time_ticks, start_presentation_timestamp, needs_flush_,
116      callback));
117  needs_flush_ = false;
118}
119
120MediaDecoderJob::DecodeStatus MediaDecoderJob::QueueInputBuffer(
121    const AccessUnit& unit) {
122  base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
123      kMediaCodecTimeoutInMilliseconds);
124  int input_buf_index = media_codec_bridge_->DequeueInputBuffer(timeout);
125  if (input_buf_index == MediaCodecBridge::INFO_MEDIA_CODEC_ERROR)
126    return DECODE_FAILED;
127  if (input_buf_index == MediaCodecBridge::INFO_TRY_AGAIN_LATER)
128    return DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER;
129
130  // TODO(qinmin): skip frames if video is falling far behind.
131  DCHECK(input_buf_index >= 0);
132  if (unit.end_of_stream || unit.data.empty()) {
133    media_codec_bridge_->QueueEOS(input_buf_index);
134    return DECODE_INPUT_END_OF_STREAM;
135  }
136  if (unit.key_id.empty()) {
137    media_codec_bridge_->QueueInputBuffer(
138        input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp);
139  } else {
140    if (unit.iv.empty() || unit.subsamples.empty()) {
141      LOG(ERROR) << "The access unit doesn't have iv or subsamples while it "
142                 << "has key IDs!";
143      return DECODE_FAILED;
144    }
145    media_codec_bridge_->QueueSecureInputBuffer(
146        input_buf_index, &unit.data[0], unit.data.size(),
147        reinterpret_cast<const uint8*>(&unit.key_id[0]), unit.key_id.size(),
148        reinterpret_cast<const uint8*>(&unit.iv[0]), unit.iv.size(),
149        &unit.subsamples[0], unit.subsamples.size(), unit.timestamp);
150  }
151
152  return DECODE_SUCCEEDED;
153}
154
155void MediaDecoderJob::DecodeInternal(
156    const AccessUnit& unit,
157    const base::TimeTicks& start_time_ticks,
158    const base::TimeDelta& start_presentation_timestamp,
159    bool needs_flush,
160    const MediaDecoderJob::DecoderCallback& callback) {
161  if (needs_flush) {
162    DVLOG(1) << "DecodeInternal needs flush.";
163    input_eos_encountered_ = false;
164    int reset_status = media_codec_bridge_->Reset();
165    if (0 != reset_status) {
166      ui_loop_->PostTask(FROM_HERE, base::Bind(
167          callback, DECODE_FAILED, start_presentation_timestamp, 0));
168      return;
169    }
170  }
171
172  DecodeStatus decode_status = DECODE_INPUT_END_OF_STREAM;
173  if (!input_eos_encountered_) {
174    decode_status = QueueInputBuffer(unit);
175    if (decode_status == DECODE_INPUT_END_OF_STREAM) {
176      input_eos_encountered_ = true;
177    } else if (decode_status != DECODE_SUCCEEDED) {
178      ui_loop_->PostTask(FROM_HERE,
179                         base::Bind(callback, decode_status,
180                                    start_presentation_timestamp, 0));
181      return;
182    }
183  }
184
185  size_t offset = 0;
186  size_t size = 0;
187  base::TimeDelta presentation_timestamp;
188  bool end_of_stream = false;
189
190  base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
191      kMediaCodecTimeoutInMilliseconds);
192  int outputBufferIndex = media_codec_bridge_->DequeueOutputBuffer(
193      timeout, &offset, &size, &presentation_timestamp, &end_of_stream);
194
195  if (end_of_stream)
196    decode_status = DECODE_OUTPUT_END_OF_STREAM;
197  switch (outputBufferIndex) {
198    case MediaCodecBridge::INFO_OUTPUT_BUFFERS_CHANGED:
199      DCHECK(decode_status != DECODE_INPUT_END_OF_STREAM);
200      media_codec_bridge_->GetOutputBuffers();
201      break;
202    case MediaCodecBridge::INFO_OUTPUT_FORMAT_CHANGED:
203      DCHECK(decode_status != DECODE_INPUT_END_OF_STREAM);
204      // TODO(qinmin): figure out what we should do if format changes.
205      decode_status = DECODE_FORMAT_CHANGED;
206      break;
207    case MediaCodecBridge::INFO_TRY_AGAIN_LATER:
208      decode_status = DECODE_TRY_DEQUEUE_OUTPUT_AGAIN_LATER;
209      break;
210    case MediaCodecBridge::INFO_MEDIA_CODEC_ERROR:
211      decode_status = DECODE_FAILED;
212      break;
213    default:
214      DCHECK_LE(0, outputBufferIndex);
215      base::TimeDelta time_to_render;
216      DCHECK(!start_time_ticks.is_null());
217      if (!is_audio_) {
218        time_to_render = presentation_timestamp - (base::TimeTicks::Now() -
219            start_time_ticks + start_presentation_timestamp);
220      }
221      if (time_to_render >= base::TimeDelta()) {
222        base::MessageLoop::current()->PostDelayedTask(
223            FROM_HERE,
224            base::Bind(&MediaDecoderJob::ReleaseOutputBuffer,
225                       weak_this_.GetWeakPtr(), outputBufferIndex, size,
226                       presentation_timestamp, callback, decode_status),
227            time_to_render);
228      } else {
229        // TODO(qinmin): The codec is lagging behind, need to recalculate the
230        // |start_presentation_timestamp_| and |start_time_ticks_|.
231        DVLOG(1) << (is_audio_ ? "audio " : "video ")
232            << "codec is lagging behind :" << time_to_render.InMicroseconds();
233        ReleaseOutputBuffer(outputBufferIndex, size, presentation_timestamp,
234                            callback, decode_status);
235      }
236      return;
237  }
238  ui_loop_->PostTask(FROM_HERE, base::Bind(
239      callback, decode_status, start_presentation_timestamp, 0));
240}
241
242void MediaDecoderJob::ReleaseOutputBuffer(
243    int outputBufferIndex, size_t size,
244    const base::TimeDelta& presentation_timestamp,
245    const MediaDecoderJob::DecoderCallback& callback, DecodeStatus status) {
246  // TODO(qinmin): Refactor this function. Maybe AudioDecoderJob should provide
247  // its own ReleaseOutputBuffer().
248  if (is_audio_) {
249    static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->PlayOutputBuffer(
250        outputBufferIndex, size);
251  }
252  if (status != DECODE_OUTPUT_END_OF_STREAM || size != 0u)
253    media_codec_bridge_->ReleaseOutputBuffer(outputBufferIndex, !is_audio_);
254  ui_loop_->PostTask(FROM_HERE, base::Bind(
255      callback, status, presentation_timestamp, is_audio_ ? size : 0));
256}
257
258void MediaDecoderJob::OnDecodeCompleted() {
259  DCHECK(ui_loop_->BelongsToCurrentThread());
260  is_decoding_ = false;
261}
262
263void MediaDecoderJob::Flush() {
264  // Do nothing, flush when the next Decode() happens.
265  needs_flush_ = true;
266}
267
268void MediaDecoderJob::Release() {
269  // If |decoding_| is false, there is nothing running on the decoder thread.
270  // So it is safe to delete the MediaDecoderJob on the UI thread. However,
271  // if we post a task to the decoder thread to delete object, then we cannot
272  // immediately pass the surface to a new MediaDecoderJob instance because
273  // the java surface is still owned by the old object. New decoder creation
274  // will be blocked on the UI thread until the previous decoder gets deleted.
275  // This introduces extra latency during config changes, and makes the logic in
276  // MediaSourcePlayer more complicated.
277  //
278  // TODO(qinmin): Figure out the logic to passing the surface to a new
279  // MediaDecoderJob instance after the previous one gets deleted on the decoder
280  // thread.
281  if (is_decoding_ && !decoder_loop_->BelongsToCurrentThread()) {
282    DCHECK(ui_loop_->BelongsToCurrentThread());
283    decoder_loop_->DeleteSoon(FROM_HERE, this);
284  } else {
285    delete this;
286  }
287}
288
289VideoDecoderJob* VideoDecoderJob::Create(
290    const VideoCodec video_codec, const gfx::Size& size, jobject surface,
291    jobject media_crypto) {
292  scoped_ptr<VideoCodecBridge> codec(VideoCodecBridge::Create(video_codec));
293  if (codec && codec->Start(video_codec, size, surface, media_crypto))
294    return new VideoDecoderJob(codec.release());
295  return NULL;
296}
297
298VideoDecoderJob::VideoDecoderJob(MediaCodecBridge* media_codec_bridge)
299    : MediaDecoderJob(g_video_decoder_thread.Pointer()->message_loop_proxy(),
300                      media_codec_bridge,
301                      false) {}
302
303AudioDecoderJob* AudioDecoderJob::Create(
304    const AudioCodec audio_codec,
305    int sample_rate,
306    int channel_count,
307    const uint8* extra_data,
308    size_t extra_data_size,
309    jobject media_crypto) {
310  scoped_ptr<AudioCodecBridge> codec(AudioCodecBridge::Create(audio_codec));
311  if (codec && codec->Start(audio_codec, sample_rate, channel_count, extra_data,
312                            extra_data_size, true, media_crypto)) {
313    return new AudioDecoderJob(codec.release());
314  }
315  return NULL;
316}
317
318AudioDecoderJob::AudioDecoderJob(MediaCodecBridge* media_codec_bridge)
319    : MediaDecoderJob(g_audio_decoder_thread.Pointer()->message_loop_proxy(),
320                      media_codec_bridge,
321                      true) {}
322
323void AudioDecoderJob::SetVolume(double volume) {
324  static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume(volume);
325}
326
327MediaSourcePlayer::MediaSourcePlayer(
328    int player_id,
329    MediaPlayerManager* manager)
330    : MediaPlayerAndroid(player_id, manager),
331      pending_event_(NO_EVENT_PENDING),
332      seek_request_id_(0),
333      width_(0),
334      height_(0),
335      audio_codec_(kUnknownAudioCodec),
336      video_codec_(kUnknownVideoCodec),
337      num_channels_(0),
338      sampling_rate_(0),
339      audio_finished_(true),
340      video_finished_(true),
341      playing_(false),
342      is_audio_encrypted_(false),
343      is_video_encrypted_(false),
344      volume_(-1.0),
345      clock_(&default_tick_clock_),
346      reconfig_audio_decoder_(false),
347      reconfig_video_decoder_(false),
348      audio_access_unit_index_(0),
349      video_access_unit_index_(0),
350      waiting_for_audio_data_(false),
351      waiting_for_video_data_(false),
352      sync_decoder_jobs_(true),
353      weak_this_(this),
354      drm_bridge_(NULL) {
355}
356
357MediaSourcePlayer::~MediaSourcePlayer() {
358  Release();
359}
360
361void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
362  // Ignore non-empty surface that is unprotected if |is_video_encrypted_| is
363  // true.
364  if (is_video_encrypted_ && !surface.IsEmpty() && !surface.is_protected())
365    return;
366
367  surface_ =  surface.Pass();
368  pending_event_ |= SURFACE_CHANGE_EVENT_PENDING;
369  if (pending_event_ & SEEK_EVENT_PENDING) {
370    // Waiting for the seek to finish.
371    return;
372  }
373  // Setting a new surface will require a new MediaCodec to be created.
374  // Request a seek so that the new decoder will decode an I-frame first.
375  // Or otherwise, the new MediaCodec might crash. See b/8950387.
376  pending_event_ |= SEEK_EVENT_PENDING;
377  ProcessPendingEvents();
378}
379
380bool MediaSourcePlayer::Seekable() {
381  // If the duration TimeDelta, converted to milliseconds from microseconds,
382  // is >= 2^31, then the media is assumed to be unbounded and unseekable.
383  // 2^31 is the bound due to java player using 32-bit integer for time
384  // values at millisecond resolution.
385  return duration_ <
386         base::TimeDelta::FromMilliseconds(std::numeric_limits<int32>::max());
387}
388
389void MediaSourcePlayer::Start() {
390  playing_ = true;
391
392  if (is_video_encrypted_)
393    manager()->OnProtectedSurfaceRequested(player_id());
394
395  StartInternal();
396}
397
398void MediaSourcePlayer::Pause() {
399  // Since decoder jobs have their own thread, decoding is not fully paused
400  // until all the decoder jobs call MediaDecoderCallback(). It is possible
401  // that Start() is called while the player is waiting for
402  // MediaDecoderCallback(). In that case, decoding will continue when
403  // MediaDecoderCallback() is called.
404  playing_ = false;
405  start_time_ticks_ = base::TimeTicks();
406}
407
408bool MediaSourcePlayer::IsPlaying() {
409  return playing_;
410}
411
412int MediaSourcePlayer::GetVideoWidth() {
413  return width_;
414}
415
416int MediaSourcePlayer::GetVideoHeight() {
417  return height_;
418}
419
420void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) {
421  clock_.SetTime(timestamp, timestamp);
422  if (audio_timestamp_helper_)
423    audio_timestamp_helper_->SetBaseTimestamp(timestamp);
424  pending_event_ |= SEEK_EVENT_PENDING;
425  ProcessPendingEvents();
426}
427
428base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
429  return clock_.Elapsed();
430}
431
432base::TimeDelta MediaSourcePlayer::GetDuration() {
433  return duration_;
434}
435
436void MediaSourcePlayer::Release() {
437  ClearDecodingData();
438  audio_decoder_job_.reset();
439  video_decoder_job_.reset();
440  reconfig_audio_decoder_ = false;
441  reconfig_video_decoder_ = false;
442  playing_ = false;
443  pending_event_ = NO_EVENT_PENDING;
444  surface_ = gfx::ScopedJavaSurface();
445  ReleaseMediaResourcesFromManager();
446}
447
448void MediaSourcePlayer::SetVolume(double volume) {
449  volume_ = volume;
450  SetVolumeInternal();
451}
452
453bool MediaSourcePlayer::CanPause() {
454  return Seekable();
455}
456
457bool MediaSourcePlayer::CanSeekForward() {
458  return Seekable();
459}
460
461bool MediaSourcePlayer::CanSeekBackward() {
462  return Seekable();
463}
464
465bool MediaSourcePlayer::IsPlayerReady() {
466  return audio_decoder_job_ || video_decoder_job_;
467}
468
469void MediaSourcePlayer::StartInternal() {
470  // If there are pending events, wait for them finish.
471  if (pending_event_ != NO_EVENT_PENDING)
472    return;
473
474  // Create decoder jobs if they are not created
475  ConfigureAudioDecoderJob();
476  ConfigureVideoDecoderJob();
477
478
479  // If one of the decoder job is not ready, do nothing.
480  if ((HasAudio() && !audio_decoder_job_) ||
481      (HasVideo() && !video_decoder_job_)) {
482    return;
483  }
484
485  audio_finished_ = false;
486  video_finished_ = false;
487  sync_decoder_jobs_ = true;
488  SyncAndStartDecoderJobs();
489}
490
491void MediaSourcePlayer::DemuxerReady(
492    const MediaPlayerHostMsg_DemuxerReady_Params& params) {
493  duration_ = base::TimeDelta::FromMilliseconds(params.duration_ms);
494  clock_.SetDuration(duration_);
495
496  audio_codec_ = params.audio_codec;
497  num_channels_ = params.audio_channels;
498  sampling_rate_ = params.audio_sampling_rate;
499  is_audio_encrypted_ = params.is_audio_encrypted;
500  audio_extra_data_ = params.audio_extra_data;
501  if (HasAudio()) {
502    DCHECK_GT(num_channels_, 0);
503    audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_));
504    audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime());
505  } else {
506    audio_timestamp_helper_.reset();
507  }
508
509  video_codec_ = params.video_codec;
510  width_ = params.video_size.width();
511  height_ = params.video_size.height();
512  is_video_encrypted_ = params.is_video_encrypted;
513
514  OnMediaMetadataChanged(duration_, width_, height_, true);
515
516  if (pending_event_ & CONFIG_CHANGE_EVENT_PENDING) {
517    if (reconfig_audio_decoder_)
518      ConfigureAudioDecoderJob();
519
520    // If there is a pending surface change, we can merge it with the config
521    // change.
522    if (reconfig_video_decoder_) {
523      pending_event_ &= ~SURFACE_CHANGE_EVENT_PENDING;
524      ConfigureVideoDecoderJob();
525    }
526    pending_event_ &= ~CONFIG_CHANGE_EVENT_PENDING;
527    if (playing_)
528      StartInternal();
529  }
530}
531
532void MediaSourcePlayer::ReadFromDemuxerAck(
533    const MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) {
534  DCHECK_LT(0u, params.access_units.size());
535  if (params.type == DemuxerStream::AUDIO)
536    waiting_for_audio_data_ = false;
537  else
538    waiting_for_video_data_ = false;
539
540  // If there is a pending seek request, ignore the data from the chunk demuxer.
541  // The data will be requested later when OnSeekRequestAck() is called.
542  if (pending_event_ & SEEK_EVENT_PENDING)
543    return;
544
545  if (params.type == DemuxerStream::AUDIO) {
546    DCHECK_EQ(0u, audio_access_unit_index_);
547    received_audio_ = params;
548  } else {
549    DCHECK_EQ(0u, video_access_unit_index_);
550    received_video_ = params;
551  }
552
553  if (pending_event_ != NO_EVENT_PENDING || !playing_)
554    return;
555
556  if (sync_decoder_jobs_) {
557    SyncAndStartDecoderJobs();
558    return;
559  }
560
561  if (params.type == DemuxerStream::AUDIO)
562    DecodeMoreAudio();
563  else
564    DecodeMoreVideo();
565}
566
567void MediaSourcePlayer::DurationChanged(const base::TimeDelta& duration) {
568  duration_ = duration;
569  clock_.SetDuration(duration_);
570}
571
572void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) {
573  // Currently we don't support DRM change during the middle of playback, even
574  // if the player is paused.
575  // TODO(qinmin): support DRM change after playback has started.
576  // http://crbug.com/253792.
577  if (GetCurrentTime() > base::TimeDelta()) {
578    LOG(INFO) << "Setting DRM bridge after play back has started. "
579              << "This is not well supported!";
580  }
581
582  drm_bridge_ = drm_bridge;
583
584  if (playing_)
585    StartInternal();
586}
587
588void MediaSourcePlayer::OnSeekRequestAck(unsigned seek_request_id) {
589  DVLOG(1) << "OnSeekRequestAck(" << seek_request_id << ")";
590  // Do nothing until the most recent seek request is processed.
591  if (seek_request_id_ != seek_request_id)
592    return;
593  pending_event_ &= ~SEEK_EVENT_PENDING;
594  OnSeekComplete();
595  ProcessPendingEvents();
596}
597
598void MediaSourcePlayer::UpdateTimestamps(
599    const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
600  if (audio_output_bytes > 0) {
601    audio_timestamp_helper_->AddFrames(
602        audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
603    clock_.SetMaxTime(audio_timestamp_helper_->GetTimestamp());
604  } else {
605    clock_.SetMaxTime(presentation_timestamp);
606  }
607
608  OnTimeUpdated();
609}
610
611void MediaSourcePlayer::ProcessPendingEvents() {
612  // Wait for all the decoding jobs to finish before processing pending tasks.
613  if ((audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
614      (video_decoder_job_ && video_decoder_job_->is_decoding())) {
615    return;
616  }
617
618  if (pending_event_ & SEEK_EVENT_PENDING) {
619    ClearDecodingData();
620    manager()->OnMediaSeekRequest(
621        player_id(), GetCurrentTime(), ++seek_request_id_);
622    return;
623  }
624
625  start_time_ticks_ = base::TimeTicks();
626  if (pending_event_ & CONFIG_CHANGE_EVENT_PENDING) {
627    DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
628    manager()->OnMediaConfigRequest(player_id());
629    return;
630  }
631
632  if (pending_event_ & SURFACE_CHANGE_EVENT_PENDING) {
633    video_decoder_job_.reset();
634    ConfigureVideoDecoderJob();
635    pending_event_ &= ~SURFACE_CHANGE_EVENT_PENDING;
636  }
637
638  if (playing_)
639    StartInternal();
640}
641
642void MediaSourcePlayer::MediaDecoderCallback(
643    bool is_audio, MediaDecoderJob::DecodeStatus decode_status,
644    const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
645  if (is_audio && audio_decoder_job_)
646    audio_decoder_job_->OnDecodeCompleted();
647  if (!is_audio && video_decoder_job_)
648    video_decoder_job_->OnDecodeCompleted();
649
650  if (is_audio)
651    decoder_starvation_callback_.Cancel();
652
653  if (decode_status == MediaDecoderJob::DECODE_FAILED) {
654    Release();
655    OnMediaError(MEDIA_ERROR_DECODE);
656    return;
657  }
658
659  // If the input reaches input EOS, there is no need to request new data.
660  if (decode_status != MediaDecoderJob::DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER &&
661      decode_status != MediaDecoderJob::DECODE_INPUT_END_OF_STREAM) {
662    if (is_audio)
663      audio_access_unit_index_++;
664    else
665      video_access_unit_index_++;
666  }
667
668  if (pending_event_ != NO_EVENT_PENDING) {
669    ProcessPendingEvents();
670    return;
671  }
672
673  if (decode_status == MediaDecoderJob::DECODE_SUCCEEDED &&
674      (is_audio || !HasAudio())) {
675    UpdateTimestamps(presentation_timestamp, audio_output_bytes);
676  }
677
678  if (decode_status == MediaDecoderJob::DECODE_OUTPUT_END_OF_STREAM) {
679    PlaybackCompleted(is_audio);
680    return;
681  }
682
683  if (!playing_) {
684    if (is_audio || !HasAudio())
685      clock_.Pause();
686    return;
687  }
688
689  if (sync_decoder_jobs_) {
690    SyncAndStartDecoderJobs();
691    return;
692  }
693
694  base::TimeDelta current_timestamp = GetCurrentTime();
695  if (is_audio) {
696    if (decode_status == MediaDecoderJob::DECODE_SUCCEEDED) {
697      base::TimeDelta timeout =
698          audio_timestamp_helper_->GetTimestamp() - current_timestamp;
699      StartStarvationCallback(timeout);
700    }
701    if (!HasAudioData())
702      RequestAudioData();
703    else
704      DecodeMoreAudio();
705    return;
706  }
707
708  if (!HasAudio() && decode_status == MediaDecoderJob::DECODE_SUCCEEDED) {
709    DCHECK(current_timestamp <= presentation_timestamp);
710    // For video only streams, fps can be estimated from the difference
711    // between the previous and current presentation timestamps. The
712    // previous presentation timestamp is equal to current_timestamp.
713    // TODO(qinmin): determine whether 2 is a good coefficient for estimating
714    // video frame timeout.
715    StartStarvationCallback(2 * (presentation_timestamp - current_timestamp));
716  }
717  if (!HasVideoData())
718    RequestVideoData();
719  else
720    DecodeMoreVideo();
721}
722
723void MediaSourcePlayer::DecodeMoreAudio() {
724  DCHECK(!audio_decoder_job_->is_decoding());
725  DCHECK(HasAudioData());
726
727  if (DemuxerStream::kConfigChanged ==
728      received_audio_.access_units[audio_access_unit_index_].status) {
729    // Wait for demuxer ready message.
730    reconfig_audio_decoder_ = true;
731    pending_event_ |= CONFIG_CHANGE_EVENT_PENDING;
732    received_audio_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params();
733    audio_access_unit_index_ = 0;
734    ProcessPendingEvents();
735    return;
736  }
737
738  audio_decoder_job_->Decode(
739      received_audio_.access_units[audio_access_unit_index_],
740      start_time_ticks_, start_presentation_timestamp_,
741      base::Bind(&MediaSourcePlayer::MediaDecoderCallback,
742                 weak_this_.GetWeakPtr(), true));
743}
744
745void MediaSourcePlayer::DecodeMoreVideo() {
746  DVLOG(1) << "DecodeMoreVideo()";
747  DCHECK(!video_decoder_job_->is_decoding());
748  DCHECK(HasVideoData());
749
750  if (DemuxerStream::kConfigChanged ==
751      received_video_.access_units[video_access_unit_index_].status) {
752    // Wait for demuxer ready message.
753    reconfig_video_decoder_ = true;
754    pending_event_ |= CONFIG_CHANGE_EVENT_PENDING;
755    received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params();
756    video_access_unit_index_ = 0;
757    ProcessPendingEvents();
758    return;
759  }
760
761  DVLOG(3) << "VideoDecoderJob::Decode(" << video_access_unit_index_ << ", "
762           << start_time_ticks_.ToInternalValue() << ", "
763           << start_presentation_timestamp_.InMilliseconds() << ")";
764  video_decoder_job_->Decode(
765      received_video_.access_units[video_access_unit_index_],
766      start_time_ticks_, start_presentation_timestamp_,
767      base::Bind(&MediaSourcePlayer::MediaDecoderCallback,
768                 weak_this_.GetWeakPtr(), false));
769}
770
771void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
772  if (is_audio)
773    audio_finished_ = true;
774  else
775    video_finished_ = true;
776
777  if ((!HasAudio() || audio_finished_) && (!HasVideo() || video_finished_)) {
778    playing_ = false;
779    clock_.Pause();
780    start_time_ticks_ = base::TimeTicks();
781    OnPlaybackComplete();
782  }
783}
784
785void MediaSourcePlayer::ClearDecodingData() {
786  DVLOG(1) << "ClearDecodingData()";
787  if (audio_decoder_job_)
788    audio_decoder_job_->Flush();
789  if (video_decoder_job_)
790    video_decoder_job_->Flush();
791  start_time_ticks_ = base::TimeTicks();
792  received_audio_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params();
793  received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params();
794  audio_access_unit_index_ = 0;
795  video_access_unit_index_ = 0;
796  waiting_for_audio_data_ = false;
797  waiting_for_video_data_ = false;
798}
799
800bool MediaSourcePlayer::HasVideo() {
801  return kUnknownVideoCodec != video_codec_;
802}
803
804bool MediaSourcePlayer::HasAudio() {
805  return kUnknownAudioCodec != audio_codec_;
806}
807
808void MediaSourcePlayer::ConfigureAudioDecoderJob() {
809  if (!HasAudio()) {
810    audio_decoder_job_.reset();
811    return;
812  }
813
814  // Create audio decoder job only if config changes.
815  if (audio_decoder_job_ && !reconfig_audio_decoder_)
816    return;
817
818  base::android::ScopedJavaLocalRef<jobject> media_codec;
819  if (is_audio_encrypted_) {
820    if (drm_bridge_) {
821      media_codec = drm_bridge_->GetMediaCrypto();
822      // TODO(qinmin): currently we assume MediaCrypto is available whenever
823      // MediaDrmBridge is constructed. This will change if we want to support
824      // more general uses cases of EME.
825      DCHECK(!media_codec.is_null());
826    } else {
827      // Don't create the decoder job if |drm_bridge_| is not set,
828      // so StartInternal() will not proceed.
829      LOG(INFO) << "MediaDrmBridge is not available when creating decoder "
830                << "for encrypted audio stream.";
831      return;
832    }
833  }
834
835  audio_decoder_job_.reset(AudioDecoderJob::Create(
836      audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
837      audio_extra_data_.size(), media_codec.obj()));
838
839  if (audio_decoder_job_) {
840    SetVolumeInternal();
841    reconfig_audio_decoder_ =  false;
842  }
843}
844
845void MediaSourcePlayer::ConfigureVideoDecoderJob() {
846  if (!HasVideo() || surface_.IsEmpty()) {
847    video_decoder_job_.reset();
848    return;
849  }
850
851  // Create video decoder job only if config changes.
852  if (video_decoder_job_ && !reconfig_video_decoder_)
853    return;
854
855  base::android::ScopedJavaLocalRef<jobject> media_codec;
856  if (is_video_encrypted_) {
857    if (drm_bridge_) {
858      media_codec = drm_bridge_->GetMediaCrypto();
859      DCHECK(!media_codec.is_null());
860    } else {
861      LOG(INFO) << "MediaDrmBridge is not available when creating decoder "
862                << "for encrypted video stream.";
863      return;
864    }
865  }
866
867  // Release the old VideoDecoderJob first so the surface can get released.
868  // Android does not allow 2 MediaCodec instances use the same surface.
869  video_decoder_job_.reset();
870  // Create the new VideoDecoderJob.
871  video_decoder_job_.reset(VideoDecoderJob::Create(
872      video_codec_, gfx::Size(width_, height_), surface_.j_surface().obj(),
873      media_codec.obj()));
874  if (video_decoder_job_)
875    reconfig_video_decoder_ = false;
876
877  // Inform the fullscreen view the player is ready.
878  // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
879  // to inform ContentVideoView.
880  OnMediaMetadataChanged(duration_, width_, height_, true);
881}
882
883void MediaSourcePlayer::OnDecoderStarved() {
884  sync_decoder_jobs_ = true;
885}
886
887void MediaSourcePlayer::StartStarvationCallback(
888    const base::TimeDelta& timeout) {
889  decoder_starvation_callback_.Reset(
890      base::Bind(&MediaSourcePlayer::OnDecoderStarved,
891                 weak_this_.GetWeakPtr()));
892  base::MessageLoop::current()->PostDelayedTask(
893      FROM_HERE, decoder_starvation_callback_.callback(), timeout);
894}
895
896void MediaSourcePlayer::SyncAndStartDecoderJobs() {
897  // For streams with both audio and video, send the request for video too.
898  // However, don't wait for the response so that we won't have lots of
899  // noticeable pauses in the audio. Video will sync with audio by itself.
900  if (HasVideo() && !HasVideoData()) {
901    RequestVideoData();
902    if (!HasAudio())
903      return;
904  }
905  if (HasAudio() && !HasAudioData()) {
906    RequestAudioData();
907    return;
908  }
909  start_time_ticks_ = base::TimeTicks::Now();
910  start_presentation_timestamp_ = GetCurrentTime();
911  if (!clock_.IsPlaying())
912    clock_.Play();
913  if (HasAudioData() && !audio_decoder_job_->is_decoding())
914    DecodeMoreAudio();
915  if (HasVideoData() && !video_decoder_job_->is_decoding())
916    DecodeMoreVideo();
917  sync_decoder_jobs_ = false;
918}
919
920void MediaSourcePlayer::RequestAudioData() {
921  DVLOG(2) << "RequestAudioData()";
922  DCHECK(HasAudio());
923
924  if (waiting_for_audio_data_)
925    return;
926
927  manager()->OnReadFromDemuxer(player_id(), DemuxerStream::AUDIO);
928  received_audio_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params();
929  audio_access_unit_index_ = 0;
930  waiting_for_audio_data_ = true;
931}
932
933void MediaSourcePlayer::RequestVideoData() {
934  DVLOG(2) << "RequestVideoData()";
935  DCHECK(HasVideo());
936  if (waiting_for_video_data_)
937    return;
938
939  manager()->OnReadFromDemuxer(player_id(), DemuxerStream::VIDEO);
940  received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params();
941  video_access_unit_index_ = 0;
942  waiting_for_video_data_ = true;
943}
944
945bool MediaSourcePlayer::HasAudioData() const {
946  return audio_access_unit_index_ < received_audio_.access_units.size();
947}
948
949bool MediaSourcePlayer::HasVideoData() const {
950  return video_access_unit_index_ < received_video_.access_units.size();
951}
952
953void MediaSourcePlayer::SetVolumeInternal() {
954  if (audio_decoder_job_ && volume_ >= 0)
955    audio_decoder_job_.get()->SetVolume(volume_);
956}
957
958}  // namespace media
959