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"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media {
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaSourcePlayer::MediaSourcePlayer(
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int player_id,
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    MediaPlayerManager* manager,
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RequestMediaResourcesCB& request_media_resources_cb,
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_ptr<DemuxerAndroid> demuxer,
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const GURL& frame_url)
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : MediaPlayerAndroid(player_id,
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         manager,
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         request_media_resources_cb,
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         frame_url),
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      demuxer_(demuxer.Pass()),
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      pending_event_(NO_EVENT_PENDING),
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      playing_(false),
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      interpolator_(&default_tick_clock_),
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      doing_browser_seek_(false),
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_seek_(false),
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      drm_bridge_(NULL),
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      cdm_registration_id_(0),
4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      is_waiting_for_key_(false),
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      is_waiting_for_audio_decoder_(false),
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      is_waiting_for_video_decoder_(false),
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      prerolling_(false),
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      weak_factory_(this) {
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_decoder_job_.reset(new AudioDecoderJob(
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&DemuxerAndroid::RequestDemuxerData,
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(demuxer_.get()),
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 DemuxerStream::AUDIO),
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 weak_factory_.GetWeakPtr())));
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  video_decoder_job_.reset(new VideoDecoderJob(
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&DemuxerAndroid::RequestDemuxerData,
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(demuxer_.get()),
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 DemuxerStream::VIDEO),
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(request_media_resources_cb_, player_id),
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 weak_factory_.GetWeakPtr())));
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  demuxer_->Initialize(this);
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  interpolator_.SetUpperBound(base::TimeDelta());
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  weak_this_ = weak_factory_.GetWeakPtr();
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaSourcePlayer::~MediaSourcePlayer() {
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Release();
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK_EQ(!drm_bridge_, !cdm_registration_id_);
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (drm_bridge_) {
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    drm_bridge_->UnregisterPlayer(cdm_registration_id_);
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    cdm_registration_id_ = 0;
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!video_decoder_job_->SetVideoSurface(surface.Pass()))
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Retry video decoder creation.
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RetryDecoderCreation(false, true);
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::TimeDelta seek_time) {
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_seek_ = false;
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  interpolator_.SetBounds(seek_time, seek_time);
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (audio_decoder_job_->is_decoding())
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->StopDecode();
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (video_decoder_job_->is_decoding())
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    video_decoder_job_->StopDecode();
97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(SEEK_EVENT_PENDING);
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessPendingEvents();
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::BrowserSeekToCurrentTime() {
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  doing_browser_seek_ = true;
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScheduleSeekEventAndStopDecoding(GetCurrentTime());
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MediaSourcePlayer::Seekable() {
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the duration TimeDelta, converted to milliseconds from microseconds,
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is >= 2^31, then the media is assumed to be unbounded and unseekable.
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // 2^31 is the bound due to java player using 32-bit integer for time
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // values at millisecond resolution.
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return duration_ <
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         base::TimeDelta::FromMilliseconds(std::numeric_limits<int32>::max());
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::Start() {
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  playing_ = true;
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool request_fullscreen = IsProtectedSurfaceRequired();
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(VIDEO_HOLE)
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Skip to request fullscreen when hole-punching is used.
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request_fullscreen = request_fullscreen &&
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      !manager()->ShouldUseVideoOverlayForEmbeddedEncryptedVideo();
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // defined(VIDEO_HOLE)
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (request_fullscreen)
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    manager()->RequestFullScreen(player_id());
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StartInternal();
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaSourcePlayer::Pause(bool is_media_related_action) {
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Since decoder jobs have their own thread, decoding is not fully paused
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // until all the decoder jobs call MediaDecoderCallback(). It is possible
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // that Start() is called while the player is waiting for
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MediaDecoderCallback(). In that case, decoding will continue when
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MediaDecoderCallback() is called.
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  playing_ = false;
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::IsPlaying() {
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return playing_;
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int MediaSourcePlayer::GetVideoWidth() {
1535b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  return video_decoder_job_->output_width();
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int MediaSourcePlayer::GetVideoHeight() {
1575b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  return video_decoder_job_->output_height();
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) {
161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(doing_browser_seek_) << "SeekTo while SeekTo in progress";
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(!pending_seek_) << "SeekTo while SeekTo pending browser seek";
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // There is a browser seek currently in progress to obtain I-frame to feed
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // a newly constructed video decoder. Remember this real seek request so
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // it can be initiated once OnDemuxerSeekDone() occurs for the browser seek.
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_seek_ = true;
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_seek_time_ = timestamp;
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  doing_browser_seek_ = false;
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScheduleSeekEventAndStopDecoding(timestamp);
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return std::min(interpolator_.GetInterpolatedTime(), duration_);
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::TimeDelta MediaSourcePlayer::GetDuration() {
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return duration_;
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::Release() {
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_decoder_job_->ReleaseDecoderResources();
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  video_decoder_job_->ReleaseDecoderResources();
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Prevent player restart, including job re-creation attempts.
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  playing_ = false;
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  decoder_starvation_callback_.Cancel();
1971675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  DetachListener();
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MediaSourcePlayer::SetVolume(double volume) {
20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_decoder_job_->SetVolume(volume);
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::CanPause() {
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return Seekable();
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::CanSeekForward() {
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return Seekable();
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::CanSeekBackward() {
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return Seekable();
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool MediaSourcePlayer::IsPlayerReady() {
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return audio_decoder_job_ || video_decoder_job_;
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::StartInternal() {
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If there are pending events, wait for them finish.
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING)
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // When we start, we'll have new demuxed data coming in. This new data could
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // be clear (not encrypted) or encrypted with different keys. So
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |is_waiting_for_key_| condition may not be true anymore.
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  is_waiting_for_key_ = false;
2301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  AttachListener(NULL);
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerConfigsAvailable(
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const DemuxerConfigs& configs) {
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!HasAudio() && !HasVideo());
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  duration_ = configs.duration;
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_decoder_job_->SetDemuxerConfigs(configs);
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  video_decoder_job_->SetDemuxerConfigs(configs);
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  OnDemuxerConfigsChanged();
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_LT(0u, data.access_units.size());
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CHECK_GE(1u, data.demuxer_configs.size());
25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (data.type == DemuxerStream::AUDIO)
253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    audio_decoder_job_->OnDataReceived(data);
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  else if (data.type == DemuxerStream::VIDEO)
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    video_decoder_job_->OnDataReceived(data);
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerDurationChanged(base::TimeDelta duration) {
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  duration_ = duration;
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::OnMediaCryptoReady() {
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Retry decoder creation if the decoders are waiting for MediaCrypto.
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RetryDecoderCreation(true, true);
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaSourcePlayer::SetCdm(BrowserCdm* cdm) {
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Currently we don't support DRM change during the middle of playback, even
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // if the player is paused.
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(qinmin): support DRM change after playback has started.
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://crbug.com/253792.
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (GetCurrentTime() > base::TimeDelta()) {
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(0) << "Setting DRM bridge after playback has started. "
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << "This is not well supported!";
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (drm_bridge_) {
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    NOTREACHED() << "Currently we do not support resetting CDM.";
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Only MediaDrmBridge will be set on MediaSourcePlayer.
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  drm_bridge_ = static_cast<MediaDrmBridge*>(cdm);
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  cdm_registration_id_ = drm_bridge_->RegisterPlayer(
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::OnKeyAdded, weak_this_),
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::OnCdmUnset, weak_this_));
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_decoder_job_->SetDrmBridge(drm_bridge_);
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  video_decoder_job_->SetDrmBridge(drm_bridge_);
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (drm_bridge_->GetMediaCrypto().is_null()) {
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    drm_bridge_->SetMediaCryptoReadyCB(
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(&MediaSourcePlayer::OnMediaCryptoReady, weak_this_));
298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // If the player is previously waiting for CDM, retry decoder creation.
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RetryDecoderCreation(true, true);
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourcePlayer::OnDemuxerSeekDone(
30623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::TimeDelta actual_browser_seek_time) {
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ClearPendingEvent(SEEK_EVENT_PENDING);
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING))
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (pending_seek_) {
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << "processing pending seek";
3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(doing_browser_seek_);
3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_seek_ = false;
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SeekTo(pending_seek_time_);
3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // It is possible that a browser seek to I-frame had to seek to a buffered
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // I-frame later than the requested one due to data removal or GC. Update
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // player clock to the actual seek target.
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (doing_browser_seek_) {
3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(actual_browser_seek_time != kNoTimestamp());
32623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::TimeDelta seek_time = actual_browser_seek_time;
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // A browser seek must not jump into the past. Ideally, it seeks to the
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // requested time, but it might jump into the future.
32923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(seek_time >= GetCurrentTime());
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
33123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)             << seek_time.InSecondsF();
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    interpolator_.SetBounds(seek_time, seek_time);
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    audio_decoder_job_->SetBaseTimestamp(seek_time);
33423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
33523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(actual_browser_seek_time == kNoTimestamp());
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeDelta current_time = GetCurrentTime();
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // is calculated from decoder output, while preroll relies on the access
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unit's timestamp. There are some differences between the two.
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  preroll_timestamp_ = current_time;
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (HasAudio())
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (HasVideo())
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    video_decoder_job_->BeginPrerolling(preroll_timestamp_);
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prerolling_ = true;
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!doing_browser_seek_)
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    manager()->OnSeekComplete(player_id(), current_time);
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessPendingEvents();
35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::UpdateTimestamps(
3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::TimeDelta current_presentation_timestamp,
3580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::TimeDelta max_presentation_timestamp) {
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  interpolator_.SetBounds(current_presentation_timestamp,
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          max_presentation_timestamp);
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  manager()->OnTimeUpdate(player_id(),
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          GetCurrentTime(),
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          base::TimeTicks::Now());
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::ProcessPendingEvents() {
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Wait for all the decoding jobs to finish before processing pending tasks.
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (video_decoder_job_->is_decoding()) {
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (audio_decoder_job_->is_decoding()) {
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ClearDecodingData();
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    audio_decoder_job_->SetBaseTimestamp(GetCurrentTime());
3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (IsEventPending(DECODER_CREATION_EVENT_PENDING)) {
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Don't continue if one of the decoder is not created.
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (is_waiting_for_audio_decoder_ || is_waiting_for_video_decoder_)
3951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return;
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ClearPendingEvent(DECODER_CREATION_EVENT_PENDING);
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // It is possible that all streams have finished decode, yet starvation
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // occurred during the last stream's EOS decode. In this case, prefetch is a
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // no-op.
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (count == 0)
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::Closure barrier = BarrierClosure(
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        count, base::Bind(&MediaSourcePlayer::OnPrefetchDone, weak_this_));
413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!AudioFinished())
415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      audio_decoder_job_->Prefetch(barrier);
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!VideoFinished())
418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      video_decoder_job_->Prefetch(barrier);
419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
423424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
424424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
425424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Now that all pending events have been handled, resume decoding if we are
426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // still playing.
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (playing_)
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    StartInternal();
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::MediaDecoderCallback(
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool is_audio, MediaCodecStatus status,
4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::TimeDelta current_presentation_timestamp,
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::TimeDelta max_presentation_timestamp) {
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed.
4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_audio) {
4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_END1("media",
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaSourcePlayer::DecodeMoreAudio",
4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           audio_decoder_job_.get(),
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaCodecStatus",
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           base::IntToString(status));
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_END1("media",
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaSourcePlayer::DecodeMoreVideo",
4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           video_decoder_job_.get(),
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           "MediaCodecStatus",
4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           base::IntToString(status));
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Let tests hook the completion of this decode cycle.
4530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!decode_callback_for_testing_.is_null())
4540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::ResetAndReturn(&decode_callback_for_testing_).Run();
4550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool is_clock_manager = is_audio || !HasAudio();
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
45858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_clock_manager)
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    decoder_starvation_callback_.Cancel();
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (status == MEDIA_CODEC_ERROR) {
4620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : decode error";
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Release();
46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // any other pending events only after handling EOS detection.
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (IsEventPending(SEEK_EVENT_PENDING)) {
47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ProcessPendingEvents();
47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if ((status == MEDIA_CODEC_OK || status == MEDIA_CODEC_INPUT_END_OF_STREAM) &&
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      is_clock_manager && current_presentation_timestamp != kNoTimestamp()) {
48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    UpdateTimestamps(current_presentation_timestamp,
48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     max_presentation_timestamp);
4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PlaybackCompleted(is_audio);
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (is_clock_manager)
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      interpolator_.StopInterpolating();
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING) {
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProcessPendingEvents();
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!playing_) {
49958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (is_clock_manager)
500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      interpolator_.StopInterpolating();
50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_NO_KEY) {
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    is_waiting_for_key_ = true;
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // in the middle of a seek or stop event and needs to wait for the IPCs to
5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // come.
5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status == MEDIA_CODEC_STOPPED)
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (prerolling_ && IsPrerollFinished(is_audio)) {
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (IsPrerollFinished(!is_audio)) {
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      prerolling_ = false;
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      StartInternal();
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_clock_manager) {
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If we have a valid timestamp, start the starvation callback. Otherwise,
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // reset the |start_time_ticks_| so that the next frame will not suffer
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // from the decoding delay caused by the current frame.
5270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (current_presentation_timestamp != kNoTimestamp())
5280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      StartStarvationCallback(current_presentation_timestamp,
5290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              max_presentation_timestamp);
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      start_time_ticks_ = base::TimeTicks::Now();
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
53358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (is_audio)
53558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DecodeMoreAudio();
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DecodeMoreVideo();
53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
53990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool MediaSourcePlayer::IsPrerollFinished(bool is_audio) const {
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (is_audio)
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return !HasAudio() || !audio_decoder_job_->prerolling();
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return !HasVideo() || !video_decoder_job_->prerolling();
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::DecodeMoreAudio() {
547424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!audio_decoder_job_->is_decoding());
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!AudioFinished());
550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (audio_decoder_job_->Decode(
552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      start_time_ticks_,
553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      start_presentation_timestamp_,
55446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true))) {
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             audio_decoder_job_.get());
557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  is_waiting_for_audio_decoder_ = true;
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!IsEventPending(DECODER_CREATION_EVENT_PENDING))
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SetPendingEvent(DECODER_CREATION_EVENT_PENDING);
56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::DecodeMoreVideo() {
566424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!video_decoder_job_->is_decoding());
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!VideoFinished());
569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
57046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (video_decoder_job_->Decode(
571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      start_time_ticks_,
572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      start_presentation_timestamp_,
57346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_,
57446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 false))) {
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             video_decoder_job_.get());
577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // If the decoder is waiting for iframe, trigger a browser seek.
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!video_decoder_job_->next_video_data_is_iframe()) {
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    BrowserSeekToCurrentTime();
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  is_waiting_for_video_decoder_ = true;
58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!IsEventPending(DECODER_CREATION_EVENT_PENDING))
58846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SetPendingEvent(DECODER_CREATION_EVENT_PENDING);
58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
59090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (AudioFinished() && VideoFinished()) {
59590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    playing_ = false;
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    start_time_ticks_ = base::TimeTicks();
59768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    manager()->OnPlaybackComplete(player_id());
59890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
59990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
60190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaSourcePlayer::ClearDecodingData() {
602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
60346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_decoder_job_->Flush();
60446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  video_decoder_job_->Flush();
605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks();
60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
60790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool MediaSourcePlayer::HasVideo() const {
60946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return video_decoder_job_->HasStream();
61090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool MediaSourcePlayer::HasAudio() const {
61346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return audio_decoder_job_->HasStream();
61490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
61590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaSourcePlayer::AudioFinished() {
61746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return audio_decoder_job_->OutputEOSReached() || !HasAudio();
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaSourcePlayer::VideoFinished() {
62146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return video_decoder_job_->OutputEOSReached() || !HasVideo();
622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::OnDecoderStarved() {
625424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
626424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
627424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProcessPendingEvents();
628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourcePlayer::StartStarvationCallback(
6310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::TimeDelta current_presentation_timestamp,
6320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::TimeDelta max_presentation_timestamp) {
63358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // 20ms was chosen because it is the typical size of a compressed audio frame.
63458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Anything smaller than this would likely cause unnecessary cycling in and
63558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // out of the prefetch state.
63658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::TimeDelta kMinStarvationTimeout =
63758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(20);
63858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta current_timestamp = GetCurrentTime();
64058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::TimeDelta timeout;
64158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (HasAudio()) {
6420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    timeout = max_presentation_timestamp - current_timestamp;
64358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
6440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(current_timestamp <= current_presentation_timestamp);
64558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
64658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // For video only streams, fps can be estimated from the difference
64758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // between the previous and current presentation timestamps. The
64858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // previous presentation timestamp is equal to current_timestamp.
64958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(qinmin): determine whether 2 is a good coefficient for estimating
65058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // video frame timeout.
6510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    timeout = 2 * (current_presentation_timestamp - current_timestamp);
65258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
65358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
65458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  timeout = std::max(timeout, kMinStarvationTimeout);
655424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
65646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  decoder_starvation_callback_.Reset(
65746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&MediaSourcePlayer::OnDecoderStarved, weak_this_));
658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoop::current()->PostDelayedTask(
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE, decoder_starvation_callback_.callback(), timeout);
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
662424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
66346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return video_decoder_job_->is_content_encrypted() &&
664424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      drm_bridge_ && drm_bridge_->IsProtectedSurfaceRequired();
665424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::OnPrefetchDone() {
668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
66946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!audio_decoder_job_->is_decoding());
67046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!video_decoder_job_->is_decoding());
6710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // A previously posted OnPrefetchDone() could race against a Release(). If
6730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Release() won the race, we should no longer have decoder jobs.
6740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(qinmin/wolenetz): Maintain channel state to not double-request data
6750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // or drop data received across Release()+Start(). See http://crbug.com/306314
6760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // and http://crbug.com/304234.
6770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
6780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DVLOG(1) << __FUNCTION__ << " : aborting";
6790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
6800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
681424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
682424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ClearPendingEvent(PREFETCH_DONE_EVENT_PENDING);
683424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
684424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (pending_event_ != NO_EVENT_PENDING) {
685424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ProcessPendingEvents();
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
688424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
68946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!playing_)
69046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
69146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_time_ticks_ = base::TimeTicks::Now();
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  start_presentation_timestamp_ = GetCurrentTime();
694116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!interpolator_.interpolating())
695116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    interpolator_.StartInterpolating();
696424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!AudioFinished())
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DecodeMoreAudio();
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!VideoFinished())
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DecodeMoreVideo();
70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaSourcePlayer::OnDemuxerConfigsChanged() {
70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  manager()->OnMediaMetadataChanged(
70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      player_id(), duration_, GetVideoWidth(), GetVideoHeight(), true);
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
709424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Please keep this in sync with PendingEventFlags.
711424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const char* kPendingEventNames[] = {
71246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    "PREFETCH_DONE",
713424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "SEEK",
71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    "DECODER_CREATION",
715424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    "PREFETCH_REQUEST",
716424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
718424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int mask = 1;
719424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kPendingEventNames); ++i, mask <<= 1) {
720424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (event & mask)
721424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return kPendingEventNames[i];
722424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
724424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return "UNKNOWN";
725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
727424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaSourcePlayer::IsEventPending(PendingEventFlags event) const {
728424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return pending_event_ & event;
729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
731424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::SetPendingEvent(PendingEventFlags event) {
732424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
733424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_NE(event, NO_EVENT_PENDING);
734424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!IsEventPending(event));
735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
736424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pending_event_ |= event;
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
739424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
740424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
741424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_NE(event, NO_EVENT_PENDING);
742d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(IsEventPending(event)) << GetEventName(event);
743424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
744424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pending_event_ &= ~event;
745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
74746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaSourcePlayer::RetryDecoderCreation(bool audio, bool video) {
74846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (audio)
74946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    is_waiting_for_audio_decoder_ = false;
75046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (video)
75146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    is_waiting_for_video_decoder_ = false;
75246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (IsEventPending(DECODER_CREATION_EVENT_PENDING))
75346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ProcessPendingEvents();
75446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
75546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
75646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaSourcePlayer::OnKeyAdded() {
75746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
75846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!is_waiting_for_key_)
75946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
76046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
76146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  is_waiting_for_key_ = false;
76246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (playing_)
76346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    StartInternal();
76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
76546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
76646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaSourcePlayer::OnCdmUnset() {
76746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(drm_bridge_);
7691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xhwang): Currently this is only called during teardown. Support full
7701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // detachment of CDM during playback. This will be needed when we start to
7711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // support setMediaKeys(0) (see http://crbug.com/330324), or when we release
7721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MediaDrm when the video is paused, or when the device goes to sleep (see
7731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // http://crbug.com/272421).
774f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  audio_decoder_job_->SetDrmBridge(NULL);
775f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  video_decoder_job_->SetDrmBridge(NULL);
7761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cdm_registration_id_ = 0;
777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  drm_bridge_ = NULL;
778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace media
781