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