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),
76d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      reached_audio_eos_(false),
77d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      reached_video_eos_(false),
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)
321424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerConfigsAvailable(
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const DemuxerConfigs& configs) {
327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
328424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms);
3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  clock_.SetDuration(duration_);
3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  audio_codec_ = configs.audio_codec;
332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  num_channels_ = configs.audio_channels;
333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  sampling_rate_ = configs.audio_sampling_rate;
334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_audio_encrypted_ = configs.is_audio_encrypted;
335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  audio_extra_data_ = configs.audio_extra_data;
3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (HasAudio()) {
3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK_GT(num_channels_, 0);
3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_));
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime());
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_.reset();
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  video_codec_ = configs.video_codec;
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  width_ = configs.video_size.width();
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  height_ = configs.video_size.height();
347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_video_encrypted_ = configs.is_video_encrypted;
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->OnMediaMetadataChanged(
35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      player_id(), duration_, width_, height_, true);
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (reconfig_audio_decoder_)
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ConfigureAudioDecoderJob();
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (reconfig_video_decoder_)
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ConfigureVideoDecoderJob();
358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ClearPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Resume decoding after the config change if we are still playing.
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (playing_)
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      StartInternal();
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_LT(0u, data.access_units.size());
3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (data.type == DemuxerStream::AUDIO && audio_decoder_job_) {
371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->OnDataReceived(data);
3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (data.type == DemuxerStream::VIDEO) {
3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    next_video_data_is_iframe_ = false;
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (video_decoder_job_)
3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      video_decoder_job_->OnDataReceived(data);
3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  duration_ = duration;
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  clock_.SetDuration(duration_);
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)base::android::ScopedJavaLocalRef<jobject> MediaSourcePlayer::GetMediaCrypto() {
385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> media_crypto;
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (drm_bridge_)
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    media_crypto = drm_bridge_->GetMediaCrypto();
388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return media_crypto;
389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::OnMediaCryptoReady() {
392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (playing_)
396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    StartInternal();
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) {
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Currently we don't support DRM change during the middle of playback, even
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // if the player is paused.
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(qinmin): support DRM change after playback has started.
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://crbug.com/253792.
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (GetCurrentTime() > base::TimeDelta()) {
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(0) << "Setting DRM bridge after playback has started. "
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << "This is not well supported!";
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drm_bridge_ = drm_bridge;
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (drm_bridge_->GetMediaCrypto().is_null()) {
412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    drm_bridge_->SetMediaCryptoReadyCB(base::Bind(
413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr()));
414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (playing_)
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    StartInternal();
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::OnDemuxerSeekDone(
4221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::TimeDelta& actual_browser_seek_time) {
42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
424424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
425424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ClearPendingEvent(SEEK_EVENT_PENDING);
426f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)  if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
427f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)    ClearPendingEvent(PREFETCH_REQUEST_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)
454d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  reached_audio_eos_ = false;
455d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  reached_video_eos_ = false;
456d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeDelta current_time = GetCurrentTime();
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // is calculated from decoder output, while preroll relies on the access
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unit's timestamp. There are some differences between the two.
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  preroll_timestamp_ = current_time;
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (audio_decoder_job_)
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (video_decoder_job_)
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    video_decoder_job_->BeginPrerolling(preroll_timestamp_);
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!doing_browser_seek_)
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    manager()->OnSeekComplete(player_id(), current_time);
4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessPendingEvents();
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::UpdateTimestamps(
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta new_max_time = presentation_timestamp;
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (audio_output_bytes > 0) {
4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    audio_timestamp_helper_->AddFrames(
4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    new_max_time = audio_timestamp_helper_->GetTimestamp();
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
48458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  clock_.SetMaxTime(new_max_time);
48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->OnTimeUpdate(player_id(), GetCurrentTime());
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::ProcessPendingEvents() {
48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Wait for all the decoding jobs to finish before processing pending tasks.
49158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (video_decoder_job_ && video_decoder_job_->is_decoding()) {
49258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
49358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) {
49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
500424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
506424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ClearDecodingData();
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
514424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
515424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT.";
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    demuxer_->RequestDemuxerConfigs();
518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING)) {
522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling SURFACE_CHANGE_EVENT.";
5231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Setting a new surface will require a new MediaCodec to be created.
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResetVideoDecoderJob();
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ConfigureVideoDecoderJob();
5261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Return early if we can't successfully configure a new video decoder job
5286680793cbf6b80d9dabf0def799cdc62ca552bf6Tao Bai    // yet.
5296680793cbf6b80d9dabf0def799cdc62ca552bf6Tao Bai    if (HasVideo() && !video_decoder_job_)
5301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return;
531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
535d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    DCHECK(audio_decoder_job_ || AudioFinished());
536d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    DCHECK(video_decoder_job_ || VideoFinished());
537d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
538d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
539d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
540d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    // It is possible that all streams have finished decode, yet starvation
541d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    // occurred during the last stream's EOS decode. In this case, prefetch is a
542d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    // no-op.
543d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
544d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (count == 0)
545d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      return;
546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
547d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    base::Closure barrier = BarrierClosure(count, base::Bind(
549424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr()));
550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
551d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (!AudioFinished())
552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      audio_decoder_job_->Prefetch(barrier);
553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
554d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (!VideoFinished())
555424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      video_decoder_job_->Prefetch(barrier);
556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
55990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Now that all pending events have been handled, resume decoding if we are
563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // still playing.
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (playing_)
565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    StartInternal();
56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::MediaDecoderCallback(
56958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool is_audio, MediaCodecStatus status,
570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed.
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_audio) {
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_END1("media",
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaSourcePlayer::DecodeMoreAudio",
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           audio_decoder_job_.get(),
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaCodecStatus",
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           base::IntToString(status));
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_END1("media",
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaSourcePlayer::DecodeMoreVideo",
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           video_decoder_job_.get(),
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaCodecStatus",
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           base::IntToString(status));
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Let tests hook the completion of this decode cycle.
5890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!decode_callback_for_testing_.is_null())
5900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::ResetAndReturn(&decode_callback_for_testing_).Run();
5910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool is_clock_manager = is_audio || !HasAudio();
59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
59458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_clock_manager)
595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    decoder_starvation_callback_.Cancel();
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
59758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (status == MEDIA_CODEC_ERROR) {
5980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : decode error";
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Release();
60068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
604d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
605d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
606d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
607d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
608d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // any other pending events only after handling EOS detection.
609d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
61090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ProcessPendingEvents();
61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
61290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
614d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
61590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PlaybackCompleted(is_audio);
616d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
617d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING) {
618d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    ProcessPendingEvents();
61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
62090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
622d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
623d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    return;
624d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_OK && is_clock_manager &&
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      presentation_timestamp != kNoTimestamp()) {
62758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    UpdateTimestamps(presentation_timestamp, audio_output_bytes);
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
62958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!playing_) {
63158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (is_clock_manager)
632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      clock_.Pause();
63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_NO_KEY) {
6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    is_waiting_for_key_ = true;
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // in the middle of a seek or stop event and needs to wait for the IPCs to
6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // come.
6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_STOPPED)
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_clock_manager) {
6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If we have a valid timestamp, start the starvation callback. Otherwise,
6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // reset the |start_time_ticks_| so that the next frame will not suffer
6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // from the decoding delay caused by the current frame.
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (presentation_timestamp != kNoTimestamp())
6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      StartStarvationCallback(presentation_timestamp);
6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else
6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      start_time_ticks_ = base::TimeTicks::Now();
6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
65658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
65758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_audio) {
65858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DecodeMoreAudio();
65958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
661424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
662424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DecodeMoreVideo();
66390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
66490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
66590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::DecodeMoreAudio() {
666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!audio_decoder_job_->is_decoding());
668d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  DCHECK(!AudioFinished());
669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
670424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (audio_decoder_job_->Decode(
671424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          start_time_ticks_, start_presentation_timestamp_, base::Bind(
672424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              &MediaSourcePlayer::MediaDecoderCallback,
673424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              weak_this_.GetWeakPtr(), true))) {
6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             audio_decoder_job_.get());
676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
679424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Failed to start the next decode.
680424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Wait for demuxer ready message.
681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!reconfig_audio_decoder_);
682424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  reconfig_audio_decoder_ = true;
683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Config change may have just been detected on the other stream. If so,
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // don't send a duplicate demuxer config request.
686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(reconfig_video_decoder_);
688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
691424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
692424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
69490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
69590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::DecodeMoreVideo() {
696424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!video_decoder_job_->is_decoding());
698d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  DCHECK(!VideoFinished());
699424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
700424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (video_decoder_job_->Decode(
701424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          start_time_ticks_, start_presentation_timestamp_, base::Bind(
702424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              &MediaSourcePlayer::MediaDecoderCallback,
703424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)              weak_this_.GetWeakPtr(), false))) {
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             video_decoder_job_.get());
706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
709424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Failed to start the next decode.
710424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Wait for demuxer ready message.
7111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // After this detection of video config change, next video data received
7131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // will begin with I-frame.
7141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  next_video_data_is_iframe_ = true;
7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!reconfig_video_decoder_);
717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  reconfig_video_decoder_ = true;
718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Config change may have just been detected on the other stream. If so,
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // don't send a duplicate demuxer config request.
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(reconfig_audio_decoder_);
723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
726424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
727424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
72890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
72990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
73090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
731424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
73290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (is_audio)
733d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    reached_audio_eos_ = true;
73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else
735d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    reached_video_eos_ = true;
73690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
737d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (AudioFinished() && VideoFinished()) {
73890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    playing_ = false;
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    clock_.Pause();
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    start_time_ticks_ = base::TimeTicks();
74168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    manager()->OnPlaybackComplete(player_id());
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
74390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
74490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
74590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::ClearDecodingData() {
746424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
74790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (audio_decoder_job_)
74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    audio_decoder_job_->Flush();
74990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (video_decoder_job_)
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    video_decoder_job_->Flush();
751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
75390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
75490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::HasVideo() {
75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return kUnknownVideoCodec != video_codec_;
75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
75890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::HasAudio() {
75990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return kUnknownAudioCodec != audio_codec_;
76090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
76190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
762d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool MediaSourcePlayer::AudioFinished() {
763d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  return reached_audio_eos_ || !HasAudio();
764d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)}
765d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
766d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool MediaSourcePlayer::VideoFinished() {
767d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  return reached_video_eos_ || !HasVideo();
768d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)}
769d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
7707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaSourcePlayer::ConfigureAudioDecoderJob() {
7717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!HasAudio()) {
7727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    audio_decoder_job_.reset();
7737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
7747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create audio decoder job only if config changes.
777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (audio_decoder_job_ && !reconfig_audio_decoder_)
778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
780424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
781424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (is_audio_encrypted_ && media_crypto.is_null())
782424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
783424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
784424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job";
7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_decoder_job_.reset(AudioDecoderJob::Create(
789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
790424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      audio_extra_data_.size(), media_crypto.obj(),
79158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&DemuxerAndroid::RequestDemuxerData,
7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
794a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (audio_decoder_job_) {
795a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetVolumeInternal();
7961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reconfig_audio_decoder_ =  false;
798a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaSourcePlayer::ResetVideoDecoderJob() {
802f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video_decoder_job_.reset();
803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Any eventual video decoder job re-creation will use the current |surface_|.
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsEventPending(SURFACE_CHANGE_EVENT_PENDING))
806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ClearPendingEvent(SURFACE_CHANGE_EVENT_PENDING);
807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaSourcePlayer::ConfigureVideoDecoderJob() {
8107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!HasVideo() || surface_.IsEmpty()) {
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResetVideoDecoderJob();
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create video decoder job only if config changes or we don't have a job.
816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (video_decoder_job_ && !reconfig_video_decoder_) {
817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(!IsEventPending(SURFACE_CHANGE_EVENT_PENDING));
818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (reconfig_video_decoder_) {
8241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // No hack browser seek should be required. I-Frame must be next.
8251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(next_video_data_is_iframe_) << "Received video data between "
8261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        << "detecting video config change and reconfiguring video decoder";
8271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
8281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
8291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If uncertain that video I-frame data is next and there is no seek already
8301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // in process, request browser demuxer seek so the new decoder will decode
8311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // an I-frame first. Otherwise, the new MediaCodec might crash. See b/8950387.
832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Eventual OnDemuxerSeekDone() will trigger ProcessPendingEvents() and
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // continue from here.
8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(wolenetz): Instead of doing hack browser seek, replay cached data
8351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // since last keyframe. See http://crbug.com/304234.
8361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!next_video_data_is_iframe_ && !IsEventPending(SEEK_EVENT_PENDING)) {
8371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    BrowserSeekToCurrentTime();
8381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
8391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
8401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Release the old VideoDecoderJob first so the surface can get released.
842f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Android does not allow 2 MediaCodec instances use the same surface.
843f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResetVideoDecoderJob();
844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
845424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> media_crypto = GetMediaCrypto();
846424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (is_video_encrypted_ && media_crypto.is_null())
847424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
848424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
8491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : creating new video decoder job";
8501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Create the new VideoDecoderJob.
85258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool is_secure = IsProtectedSurfaceRequired();
85358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  video_decoder_job_.reset(
85458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      VideoDecoderJob::Create(video_codec_,
85558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              is_secure,
85658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              gfx::Size(width_, height_),
85758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              surface_.j_surface().obj(),
85858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              media_crypto.obj(),
85958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              base::Bind(&DemuxerAndroid::RequestDemuxerData,
8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                         base::Unretained(demuxer_.get()),
86158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         DemuxerStream::VIDEO)));
862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!video_decoder_job_)
863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
8641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video_decoder_job_->BeginPrerolling(preroll_timestamp_);
866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  reconfig_video_decoder_ = false;
867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Inform the fullscreen view the player is ready.
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // to inform ContentVideoView.
87168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  manager()->OnMediaMetadataChanged(
87268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      player_id(), duration_, width_, height_, true);
873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::OnDecoderStarved() {
876424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
877424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
878424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::StartStarvationCallback(
88258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::TimeDelta& presentation_timestamp) {
88358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // 20ms was chosen because it is the typical size of a compressed audio frame.
88458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Anything smaller than this would likely cause unnecessary cycling in and
88558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // out of the prefetch state.
88658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::TimeDelta kMinStarvationTimeout =
88758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(20);
88858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
88958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta current_timestamp = GetCurrentTime();
89058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta timeout;
89158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (HasAudio()) {
89258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp;
89358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
89458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(current_timestamp <= presentation_timestamp);
89558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
89658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // For video only streams, fps can be estimated from the difference
89758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // between the previous and current presentation timestamps. The
89858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // previous presentation timestamp is equal to current_timestamp.
89958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(qinmin): determine whether 2 is a good coefficient for estimating
90058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // video frame timeout.
90158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    timeout = 2 * (presentation_timestamp - current_timestamp);
90258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
90358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
90458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  timeout = std::max(timeout, kMinStarvationTimeout);
905424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  decoder_starvation_callback_.Reset(
907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&MediaSourcePlayer::OnDecoderStarved,
908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 weak_this_.GetWeakPtr()));
909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoop::current()->PostDelayedTask(
910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE, decoder_starvation_callback_.callback(), timeout);
911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
913424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::SetVolumeInternal() {
914424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (audio_decoder_job_ && volume_ >= 0)
915424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->SetVolume(volume_);
916424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
917424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
918424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
919424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return is_video_encrypted_ &&
920424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
921424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
922424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
923424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::OnPrefetchDone() {
924424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
925424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!audio_decoder_job_ || !audio_decoder_job_->is_decoding());
926424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!video_decoder_job_ || !video_decoder_job_->is_decoding());
9270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // A previously posted OnPrefetchDone() could race against a Release(). If
9290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Release() won the race, we should no longer have decoder jobs.
9300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
9310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // or drop data received across Release()+Start(). See http://crbug.com/306314
9320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // and http://crbug.com/304234.
9330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
9340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : aborting";
9350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(!audio_decoder_job_ && !video_decoder_job_);
9360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
9370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
938424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
939424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
940424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
941424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING) {
942424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ProcessPendingEvents();
943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
945424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks::Now();
947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_presentation_timestamp_ = GetCurrentTime();
948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!clock_.IsPlaying())
949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    clock_.Play();
950424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
951d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (!AudioFinished())
952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DecodeMoreAudio();
953d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
954d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (!VideoFinished())
955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DecodeMoreVideo();
956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
958424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
959424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const char* kPendingEventNames[] = {
960424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "SEEK",
961424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "SURFACE_CHANGE",
962424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "CONFIG_CHANGE",
963424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "PREFETCH_REQUEST",
964424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "PREFETCH_DONE",
965424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
967424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int mask = 1;
968424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) {
969424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (event & mask)
970424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return kPendingEventNames[i];
971424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
973424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return "UNKNOWN";
974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
976424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaSourcePlayer::IsEventPending(PendingEventFlags event) const {
977424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return pending_event_ & event;
978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
980424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::SetPendingEvent(PendingEventFlags event) {
981424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
982424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_NE(event, NO_EVENT_PENDING);
983424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!IsEventPending(event));
984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
985424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pending_event_ |= event;
986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
988424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
989424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
990424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_NE(event, NO_EVENT_PENDING);
991d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(IsEventPending(event)) << GetEventName(event);
992424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
993424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pending_event_ &= ~event;
994a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
995a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
99690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace media
997