Home | History | Annotate | Download | only in android
      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 <limits>
      8 
      9 #include "base/android/jni_android.h"
     10 #include "base/android/jni_string.h"
     11 #include "base/barrier_closure.h"
     12 #include "base/basictypes.h"
     13 #include "base/bind.h"
     14 #include "base/callback_helpers.h"
     15 #include "base/debug/trace_event.h"
     16 #include "base/logging.h"
     17 #include "base/strings/string_number_conversions.h"
     18 #include "media/base/android/audio_decoder_job.h"
     19 #include "media/base/android/media_drm_bridge.h"
     20 #include "media/base/android/media_player_manager.h"
     21 #include "media/base/android/video_decoder_job.h"
     22 #include "media/base/audio_timestamp_helper.h"
     23 #include "media/base/buffers.h"
     24 
     25 namespace {
     26 
     27 // Use 16bit PCM for audio output. Keep this value in sync with the output
     28 // format we passed to AudioTrack in MediaCodecBridge.
     29 const int kBytesPerAudioOutputSample = 2;
     30 }
     31 
     32 namespace media {
     33 
     34 // static
     35 bool MediaSourcePlayer::IsTypeSupported(
     36     const std::vector<uint8>& scheme_uuid,
     37     const std::string& security_level,
     38     const std::string& container,
     39     const std::vector<std::string>& codecs) {
     40   if (!MediaDrmBridge::IsCryptoSchemeSupported(scheme_uuid, container)) {
     41     DVLOG(1) << "UUID and container '" << container << "' not supported.";
     42     return false;
     43   }
     44 
     45   if (!MediaDrmBridge::IsSecurityLevelSupported(scheme_uuid, security_level)) {
     46     DVLOG(1) << "UUID and security level '" << security_level
     47              << "' not supported.";
     48     return false;
     49   }
     50 
     51   bool is_secure = MediaDrmBridge::IsSecureDecoderRequired(security_level);
     52   for (size_t i = 0; i < codecs.size(); ++i) {
     53     if (!MediaCodecBridge::CanDecode(codecs[i], is_secure)) {
     54       DVLOG(1) << "Codec '" << codecs[i] << "' "
     55                << (is_secure ? "in secure mode " : "") << "not supported.";
     56       return false;
     57     }
     58   }
     59 
     60   return true;
     61 }
     62 
     63 MediaSourcePlayer::MediaSourcePlayer(
     64     int player_id,
     65     MediaPlayerManager* manager,
     66     scoped_ptr<DemuxerAndroid> demuxer)
     67     : MediaPlayerAndroid(player_id, manager),
     68       demuxer_(demuxer.Pass()),
     69       pending_event_(NO_EVENT_PENDING),
     70       width_(0),
     71       height_(0),
     72       audio_codec_(kUnknownAudioCodec),
     73       video_codec_(kUnknownVideoCodec),
     74       num_channels_(0),
     75       sampling_rate_(0),
     76       reached_audio_eos_(false),
     77       reached_video_eos_(false),
     78       playing_(false),
     79       is_audio_encrypted_(false),
     80       is_video_encrypted_(false),
     81       volume_(-1.0),
     82       clock_(&default_tick_clock_),
     83       next_video_data_is_iframe_(true),
     84       doing_browser_seek_(false),
     85       pending_seek_(false),
     86       reconfig_audio_decoder_(false),
     87       reconfig_video_decoder_(false),
     88       weak_this_(this),
     89       drm_bridge_(NULL),
     90       is_waiting_for_key_(false) {
     91   demuxer_->Initialize(this);
     92   clock_.SetMaxTime(base::TimeDelta());
     93 }
     94 
     95 MediaSourcePlayer::~MediaSourcePlayer() {
     96   Release();
     97 }
     98 
     99 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
    100   // For an empty surface, always pass it to the decoder job so that it
    101   // can detach from the current one. Otherwise, don't pass an unprotected
    102   // surface if the video content requires a protected one.
    103   if (!surface.IsEmpty() &&
    104       IsProtectedSurfaceRequired() && !surface.is_protected()) {
    105     return;
    106   }
    107 
    108   surface_ =  surface.Pass();
    109 
    110   // If there is a pending surface change event, just wait for it to be
    111   // processed.
    112   if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
    113     return;
    114 
    115   // Eventual processing of surface change will take care of feeding the new
    116   // video decoder initially with I-frame. See b/8950387.
    117   SetPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
    118 
    119   // If seek is already pending, processing of the pending surface change
    120   // event will occur in OnDemuxerSeekDone().
    121   if (IsEventPending(SEEK_EVENT_PENDING))
    122     return;
    123 
    124   // If video config change is already pending, processing of the pending
    125   // surface change event will occur in OnDemuxerConfigsAvailable().
    126   if (reconfig_video_decoder_ && IsEventPending(CONFIG_CHANGE_EVENT_PENDING))
    127     return;
    128 
    129   // Otherwise we need to trigger pending event processing now.
    130   ProcessPendingEvents();
    131 }
    132 
    133 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
    134     const base::TimeDelta& seek_time) {
    135   DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
    136   DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
    137 
    138   pending_seek_ = false;
    139 
    140   clock_.SetTime(seek_time, seek_time);
    141   if (audio_timestamp_helper_)
    142     audio_timestamp_helper_->SetBaseTimestamp(seek_time);
    143 
    144   if (audio_decoder_job_ && audio_decoder_job_->is_decoding())
    145     audio_decoder_job_->StopDecode();
    146   if (video_decoder_job_ && video_decoder_job_->is_decoding())
    147     video_decoder_job_->StopDecode();
    148 
    149   SetPendingEvent(SEEK_EVENT_PENDING);
    150   ProcessPendingEvents();
    151 }
    152 
    153 void MediaSourcePlayer::BrowserSeekToCurrentTime() {
    154   DVLOG(1) << __FUNCTION__;
    155 
    156   DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
    157   doing_browser_seek_ = true;
    158   ScheduleSeekEventAndStopDecoding(GetCurrentTime());
    159 }
    160 
    161 bool MediaSourcePlayer::Seekable() {
    162   // If the duration TimeDelta, converted to milliseconds from microseconds,
    163   // is >= 2^31, then the media is assumed to be unbounded and unseekable.
    164   // 2^31 is the bound due to java player using 32-bit integer for time
    165   // values at millisecond resolution.
    166   return duration_ <
    167          base::TimeDelta::FromMilliseconds(std::numeric_limits<int32>::max());
    168 }
    169 
    170 void MediaSourcePlayer::Start() {
    171   DVLOG(1) << __FUNCTION__;
    172 
    173   playing_ = true;
    174 
    175   if (IsProtectedSurfaceRequired())
    176     manager()->OnProtectedSurfaceRequested(player_id());
    177 
    178   StartInternal();
    179 }
    180 
    181 void MediaSourcePlayer::Pause(bool is_media_related_action) {
    182   DVLOG(1) << __FUNCTION__;
    183 
    184   // Since decoder jobs have their own thread, decoding is not fully paused
    185   // until all the decoder jobs call MediaDecoderCallback(). It is possible
    186   // that Start() is called while the player is waiting for
    187   // MediaDecoderCallback(). In that case, decoding will continue when
    188   // MediaDecoderCallback() is called.
    189   playing_ = false;
    190   start_time_ticks_ = base::TimeTicks();
    191 }
    192 
    193 bool MediaSourcePlayer::IsPlaying() {
    194   return playing_;
    195 }
    196 
    197 int MediaSourcePlayer::GetVideoWidth() {
    198   return width_;
    199 }
    200 
    201 int MediaSourcePlayer::GetVideoHeight() {
    202   return height_;
    203 }
    204 
    205 void MediaSourcePlayer::SeekTo(const base::TimeDelta& timestamp) {
    206   DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
    207 
    208   if (IsEventPending(SEEK_EVENT_PENDING)) {
    209     DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress";
    210     DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek";
    211 
    212     // There is a browser seek currently in progress to obtain I-frame to feed
    213     // a newly constructed video decoder. Remember this real seek request so
    214     // it can be initiated once OnDemuxerSeekDone() occurs for the browser seek.
    215     pending_seek_ = true;
    216     pending_seek_time_ = timestamp;
    217     return;
    218   }
    219 
    220   doing_browser_seek_ = false;
    221   ScheduleSeekEventAndStopDecoding(timestamp);
    222 }
    223 
    224 base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
    225   return clock_.Elapsed();
    226 }
    227 
    228 base::TimeDelta MediaSourcePlayer::GetDuration() {
    229   return duration_;
    230 }
    231 
    232 void MediaSourcePlayer::Release() {
    233   DVLOG(1) << __FUNCTION__;
    234 
    235   // Allow pending seeks and config changes to survive this Release().
    236   // If previously pending a prefetch done event, or a job was still decoding,
    237   // then at end of Release() we need to ProcessPendingEvents() to process any
    238   // seek or config change that was blocked by the prefetch or decode.
    239   // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
    240   // or drop data received across Release()+Start(). See http://crbug.com/306314
    241   // and http://crbug.com/304234.
    242   bool process_pending_events = false;
    243   process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) ||
    244       (audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
    245       (video_decoder_job_ && video_decoder_job_->is_decoding());
    246 
    247   // Clear all the pending events except seeks and config changes.
    248   pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING);
    249 
    250   audio_decoder_job_.reset();
    251   ResetVideoDecoderJob();
    252 
    253   // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
    254   reconfig_audio_decoder_ = false;
    255   reconfig_video_decoder_ = false;
    256 
    257   // Prevent player restart, including job re-creation attempts.
    258   playing_ = false;
    259 
    260   decoder_starvation_callback_.Cancel();
    261   surface_ = gfx::ScopedJavaSurface();
    262   manager()->ReleaseMediaResources(player_id());
    263   if (process_pending_events) {
    264     DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
    265     ProcessPendingEvents();
    266   }
    267 }
    268 
    269 void MediaSourcePlayer::SetVolume(double volume) {
    270   volume_ = volume;
    271   SetVolumeInternal();
    272 }
    273 
    274 void MediaSourcePlayer::OnKeyAdded() {
    275   DVLOG(1) << __FUNCTION__;
    276   if (!is_waiting_for_key_)
    277     return;
    278 
    279   is_waiting_for_key_ = false;
    280   if (playing_)
    281     StartInternal();
    282 }
    283 
    284 bool MediaSourcePlayer::CanPause() {
    285   return Seekable();
    286 }
    287 
    288 bool MediaSourcePlayer::CanSeekForward() {
    289   return Seekable();
    290 }
    291 
    292 bool MediaSourcePlayer::CanSeekBackward() {
    293   return Seekable();
    294 }
    295 
    296 bool MediaSourcePlayer::IsPlayerReady() {
    297   return audio_decoder_job_ || video_decoder_job_;
    298 }
    299 
    300 void MediaSourcePlayer::StartInternal() {
    301   DVLOG(1) << __FUNCTION__;
    302   // If there are pending events, wait for them finish.
    303   if (pending_event_ != NO_EVENT_PENDING)
    304     return;
    305 
    306   // When we start, we'll have new demuxed data coming in. This new data could
    307   // be clear (not encrypted) or encrypted with different keys. So
    308   // |is_waiting_for_key_| condition may not be true anymore.
    309   is_waiting_for_key_ = false;
    310 
    311   // Create decoder jobs if they are not created
    312   ConfigureAudioDecoderJob();
    313   ConfigureVideoDecoderJob();
    314 
    315   // If one of the decoder job is not ready, do nothing.
    316   if ((HasAudio() && !audio_decoder_job_) ||
    317       (HasVideo() && !video_decoder_job_)) {
    318     return;
    319   }
    320 
    321   SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
    322   ProcessPendingEvents();
    323 }
    324 
    325 void MediaSourcePlayer::OnDemuxerConfigsAvailable(
    326     const DemuxerConfigs& configs) {
    327   DVLOG(1) << __FUNCTION__;
    328   duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms);
    329   clock_.SetDuration(duration_);
    330 
    331   audio_codec_ = configs.audio_codec;
    332   num_channels_ = configs.audio_channels;
    333   sampling_rate_ = configs.audio_sampling_rate;
    334   is_audio_encrypted_ = configs.is_audio_encrypted;
    335   audio_extra_data_ = configs.audio_extra_data;
    336   if (HasAudio()) {
    337     DCHECK_GT(num_channels_, 0);
    338     audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_));
    339     audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime());
    340   } else {
    341     audio_timestamp_helper_.reset();
    342   }
    343 
    344   video_codec_ = configs.video_codec;
    345   width_ = configs.video_size.width();
    346   height_ = configs.video_size.height();
    347   is_video_encrypted_ = configs.is_video_encrypted;
    348 
    349   manager()->OnMediaMetadataChanged(
    350       player_id(), duration_, width_, height_, true);
    351 
    352   if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
    353     if (reconfig_audio_decoder_)
    354       ConfigureAudioDecoderJob();
    355 
    356     if (reconfig_video_decoder_)
    357       ConfigureVideoDecoderJob();
    358 
    359     ClearPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
    360 
    361     // Resume decoding after the config change if we are still playing.
    362     if (playing_)
    363       StartInternal();
    364   }
    365 }
    366 
    367 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
    368   DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
    369   DCHECK_LT(0u, data.access_units.size());
    370   if (data.type == DemuxerStream::AUDIO && audio_decoder_job_) {
    371     audio_decoder_job_->OnDataReceived(data);
    372   } else if (data.type == DemuxerStream::VIDEO) {
    373     next_video_data_is_iframe_ = false;
    374     if (video_decoder_job_)
    375       video_decoder_job_->OnDataReceived(data);
    376   }
    377 }
    378 
    379 void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
    380   duration_ = duration;
    381   clock_.SetDuration(duration_);
    382 }
    383 
    384 base::android::ScopedJavaLocalRef<jobject> MediaSourcePlayer::GetMediaCrypto() {
    385   base::android::ScopedJavaLocalRef<jobject> media_crypto;
    386   if (drm_bridge_)
    387     media_crypto = drm_bridge_->GetMediaCrypto();
    388   return media_crypto;
    389 }
    390 
    391 void MediaSourcePlayer::OnMediaCryptoReady() {
    392   DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
    393   drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
    394 
    395   if (playing_)
    396     StartInternal();
    397 }
    398 
    399 void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) {
    400   // Currently we don't support DRM change during the middle of playback, even
    401   // if the player is paused.
    402   // TODO(qinmin): support DRM change after playback has started.
    403   // http://crbug.com/253792.
    404   if (GetCurrentTime() > base::TimeDelta()) {
    405     VLOG(0) << "Setting DRM bridge after playback has started. "
    406             << "This is not well supported!";
    407   }
    408 
    409   drm_bridge_ = drm_bridge;
    410 
    411   if (drm_bridge_->GetMediaCrypto().is_null()) {
    412     drm_bridge_->SetMediaCryptoReadyCB(base::Bind(
    413         &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr()));
    414     return;
    415   }
    416 
    417   if (playing_)
    418     StartInternal();
    419 }
    420 
    421 void MediaSourcePlayer::OnDemuxerSeekDone(
    422     const base::TimeDelta& actual_browser_seek_time) {
    423   DVLOG(1) << __FUNCTION__;
    424 
    425   ClearPendingEvent(SEEK_EVENT_PENDING);
    426   if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
    427     ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
    428 
    429   next_video_data_is_iframe_ = true;
    430 
    431   if (pending_seek_) {
    432     DVLOG(1) << __FUNCTION__ << "processing pending seek";
    433     DCHECK(doing_browser_seek_);
    434     pending_seek_ = false;
    435     SeekTo(pending_seek_time_);
    436     return;
    437   }
    438 
    439   // It is possible that a browser seek to I-frame had to seek to a buffered
    440   // I-frame later than the requested one due to data removal or GC. Update
    441   // player clock to the actual seek target.
    442   if (doing_browser_seek_) {
    443     DCHECK(actual_browser_seek_time != kNoTimestamp());
    444     // A browser seek must not jump into the past. Ideally, it seeks to the
    445     // requested time, but it might jump into the future.
    446     DCHECK(actual_browser_seek_time >= GetCurrentTime());
    447     DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
    448              << actual_browser_seek_time.InSecondsF();
    449     clock_.SetTime(actual_browser_seek_time, actual_browser_seek_time);
    450     if (audio_timestamp_helper_)
    451       audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time);
    452   }
    453 
    454   reached_audio_eos_ = false;
    455   reached_video_eos_ = false;
    456 
    457   base::TimeDelta current_time = GetCurrentTime();
    458   // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
    459   // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
    460   // is calculated from decoder output, while preroll relies on the access
    461   // unit's timestamp. There are some differences between the two.
    462   preroll_timestamp_ = current_time;
    463   if (audio_decoder_job_)
    464     audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
    465   if (video_decoder_job_)
    466     video_decoder_job_->BeginPrerolling(preroll_timestamp_);
    467 
    468   if (!doing_browser_seek_)
    469     manager()->OnSeekComplete(player_id(), current_time);
    470 
    471   ProcessPendingEvents();
    472 }
    473 
    474 void MediaSourcePlayer::UpdateTimestamps(
    475     const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
    476   base::TimeDelta new_max_time = presentation_timestamp;
    477 
    478   if (audio_output_bytes > 0) {
    479     audio_timestamp_helper_->AddFrames(
    480         audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
    481     new_max_time = audio_timestamp_helper_->GetTimestamp();
    482   }
    483 
    484   clock_.SetMaxTime(new_max_time);
    485   manager()->OnTimeUpdate(player_id(), GetCurrentTime());
    486 }
    487 
    488 void MediaSourcePlayer::ProcessPendingEvents() {
    489   DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
    490   // Wait for all the decoding jobs to finish before processing pending tasks.
    491   if (video_decoder_job_ && video_decoder_job_->is_decoding()) {
    492     DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
    493     return;
    494   }
    495 
    496   if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) {
    497     DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
    498     return;
    499   }
    500 
    501   if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
    502     DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
    503     return;
    504   }
    505 
    506   if (IsEventPending(SEEK_EVENT_PENDING)) {
    507     DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
    508     ClearDecodingData();
    509     demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
    510     return;
    511   }
    512 
    513   start_time_ticks_ = base::TimeTicks();
    514   if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
    515     DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT.";
    516     DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
    517     demuxer_->RequestDemuxerConfigs();
    518     return;
    519   }
    520 
    521   if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) {
    522     DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT.";
    523     // Setting a new surface will require a new MediaCodec to be created.
    524     ResetVideoDecoderJob();
    525     ConfigureVideoDecoderJob();
    526 
    527     // Return early if we can't successfully configure a new video decoder job
    528     // yet.
    529     if (HasVideo() && !video_decoder_job_)
    530       return;
    531   }
    532 
    533   if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
    534     DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
    535     DCHECK(audio_decoder_job_ || AudioFinished());
    536     DCHECK(video_decoder_job_ || VideoFinished());
    537 
    538     int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
    539 
    540     // It is possible that all streams have finished decode, yet starvation
    541     // occurred during the last stream's EOS decode. In this case, prefetch is a
    542     // no-op.
    543     ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
    544     if (count == 0)
    545       return;
    546 
    547     SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
    548     base::Closure barrier = BarrierClosure(count, base::Bind(
    549         &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr()));
    550 
    551     if (!AudioFinished())
    552       audio_decoder_job_->Prefetch(barrier);
    553 
    554     if (!VideoFinished())
    555       video_decoder_job_->Prefetch(barrier);
    556 
    557     return;
    558   }
    559 
    560   DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
    561 
    562   // Now that all pending events have been handled, resume decoding if we are
    563   // still playing.
    564   if (playing_)
    565     StartInternal();
    566 }
    567 
    568 void MediaSourcePlayer::MediaDecoderCallback(
    569     bool is_audio, MediaCodecStatus status,
    570     const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
    571   DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
    572 
    573   // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed.
    574   if (is_audio) {
    575     TRACE_EVENT_ASYNC_END1("media",
    576                            "MediaSourcePlayer::DecodeMoreAudio",
    577                            audio_decoder_job_.get(),
    578                            "MediaCodecStatus",
    579                            base::IntToString(status));
    580   } else {
    581     TRACE_EVENT_ASYNC_END1("media",
    582                            "MediaSourcePlayer::DecodeMoreVideo",
    583                            video_decoder_job_.get(),
    584                            "MediaCodecStatus",
    585                            base::IntToString(status));
    586   }
    587 
    588   // Let tests hook the completion of this decode cycle.
    589   if (!decode_callback_for_testing_.is_null())
    590     base::ResetAndReturn(&decode_callback_for_testing_).Run();
    591 
    592   bool is_clock_manager = is_audio || !HasAudio();
    593 
    594   if (is_clock_manager)
    595     decoder_starvation_callback_.Cancel();
    596 
    597   if (status == MEDIA_CODEC_ERROR) {
    598     DVLOG(1) << __FUNCTION__ << " : decode error";
    599     Release();
    600     manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
    601     return;
    602   }
    603 
    604   DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
    605 
    606   // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
    607   // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
    608   // any other pending events only after handling EOS detection.
    609   if (IsEventPending(SEEK_EVENT_PENDING)) {
    610     ProcessPendingEvents();
    611     return;
    612   }
    613 
    614   if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
    615     PlaybackCompleted(is_audio);
    616 
    617   if (pending_event_ != NO_EVENT_PENDING) {
    618     ProcessPendingEvents();
    619     return;
    620   }
    621 
    622   if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
    623     return;
    624 
    625   if (status == MEDIA_CODEC_OK && is_clock_manager &&
    626       presentation_timestamp != kNoTimestamp()) {
    627     UpdateTimestamps(presentation_timestamp, audio_output_bytes);
    628   }
    629 
    630   if (!playing_) {
    631     if (is_clock_manager)
    632       clock_.Pause();
    633     return;
    634   }
    635 
    636   if (status == MEDIA_CODEC_NO_KEY) {
    637     is_waiting_for_key_ = true;
    638     return;
    639   }
    640 
    641   // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
    642   // in the middle of a seek or stop event and needs to wait for the IPCs to
    643   // come.
    644   if (status == MEDIA_CODEC_STOPPED)
    645     return;
    646 
    647   if (is_clock_manager) {
    648     // If we have a valid timestamp, start the starvation callback. Otherwise,
    649     // reset the |start_time_ticks_| so that the next frame will not suffer
    650     // from the decoding delay caused by the current frame.
    651     if (presentation_timestamp != kNoTimestamp())
    652       StartStarvationCallback(presentation_timestamp);
    653     else
    654       start_time_ticks_ = base::TimeTicks::Now();
    655   }
    656 
    657   if (is_audio) {
    658     DecodeMoreAudio();
    659     return;
    660   }
    661 
    662   DecodeMoreVideo();
    663 }
    664 
    665 void MediaSourcePlayer::DecodeMoreAudio() {
    666   DVLOG(1) << __FUNCTION__;
    667   DCHECK(!audio_decoder_job_->is_decoding());
    668   DCHECK(!AudioFinished());
    669 
    670   if (audio_decoder_job_->Decode(
    671           start_time_ticks_, start_presentation_timestamp_, base::Bind(
    672               &MediaSourcePlayer::MediaDecoderCallback,
    673               weak_this_.GetWeakPtr(), true))) {
    674     TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
    675                              audio_decoder_job_.get());
    676     return;
    677   }
    678 
    679   // Failed to start the next decode.
    680   // Wait for demuxer ready message.
    681   DCHECK(!reconfig_audio_decoder_);
    682   reconfig_audio_decoder_ = true;
    683 
    684   // Config change may have just been detected on the other stream. If so,
    685   // don't send a duplicate demuxer config request.
    686   if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
    687     DCHECK(reconfig_video_decoder_);
    688     return;
    689   }
    690 
    691   SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
    692   ProcessPendingEvents();
    693 }
    694 
    695 void MediaSourcePlayer::DecodeMoreVideo() {
    696   DVLOG(1) << __FUNCTION__;
    697   DCHECK(!video_decoder_job_->is_decoding());
    698   DCHECK(!VideoFinished());
    699 
    700   if (video_decoder_job_->Decode(
    701           start_time_ticks_, start_presentation_timestamp_, base::Bind(
    702               &MediaSourcePlayer::MediaDecoderCallback,
    703               weak_this_.GetWeakPtr(), false))) {
    704     TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
    705                              video_decoder_job_.get());
    706     return;
    707   }
    708 
    709   // Failed to start the next decode.
    710   // Wait for demuxer ready message.
    711 
    712   // After this detection of video config change, next video data received
    713   // will begin with I-frame.
    714   next_video_data_is_iframe_ = true;
    715 
    716   DCHECK(!reconfig_video_decoder_);
    717   reconfig_video_decoder_ = true;
    718 
    719   // Config change may have just been detected on the other stream. If so,
    720   // don't send a duplicate demuxer config request.
    721   if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
    722     DCHECK(reconfig_audio_decoder_);
    723     return;
    724   }
    725 
    726   SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
    727   ProcessPendingEvents();
    728 }
    729 
    730 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
    731   DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
    732   if (is_audio)
    733     reached_audio_eos_ = true;
    734   else
    735     reached_video_eos_ = true;
    736 
    737   if (AudioFinished() && VideoFinished()) {
    738     playing_ = false;
    739     clock_.Pause();
    740     start_time_ticks_ = base::TimeTicks();
    741     manager()->OnPlaybackComplete(player_id());
    742   }
    743 }
    744 
    745 void MediaSourcePlayer::ClearDecodingData() {
    746   DVLOG(1) << __FUNCTION__;
    747   if (audio_decoder_job_)
    748     audio_decoder_job_->Flush();
    749   if (video_decoder_job_)
    750     video_decoder_job_->Flush();
    751   start_time_ticks_ = base::TimeTicks();
    752 }
    753 
    754 bool MediaSourcePlayer::HasVideo() {
    755   return kUnknownVideoCodec != video_codec_;
    756 }
    757 
    758 bool MediaSourcePlayer::HasAudio() {
    759   return kUnknownAudioCodec != audio_codec_;
    760 }
    761 
    762 bool MediaSourcePlayer::AudioFinished() {
    763   return reached_audio_eos_ || !HasAudio();
    764 }
    765 
    766 bool MediaSourcePlayer::VideoFinished() {
    767   return reached_video_eos_ || !HasVideo();
    768 }
    769 
    770 void MediaSourcePlayer::ConfigureAudioDecoderJob() {
    771   if (!HasAudio()) {
    772     audio_decoder_job_.reset();
    773     return;
    774   }
    775 
    776   // Create audio decoder job only if config changes.
    777   if (audio_decoder_job_ && !reconfig_audio_decoder_)
    778     return;
    779 
    780   base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
    781   if (is_audio_encrypted_ && media_crypto.is_null())
    782     return;
    783 
    784   DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
    785 
    786   DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job";
    787 
    788   audio_decoder_job_.reset(AudioDecoderJob::Create(
    789       audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
    790       audio_extra_data_.size(), media_crypto.obj(),
    791       base::Bind(&DemuxerAndroid::RequestDemuxerData,
    792                  base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
    793 
    794   if (audio_decoder_job_) {
    795     SetVolumeInternal();
    796     audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
    797     reconfig_audio_decoder_ =  false;
    798   }
    799 }
    800 
    801 void MediaSourcePlayer::ResetVideoDecoderJob() {
    802   video_decoder_job_.reset();
    803 
    804   // Any eventual video decoder job re-creation will use the current |surface_|.
    805   if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
    806     ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
    807 }
    808 
    809 void MediaSourcePlayer::ConfigureVideoDecoderJob() {
    810   if (!HasVideo() || surface_.IsEmpty()) {
    811     ResetVideoDecoderJob();
    812     return;
    813   }
    814 
    815   // Create video decoder job only if config changes or we don't have a job.
    816   if (video_decoder_job_ && !reconfig_video_decoder_) {
    817     DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
    818     return;
    819   }
    820 
    821   DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
    822 
    823   if (reconfig_video_decoder_) {
    824     // No hack browser seek should be required. I-Frame must be next.
    825     DCHECK(next_video_data_is_iframe_) << "Received video data between "
    826         << "detecting video config change and reconfiguring video decoder";
    827   }
    828 
    829   // If uncertain that video I-frame data is next and there is no seek already
    830   // in process, request browser demuxer seek so the new decoder will decode
    831   // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387.
    832   // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and
    833   // continue from here.
    834   // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
    835   // since last keyframe. See http://crbug.com/304234.
    836   if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) {
    837     BrowserSeekToCurrentTime();
    838     return;
    839   }
    840 
    841   // Release the old VideoDecoderJob first so the surface can get released.
    842   // Android does not allow 2 MediaCodec instances use the same surface.
    843   ResetVideoDecoderJob();
    844 
    845   base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
    846   if (is_video_encrypted_ && media_crypto.is_null())
    847     return;
    848 
    849   DVLOG(1) << __FUNCTION__ << " : creating new video decoder job";
    850 
    851   // Create the new VideoDecoderJob.
    852   bool is_secure = IsProtectedSurfaceRequired();
    853   video_decoder_job_.reset(
    854       VideoDecoderJob::Create(video_codec_,
    855                               is_secure,
    856                               gfx::Size(width_, height_),
    857                               surface_.j_surface().obj(),
    858                               media_crypto.obj(),
    859                               base::Bind(&DemuxerAndroid::RequestDemuxerData,
    860                                          base::Unretained(demuxer_.get()),
    861                                          DemuxerStream::VIDEO)));
    862   if (!video_decoder_job_)
    863     return;
    864 
    865   video_decoder_job_->BeginPrerolling(preroll_timestamp_);
    866   reconfig_video_decoder_ = false;
    867 
    868   // Inform the fullscreen view the player is ready.
    869   // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
    870   // to inform ContentVideoView.
    871   manager()->OnMediaMetadataChanged(
    872       player_id(), duration_, width_, height_, true);
    873 }
    874 
    875 void MediaSourcePlayer::OnDecoderStarved() {
    876   DVLOG(1) << __FUNCTION__;
    877   SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
    878   ProcessPendingEvents();
    879 }
    880 
    881 void MediaSourcePlayer::StartStarvationCallback(
    882     const base::TimeDelta& presentation_timestamp) {
    883   // 20ms was chosen because it is the typical size of a compressed audio frame.
    884   // Anything smaller than this would likely cause unnecessary cycling in and
    885   // out of the prefetch state.
    886   const base::TimeDelta kMinStarvationTimeout =
    887       base::TimeDelta::FromMilliseconds(20);
    888 
    889   base::TimeDelta current_timestamp = GetCurrentTime();
    890   base::TimeDelta timeout;
    891   if (HasAudio()) {
    892     timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp;
    893   } else {
    894     DCHECK(current_timestamp <= presentation_timestamp);
    895 
    896     // For video only streams, fps can be estimated from the difference
    897     // between the previous and current presentation timestamps. The
    898     // previous presentation timestamp is equal to current_timestamp.
    899     // TODO(qinmin): determine whether 2 is a good coefficient for estimating
    900     // video frame timeout.
    901     timeout = 2 * (presentation_timestamp - current_timestamp);
    902   }
    903 
    904   timeout = std::max(timeout, kMinStarvationTimeout);
    905 
    906   decoder_starvation_callback_.Reset(
    907       base::Bind(&MediaSourcePlayer::OnDecoderStarved,
    908                  weak_this_.GetWeakPtr()));
    909   base::MessageLoop::current()->PostDelayedTask(
    910       FROM_HERE, decoder_starvation_callback_.callback(), timeout);
    911 }
    912 
    913 void MediaSourcePlayer::SetVolumeInternal() {
    914   if (audio_decoder_job_ && volume_ >= 0)
    915     audio_decoder_job_->SetVolume(volume_);
    916 }
    917 
    918 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
    919   return is_video_encrypted_ &&
    920       drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
    921 }
    922 
    923 void MediaSourcePlayer::OnPrefetchDone() {
    924   DVLOG(1) << __FUNCTION__;
    925   DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
    926   DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
    927 
    928   // A previously posted OnPrefetchDone() could race against a Release(). If
    929   // Release() won the race, we should no longer have decoder jobs.
    930   // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
    931   // or drop data received across Release()+Start(). See http://crbug.com/306314
    932   // and http://crbug.com/304234.
    933   if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
    934     DVLOG(1) << __FUNCTION__ << " : aborting";
    935     DCHECK(!audio_decoder_job_ && !video_decoder_job_);
    936     return;
    937   }
    938 
    939   ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
    940 
    941   if (pending_event_ != NO_EVENT_PENDING) {
    942     ProcessPendingEvents();
    943     return;
    944   }
    945 
    946   start_time_ticks_ = base::TimeTicks::Now();
    947   start_presentation_timestamp_ = GetCurrentTime();
    948   if (!clock_.IsPlaying())
    949     clock_.Play();
    950 
    951   if (!AudioFinished())
    952     DecodeMoreAudio();
    953 
    954   if (!VideoFinished())
    955     DecodeMoreVideo();
    956 }
    957 
    958 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
    959   static const char* kPendingEventNames[] = {
    960     "SEEK",
    961     "SURFACE_CHANGE",
    962     "CONFIG_CHANGE",
    963     "PREFETCH_REQUEST",
    964     "PREFETCH_DONE",
    965   };
    966 
    967   int mask = 1;
    968   for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) {
    969     if (event & mask)
    970       return kPendingEventNames[i];
    971   }
    972 
    973   return "UNKNOWN";
    974 }
    975 
    976 bool MediaSourcePlayer::IsEventPending(PendingEventFlags event) const {
    977   return pending_event_ & event;
    978 }
    979 
    980 void MediaSourcePlayer::SetPendingEvent(PendingEventFlags event) {
    981   DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
    982   DCHECK_NE(event, NO_EVENT_PENDING);
    983   DCHECK(!IsEventPending(event));
    984 
    985   pending_event_ |= event;
    986 }
    987 
    988 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
    989   DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
    990   DCHECK_NE(event, NO_EVENT_PENDING);
    991   DCHECK(IsEventPending(event)) << GetEventName(event);
    992 
    993   pending_event_ &= ~event;
    994 }
    995 
    996 }  // namespace media
    997