media_source_player.cc revision f2477e01787aa58f445919b809d89e252beef54f
190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/base/android/media_source_player.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <limits>
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/android/jni_android.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/android/jni_string.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/barrier_closure.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/basictypes.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h"
140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/callback_helpers.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/debug/trace_event.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/base/android/audio_decoder_job.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/base/android/media_drm_bridge.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/base/android/media_player_manager.h"
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/base/android/video_decoder_job.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/base/audio_timestamp_helper.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "media/base/buffers.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use 16bit PCM for audio output. Keep this value in sync with the output
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// format we passed to AudioTrack in MediaCodecBridge.
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kBytesPerAudioOutputSample = 2;
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media {
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MediaSourcePlayer::IsTypeSupported(
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::vector<uint8>& scheme_uuid,
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& security_level,
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& container,
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::vector<std::string>& codecs) {
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!MediaDrmBridge::IsCryptoSchemeSupported(scheme_uuid, container)) {
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << "UUID and container '" << container << "' not supported.";
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!MediaDrmBridge::IsSecurityLevelSupported(scheme_uuid, security_level)) {
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << "UUID and security level '" << security_level
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)             << "' not supported.";
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool is_secure = MediaDrmBridge::IsSecureDecoderRequired(security_level);
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < codecs.size(); ++i) {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!MediaCodecBridge::CanDecode(codecs[i], is_secure)) {
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DVLOG(1) << "Codec '" << codecs[i] << "' "
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               << (is_secure ? "in secure mode " : "") << "not supported.";
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return false;
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaSourcePlayer::MediaSourcePlayer(
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int player_id,
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    MediaPlayerManager* manager,
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<DemuxerAndroid> demuxer)
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : MediaPlayerAndroid(player_id, manager),
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      demuxer_(demuxer.Pass()),
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      pending_event_(NO_EVENT_PENDING),
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      width_(0),
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      height_(0),
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      audio_codec_(kUnknownAudioCodec),
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      video_codec_(kUnknownVideoCodec),
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      num_channels_(0),
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sampling_rate_(0),
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      audio_finished_(true),
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      video_finished_(true),
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      playing_(false),
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_audio_encrypted_(false),
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_video_encrypted_(false),
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      volume_(-1.0),
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      clock_(&default_tick_clock_),
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      next_video_data_is_iframe_(true),
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      doing_browser_seek_(false),
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_seek_(false),
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      reconfig_audio_decoder_(false),
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      reconfig_video_decoder_(false),
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      weak_this_(this),
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      drm_bridge_(NULL),
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      is_waiting_for_key_(false) {
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  demuxer_->Initialize(this);
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  clock_.SetMaxTime(base::TimeDelta());
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaSourcePlayer::~MediaSourcePlayer() {
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Release();
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // For an empty surface, always pass it to the decoder job so that it
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // can detach from the current one. Otherwise, don't pass an unprotected
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // surface if the video content requires a protected one.
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!surface.IsEmpty() &&
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      IsProtectedSurfaceRequired() && !surface.is_protected()) {
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  surface_ =  surface.Pass();
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If there is a pending surface change event, just wait for it to be
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // processed.
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Eventual processing of surface change will take care of feeding the new
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // video decoder initially with I-frame. See b/8950387.
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SetPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If seek is already pending, processing of the pending surface change
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // event will occur in OnDemuxerSeekDone().
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING))
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If video config change is already pending, processing of the pending
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // surface change event will occur in OnDemuxerConfigsAvailable().
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (reconfig_video_decoder_ && IsEventPending(CONFIG_CHANGE_EVENT_PENDING))
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Otherwise we need to trigger pending event processing now.
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ProcessPendingEvents();
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::TimeDelta& seek_time) {
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_seek_ = false;
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  clock_.SetTime(seek_time, seek_time);
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (audio_timestamp_helper_)
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    audio_timestamp_helper_->SetBaseTimestamp(seek_time);
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (audio_decoder_job_ && audio_decoder_job_->is_decoding())
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->StopDecode();
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (video_decoder_job_ && video_decoder_job_->is_decoding())
147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    video_decoder_job_->StopDecode();
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(SEEK_EVENT_PENDING);
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessPendingEvents();
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::BrowserSeekToCurrentTime() {
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  doing_browser_seek_ = true;
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScheduleSeekEventAndStopDecoding(GetCurrentTime());
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MediaSourcePlayer::Seekable() {
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the duration TimeDelta, converted to milliseconds from microseconds,
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is >= 2^31, then the media is assumed to be unbounded and unseekable.
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // 2^31 is the bound due to java player using 32-bit integer for time
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // values at millisecond resolution.
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return duration_ <
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         base::TimeDelta::FromMilliseconds(std::numeric_limits<int32>::max());
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::Start() {
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  playing_ = true;
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsProtectedSurfaceRequired())
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    manager()->OnProtectedSurfaceRequested(player_id());
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StartInternal();
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaSourcePlayer::Pause(bool is_media_related_action) {
182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Since decoder jobs have their own thread, decoding is not fully paused
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // until all the decoder jobs call MediaDecoderCallback(). It is possible
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // that Start() is called while the player is waiting for
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MediaDecoderCallback(). In that case, decoding will continue when
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MediaDecoderCallback() is called.
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  playing_ = false;
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::IsPlaying() {
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return playing_;
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int MediaSourcePlayer::GetVideoWidth() {
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return width_;
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int MediaSourcePlayer::GetVideoHeight() {
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return height_;
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourcePlayer::SeekTo(const base::TimeDelta& timestamp) {
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress";
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek";
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // There is a browser seek currently in progress to obtain I-frame to feed
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // a newly constructed video decoder. Remember this real seek request so
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // it can be initiated once OnDemuxerSeekDone() occurs for the browser seek.
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_seek_ = true;
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_seek_time_ = timestamp;
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  doing_browser_seek_ = false;
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScheduleSeekEventAndStopDecoding(timestamp);
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return clock_.Elapsed();
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::TimeDelta MediaSourcePlayer::GetDuration() {
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return duration_;
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::Release() {
233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Allow pending seeks and config changes to survive this Release().
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If previously pending a prefetch done event, or a job was still decoding,
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // then at end of Release() we need to ProcessPendingEvents() to process any
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // seek or config change that was blocked by the prefetch or decode.
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // or drop data received across Release()+Start(). See http://crbug.com/306314
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // and http://crbug.com/304234.
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool process_pending_events = false;
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  process_pending_events = IsEventPending(PREFETCH_DONE_EVENT_PENDING) ||
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      (audio_decoder_job_ && audio_decoder_job_->is_decoding()) ||
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      (video_decoder_job_ && video_decoder_job_->is_decoding());
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Clear all the pending events except seeks and config changes.
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  pending_event_ &= (SEEK_EVENT_PENDING | CONFIG_CHANGE_EVENT_PENDING);
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  audio_decoder_job_.reset();
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResetVideoDecoderJob();
2520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Prevent job re-creation attempts in OnDemuxerConfigsAvailable()
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  reconfig_audio_decoder_ = false;
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  reconfig_video_decoder_ = false;
2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Prevent player restart, including job re-creation attempts.
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  playing_ = false;
2590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  decoder_starvation_callback_.Cancel();
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  surface_ = gfx::ScopedJavaSurface();
26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->ReleaseMediaResources(player_id());
2630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (process_pending_events) {
2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ProcessPendingEvents();
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MediaSourcePlayer::SetVolume(double volume) {
270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  volume_ = volume;
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetVolumeInternal();
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnKeyAdded() {
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!is_waiting_for_key_)
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  is_waiting_for_key_ = false;
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (playing_)
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    StartInternal();
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::CanPause() {
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return Seekable();
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::CanSeekForward() {
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return Seekable();
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::CanSeekBackward() {
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return Seekable();
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::IsPlayerReady() {
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return audio_decoder_job_ || video_decoder_job_;
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::StartInternal() {
301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If there are pending events, wait for them finish.
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING)
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // When we start, we'll have new demuxed data coming in. This new data could
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // be clear (not encrypted) or encrypted with different keys. So
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |is_waiting_for_key_| condition may not be true anymore.
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  is_waiting_for_key_ = false;
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Create decoder jobs if they are not created
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ConfigureAudioDecoderJob();
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ConfigureVideoDecoderJob();
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If one of the decoder job is not ready, do nothing.
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if ((HasAudio() && !audio_decoder_job_) ||
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (HasVideo() && !video_decoder_job_)) {
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_finished_ = false;
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  video_finished_ = false;
323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerConfigsAvailable(
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const DemuxerConfigs& configs) {
329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms);
3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  clock_.SetDuration(duration_);
3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  audio_codec_ = configs.audio_codec;
334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  num_channels_ = configs.audio_channels;
335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  sampling_rate_ = configs.audio_sampling_rate;
336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_audio_encrypted_ = configs.is_audio_encrypted;
337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  audio_extra_data_ = configs.audio_extra_data;
3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (HasAudio()) {
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK_GT(num_channels_, 0);
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_));
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime());
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_.reset();
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  video_codec_ = configs.video_codec;
347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  width_ = configs.video_size.width();
348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  height_ = configs.video_size.height();
349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_video_encrypted_ = configs.is_video_encrypted;
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->OnMediaMetadataChanged(
35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      player_id(), duration_, width_, height_, true);
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (reconfig_audio_decoder_)
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ConfigureAudioDecoderJob();
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (reconfig_video_decoder_)
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ConfigureVideoDecoderJob();
360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ClearPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Resume decoding after the config change if we are still playing.
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (playing_)
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      StartInternal();
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_LT(0u, data.access_units.size());
3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (data.type == DemuxerStream::AUDIO && audio_decoder_job_) {
373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->OnDataReceived(data);
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (data.type == DemuxerStream::VIDEO) {
3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    next_video_data_is_iframe_ = false;
3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (video_decoder_job_)
3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      video_decoder_job_->OnDataReceived(data);
3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  duration_ = duration;
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  clock_.SetDuration(duration_);
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)base::android::ScopedJavaLocalRef<jobject> MediaSourcePlayer::GetMediaCrypto() {
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> media_crypto;
388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (drm_bridge_)
389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    media_crypto = drm_bridge_->GetMediaCrypto();
390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return media_crypto;
391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::OnMediaCryptoReady() {
394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (playing_)
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    StartInternal();
399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) {
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Currently we don't support DRM change during the middle of playback, even
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // if the player is paused.
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(qinmin): support DRM change after playback has started.
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://crbug.com/253792.
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (GetCurrentTime() > base::TimeDelta()) {
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(0) << "Setting DRM bridge after playback has started. "
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << "This is not well supported!";
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drm_bridge_ = drm_bridge;
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (drm_bridge_->GetMediaCrypto().is_null()) {
414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    drm_bridge_->SetMediaCryptoReadyCB(base::Bind(
415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr()));
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (playing_)
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    StartInternal();
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::OnDemuxerSeekDone(
4241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::TimeDelta& actual_browser_seek_time) {
42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ClearPendingEvent(SEEK_EVENT_PENDING);
4281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  next_video_data_is_iframe_ = true;
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (pending_seek_) {
4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << "processing pending seek";
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(doing_browser_seek_);
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_seek_ = false;
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SeekTo(pending_seek_time_);
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // It is possible that a browser seek to I-frame had to seek to a buffered
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // I-frame later than the requested one due to data removal or GC. Update
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // player clock to the actual seek target.
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (doing_browser_seek_) {
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(actual_browser_seek_time != kNoTimestamp());
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // A browser seek must not jump into the past. Ideally, it seeks to the
4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // requested time, but it might jump into the future.
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(actual_browser_seek_time >= GetCurrentTime());
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             << actual_browser_seek_time.InSecondsF();
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clock_.SetTime(actual_browser_seek_time, actual_browser_seek_time);
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (audio_timestamp_helper_)
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time);
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeDelta current_time = GetCurrentTime();
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // is calculated from decoder output, while preroll relies on the access
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unit's timestamp. There are some differences between the two.
4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  preroll_timestamp_ = current_time;
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (audio_decoder_job_)
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (video_decoder_job_)
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    video_decoder_job_->BeginPrerolling(preroll_timestamp_);
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!doing_browser_seek_)
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    manager()->OnSeekComplete(player_id(), current_time);
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessPendingEvents();
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::UpdateTimestamps(
472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
47358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta new_max_time = presentation_timestamp;
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (audio_output_bytes > 0) {
4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_->AddFrames(
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    new_max_time = audio_timestamp_helper_->GetTimestamp();
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  clock_.SetMaxTime(new_max_time);
48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->OnTimeUpdate(player_id(), GetCurrentTime());
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::ProcessPendingEvents() {
48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Wait for all the decoding jobs to finish before processing pending tasks.
48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (video_decoder_job_ && video_decoder_job_->is_decoding()) {
48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
49058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
49158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
49258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
49358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) {
49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
50468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ClearDecodingData();
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
511424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
512424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT.";
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    demuxer_->RequestDemuxerConfigs();
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) {
519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT.";
5201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Setting a new surface will require a new MediaCodec to be created.
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResetVideoDecoderJob();
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ConfigureVideoDecoderJob();
5231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Return early if we can't successfully configure a new video decoder job
5251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // yet, except continue processing other pending events if |surface_| is
5261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // empty.
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (HasVideo() && !video_decoder_job_ && !surface_.IsEmpty())
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return;
529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
530424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int count = (audio_decoder_job_ ? 1 : 0) + (video_decoder_job_ ? 1 : 0);
534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    base::Closure barrier = BarrierClosure(count, base::Bind(
536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr()));
537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
538424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (audio_decoder_job_)
539424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      audio_decoder_job_->Prefetch(barrier);
540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (video_decoder_job_)
542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      video_decoder_job_->Prefetch(barrier);
543424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
549424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Now that all pending events have been handled, resume decoding if we are
552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // still playing.
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (playing_)
554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    StartInternal();
55590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::MediaDecoderCallback(
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool is_audio, MediaCodecStatus status,
559ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
56058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed.
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_audio) {
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_END1("media",
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaSourcePlayer::DecodeMoreAudio",
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           audio_decoder_job_.get(),
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaCodecStatus",
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           base::IntToString(status));
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_END1("media",
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaSourcePlayer::DecodeMoreVideo",
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           video_decoder_job_.get(),
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaCodecStatus",
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           base::IntToString(status));
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Let tests hook the completion of this decode cycle.
5780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!decode_callback_for_testing_.is_null())
5790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::ResetAndReturn(&decode_callback_for_testing_).Run();
5800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool is_clock_manager = is_audio || !HasAudio();
58258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
58358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_clock_manager)
584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    decoder_starvation_callback_.Cancel();
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
58658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (status == MEDIA_CODEC_ERROR) {
5870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : decode error";
588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Release();
58968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING) {
59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ProcessPendingEvents();
59590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
59690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
59790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
59858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
59990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PlaybackCompleted(is_audio);
60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
60190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
60290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_OK && is_clock_manager &&
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      presentation_timestamp != kNoTimestamp()) {
60558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    UpdateTimestamps(presentation_timestamp, audio_output_bytes);
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!playing_) {
60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (is_clock_manager)
610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      clock_.Pause();
61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_NO_KEY) {
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    is_waiting_for_key_ = true;
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // in the middle of a seek or stop event and needs to wait for the IPCs to
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // come.
6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_STOPPED)
623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_clock_manager) {
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If we have a valid timestamp, start the starvation callback. Otherwise,
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // reset the |start_time_ticks_| so that the next frame will not suffer
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // from the decoding delay caused by the current frame.
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (presentation_timestamp != kNoTimestamp())
6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      StartStarvationCallback(presentation_timestamp);
6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else
6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      start_time_ticks_ = base::TimeTicks::Now();
6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
63458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_audio) {
63658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DecodeMoreAudio();
63758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
639424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
640424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DecodeMoreVideo();
64190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
64390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::DecodeMoreAudio() {
644424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!audio_decoder_job_->is_decoding());
646424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
647424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (audio_decoder_job_->Decode(
648424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          start_time_ticks_, start_presentation_timestamp_, base::Bind(
649424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              &MediaSourcePlayer::MediaDecoderCallback,
650424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              weak_this_.GetWeakPtr(), true))) {
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             audio_decoder_job_.get());
653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
656424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Failed to start the next decode.
657424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Wait for demuxer ready message.
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!reconfig_audio_decoder_);
659424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  reconfig_audio_decoder_ = true;
660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Config change may have just been detected on the other stream. If so,
662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // don't send a duplicate demuxer config request.
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(reconfig_video_decoder_);
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
67090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
67290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::DecodeMoreVideo() {
673424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!video_decoder_job_->is_decoding());
675424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
676424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (video_decoder_job_->Decode(
677424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          start_time_ticks_, start_presentation_timestamp_, base::Bind(
678424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              &MediaSourcePlayer::MediaDecoderCallback,
679424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              weak_this_.GetWeakPtr(), false))) {
6804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             video_decoder_job_.get());
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
685424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Failed to start the next decode.
686424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Wait for demuxer ready message.
6871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // After this detection of video config change, next video data received
6891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // will begin with I-frame.
6901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  next_video_data_is_iframe_ = true;
6911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!reconfig_video_decoder_);
693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  reconfig_video_decoder_ = true;
694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Config change may have just been detected on the other stream. If so,
696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // don't send a duplicate demuxer config request.
697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(reconfig_audio_decoder_);
699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
702424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
703424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
70490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
70590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
70690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
707424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
70890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (is_audio)
70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    audio_finished_ = true;
71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else
71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    video_finished_ = true;
71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if ((!HasAudio() || audio_finished_) && (!HasVideo() || video_finished_)) {
71490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    playing_ = false;
715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    clock_.Pause();
716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    start_time_ticks_ = base::TimeTicks();
71768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    manager()->OnPlaybackComplete(player_id());
71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
71990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
72090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
72190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::ClearDecodingData() {
722424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
72390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (audio_decoder_job_)
72490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    audio_decoder_job_->Flush();
72590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (video_decoder_job_)
72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    video_decoder_job_->Flush();
727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
72890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
72990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
73090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::HasVideo() {
73190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return kUnknownVideoCodec != video_codec_;
73290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::HasAudio() {
73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return kUnknownAudioCodec != audio_codec_;
73690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
73790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaSourcePlayer::ConfigureAudioDecoderJob() {
7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!HasAudio()) {
7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    audio_decoder_job_.reset();
7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
7427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create audio decoder job only if config changes.
745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (audio_decoder_job_ && !reconfig_audio_decoder_)
746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
748424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
749424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (is_audio_encrypted_ && media_crypto.is_null())
750424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
751424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
752424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job";
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_decoder_job_.reset(AudioDecoderJob::Create(
757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
758424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      audio_extra_data_.size(), media_crypto.obj(),
75958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&DemuxerAndroid::RequestDemuxerData,
7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
762a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (audio_decoder_job_) {
763a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetVolumeInternal();
7641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reconfig_audio_decoder_ =  false;
766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaSourcePlayer::ResetVideoDecoderJob() {
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video_decoder_job_.reset();
771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Any eventual video decoder job re-creation will use the current |surface_|.
773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaSourcePlayer::ConfigureVideoDecoderJob() {
7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!HasVideo() || surface_.IsEmpty()) {
779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResetVideoDecoderJob();
780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create video decoder job only if config changes or we don't have a job.
784f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (video_decoder_job_ && !reconfig_video_decoder_) {
785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
789f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (reconfig_video_decoder_) {
7921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // No hack browser seek should be required. I-Frame must be next.
7931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(next_video_data_is_iframe_) << "Received video data between "
7941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        << "detecting video config change and reconfiguring video decoder";
7951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
7961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If uncertain that video I-frame data is next and there is no seek already
7981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // in process, request browser demuxer seek so the new decoder will decode
7991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387.
800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and
801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // continue from here.
8021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
8031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // since last keyframe. See http://crbug.com/304234.
8041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) {
8051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    BrowserSeekToCurrentTime();
8061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
8071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
8081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Release the old VideoDecoderJob first so the surface can get released.
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Android does not allow 2 MediaCodec instances use the same surface.
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResetVideoDecoderJob();
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
813424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
814424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (is_video_encrypted_ && media_crypto.is_null())
815424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
816424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
8171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : creating new video decoder job";
8181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Create the new VideoDecoderJob.
82058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool is_secure = IsProtectedSurfaceRequired();
82158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  video_decoder_job_.reset(
82258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      VideoDecoderJob::Create(video_codec_,
82358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              is_secure,
82458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              gfx::Size(width_, height_),
82558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              surface_.j_surface().obj(),
82658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              media_crypto.obj(),
82758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              base::Bind(&DemuxerAndroid::RequestDemuxerData,
8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                         base::Unretained(demuxer_.get()),
82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         DemuxerStream::VIDEO)));
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!video_decoder_job_)
831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
8321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video_decoder_job_->BeginPrerolling(preroll_timestamp_);
834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  reconfig_video_decoder_ = false;
835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Inform the fullscreen view the player is ready.
837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // to inform ContentVideoView.
83968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->OnMediaMetadataChanged(
84068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      player_id(), duration_, width_, height_, true);
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::OnDecoderStarved() {
844424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
845424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
846424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
847eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::StartStarvationCallback(
85058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::TimeDelta& presentation_timestamp) {
85158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // 20ms was chosen because it is the typical size of a compressed audio frame.
85258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Anything smaller than this would likely cause unnecessary cycling in and
85358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // out of the prefetch state.
85458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::TimeDelta kMinStarvationTimeout =
85558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(20);
85658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
85758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta current_timestamp = GetCurrentTime();
85858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta timeout;
85958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (HasAudio()) {
86058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp;
86158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
86258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(current_timestamp <= presentation_timestamp);
86358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
86458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // For video only streams, fps can be estimated from the difference
86558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // between the previous and current presentation timestamps. The
86658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // previous presentation timestamp is equal to current_timestamp.
86758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(qinmin): determine whether 2 is a good coefficient for estimating
86858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // video frame timeout.
86958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    timeout = 2 * (presentation_timestamp - current_timestamp);
87058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
87158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
87258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  timeout = std::max(timeout, kMinStarvationTimeout);
873424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  decoder_starvation_callback_.Reset(
875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&MediaSourcePlayer::OnDecoderStarved,
876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 weak_this_.GetWeakPtr()));
877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoop::current()->PostDelayedTask(
878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE, decoder_starvation_callback_.callback(), timeout);
879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
881424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::SetVolumeInternal() {
882424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (audio_decoder_job_ && volume_ >= 0)
883424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->SetVolume(volume_);
884424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
885424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
886424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
887424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return is_video_encrypted_ &&
888424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
889424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
890424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
891424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::OnPrefetchDone() {
892424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
893424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
894424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
8950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // A previously posted OnPrefetchDone() could race against a Release(). If
8970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Release() won the race, we should no longer have decoder jobs.
8980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
8990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // or drop data received across Release()+Start(). See http://crbug.com/306314
9000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // and http://crbug.com/304234.
9010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
9020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : aborting";
9030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(!audio_decoder_job_ && !video_decoder_job_);
9040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
9050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
906424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
907424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
908424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
909424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING) {
910424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ProcessPendingEvents();
911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
913424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks::Now();
915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_presentation_timestamp_ = GetCurrentTime();
916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!clock_.IsPlaying())
917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    clock_.Play();
918424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
919424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (audio_decoder_job_)
920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DecodeMoreAudio();
921424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (video_decoder_job_)
922eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DecodeMoreVideo();
923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
925424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
926424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const char* kPendingEventNames[] = {
927424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "SEEK",
928424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "SURFACE_CHANGE",
929424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "CONFIG_CHANGE",
930424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "PREFETCH_REQUEST",
931424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "PREFETCH_DONE",
932424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
934424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int mask = 1;
935424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) {
936424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (event & mask)
937424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return kPendingEventNames[i];
938424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
940424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return "UNKNOWN";
941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
943424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaSourcePlayer::IsEventPending(PendingEventFlags event) const {
944424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return pending_event_ & event;
945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
947424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::SetPendingEvent(PendingEventFlags event) {
948424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
949424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_NE(event, NO_EVENT_PENDING);
950424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!IsEventPending(event));
951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
952424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pending_event_ |= event;
953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
955424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
956424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
957424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_NE(event, NO_EVENT_PENDING);
958d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(IsEventPending(event)) << GetEventName(event);
959424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
960424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pending_event_ &= ~event;
961a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
962a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
96390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace media
964