1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/renderer/media/android/media_source_delegate.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <limits> 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <string> 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <vector> 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/media/android/renderer_demuxer_android.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/android/demuxer_stream_player_params.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/bind_to_current_loop.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/demuxer_stream.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/media_log.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/webmediaplayer_util.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/webmediasource_impl.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/filters/chunk_demuxer.h" 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/filters/decrypting_demuxer_stream.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebRuntimeFeatures.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using media::DemuxerStream; 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using media::DemuxerConfigs; 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using media::DemuxerData; 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMediaPlayer; 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The size of the access unit to transfer in an IPC in case of MediaSource. 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// 4: approximately 64ms of content in 60 fps movies. 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const size_t kAccessUnitSizeForMediaSource = 4; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const uint8 kVorbisPadding[] = { 0xff, 0xff, 0xff, 0xff }; 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error) { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MediaSourceDelegate::MediaSourceDelegate( 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RendererDemuxerAndroid* demuxer_client, 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int demuxer_client_id, 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<media::MediaLog> media_log) 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : demuxer_client_(demuxer_client), 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) demuxer_client_id_(demuxer_client_id), 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media_log_(media_log), 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_demuxer_ready_(false), 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_stream_(NULL), 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_stream_(NULL), 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) seeking_(false), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_video_encrypted_(false), 611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) doing_browser_seek_(false), 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_seek_time_(media::kNoTimestamp()), 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) expecting_regular_seek_(false), 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) access_unit_size_(0), 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci main_task_runner_(base::MessageLoopProxy::current()), 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_(media_task_runner), 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) main_weak_factory_(this), 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) media_weak_factory_(this), 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) main_weak_this_(main_weak_factory_.GetWeakPtr()) { 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaSourceDelegate::~MediaSourceDelegate() { 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!chunk_demuxer_); 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!demuxer_client_); 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!audio_decrypting_demuxer_stream_); 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!video_decrypting_demuxer_stream_); 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!audio_stream_); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!video_stream_); 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaSourceDelegate::Stop(const base::Closure& stop_cb) { 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!chunk_demuxer_) { 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!demuxer_client_); 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) duration_change_cb_.Reset(); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) update_network_state_cb_.Reset(); 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media_source_opened_cb_.Reset(); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) main_weak_factory_.InvalidateWeakPtrs(); 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!main_weak_factory_.HasWeakPtrs()); 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chunk_demuxer_->Shutdown(); 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Continue to stop objects on the media thread. 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_->PostTask( 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind( 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &MediaSourceDelegate::StopDemuxer, base::Unretained(this), stop_cb)); 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaSourceDelegate::IsVideoEncrypted() { 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::AutoLock auto_lock(is_video_encrypted_lock_); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return is_video_encrypted_; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::Time MediaSourceDelegate::GetTimelineOffset() const { 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!chunk_demuxer_) 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return base::Time(); 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return chunk_demuxer_->GetTimelineOffset(); 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaSourceDelegate::StopDemuxer(const base::Closure& stop_cb) { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(2) << __FUNCTION__; 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(chunk_demuxer_); 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) demuxer_client_->RemoveDelegate(demuxer_client_id_); 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) demuxer_client_ = NULL; 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_stream_ = NULL; 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_stream_ = NULL; 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(xhwang): Figure out if we need to Reset the DDSs after Seeking or 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // before destroying them. 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_decrypting_demuxer_stream_.reset(); 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_decrypting_demuxer_stream_.reset(); 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_weak_factory_.InvalidateWeakPtrs(); 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!media_weak_factory_.HasWeakPtrs()); 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chunk_demuxer_->Stop(); 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chunk_demuxer_.reset(); 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |this| may be destroyed at this point in time as a result of running 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |stop_cb|. 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stop_cb.Run(); 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaSourceDelegate::InitializeMediaSource( 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const MediaSourceOpenedCB& media_source_opened_cb, 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const media::Demuxer::NeedKeyCB& need_key_cb, 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const media::SetDecryptorReadyCB& set_decryptor_ready_cb, 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const UpdateNetworkStateCB& update_network_state_cb, 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const DurationChangeCB& duration_change_cb) { 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!media_source_opened_cb.is_null()); 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media_source_opened_cb_ = media_source_opened_cb; 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) need_key_cb_ = need_key_cb; 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch set_decryptor_ready_cb_ = set_decryptor_ready_cb; 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb); 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) duration_change_cb_ = duration_change_cb; 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch access_unit_size_ = kAccessUnitSizeForMediaSource; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chunk_demuxer_.reset(new media::ChunkDemuxer( 165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch media::BindToCurrentLoop( 166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&MediaSourceDelegate::OnDemuxerOpened, main_weak_this_)), 167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch media::BindToCurrentLoop( 168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&MediaSourceDelegate::OnNeedKey, main_weak_this_)), 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&LogMediaSourceError, media_log_), 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch false)); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |this| will be retained until StopDemuxer() is posted, so Unretained() is 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // safe here. 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_->PostTask(FROM_HERE, 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&MediaSourceDelegate::InitializeDemuxer, 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Unretained(this))); 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaSourceDelegate::InitializeDemuxer() { 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) demuxer_client_->AddDelegate(demuxer_client_id_, this); 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chunk_demuxer_->Initialize(this, 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&MediaSourceDelegate::OnDemuxerInitDone, 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media_weak_factory_.GetWeakPtr()), 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false); 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)blink::WebTimeRanges MediaSourceDelegate::Buffered() const { 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return media::ConvertToWebTimeRanges(buffered_time_ranges_); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::DecodedFrameCount() const { 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return statistics_.video_frames_decoded; 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::DroppedFrameCount() const { 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return statistics_.video_frames_dropped; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::AudioDecodedByteCount() const { 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return statistics_.audio_bytes_decoded; 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::VideoDecodedByteCount() const { 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return statistics_.video_bytes_decoded; 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::CancelPendingSeek(const base::TimeDelta& seek_time) { 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : " 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << demuxer_client_id_; 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!chunk_demuxer_) 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) { 2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Remember to trivially finish any newly arriving browser seek requests 2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // that may arrive prior to the next regular seek request. 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock auto_lock(seeking_lock_); 2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) expecting_regular_seek_ = true; 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Cancel any previously expected or in-progress regular or browser seek. 2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // It is possible that we have just finished the seek, but caller does 2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // not know this yet. It is still safe to cancel in this case because the 2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // caller will always call StartWaitingForSeek() when it is notified of 2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the finished seek. 2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chunk_demuxer_->CancelPendingSeek(seek_time); 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::StartWaitingForSeek( 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::TimeDelta& seek_time) { 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : " 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << demuxer_client_id_; 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!chunk_demuxer_) 2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool cancel_browser_seek = false; 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) { 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Remember to trivially finish any newly arriving browser seek requests 2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // that may arrive prior to the next regular seek request. 2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock auto_lock(seeking_lock_); 2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) expecting_regular_seek_ = true; 2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Remember to cancel any in-progress browser seek. 2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (seeking_) { 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(doing_browser_seek_); 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cancel_browser_seek = true; 2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (cancel_browser_seek) 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chunk_demuxer_->CancelPendingSeek(seek_time); 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chunk_demuxer_->StartWaitingForSeek(seek_time); 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourceDelegate::Seek( 2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const base::TimeDelta& seek_time, bool is_browser_seek) { 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ", " 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << (is_browser_seek ? "browser seek" : "regular seek") << ") : " 26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << demuxer_client_id_; 26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::TimeDelta internal_seek_time = seek_time; 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) { 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock auto_lock(seeking_lock_); 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!seeking_); 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) seeking_ = true; 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) doing_browser_seek_ = is_browser_seek; 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (doing_browser_seek_ && (!chunk_demuxer_ || expecting_regular_seek_)) { 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Trivially finish the browser seek without actually doing it. Reads will 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // continue to be |kAborted| until the next regular seek is done. Browser 2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // seeking is not supported unless using a ChunkDemuxer; browser seeks are 2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // trivially finished if |chunk_demuxer_| is NULL. 2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) seeking_ = false; 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) doing_browser_seek_ = false; 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) demuxer_client_->DemuxerSeekDone(demuxer_client_id_, seek_time); 2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (doing_browser_seek_) { 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) internal_seek_time = FindBufferedBrowserSeekTime_Locked(seek_time); 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_seek_time_ = internal_seek_time; 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) expecting_regular_seek_ = false; 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_seek_time_ = media::kNoTimestamp(); 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Prepare |chunk_demuxer_| for browser seek. 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (is_browser_seek) { 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chunk_demuxer_->CancelPendingSeek(internal_seek_time); 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chunk_demuxer_->StartWaitingForSeek(internal_seek_time); 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SeekInternal(internal_seek_time); 30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::SeekInternal(const base::TimeDelta& seek_time) { 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(IsSeeking()); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chunk_demuxer_->Seek(seek_time, base::Bind( 30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &MediaSourceDelegate::OnDemuxerSeekDone, 30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) media_weak_factory_.GetWeakPtr())); 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta end) { 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buffered_time_ranges_.Add(start, end); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << duration.InSecondsF() << ") : " 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << demuxer_client_id_; 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Force duration change notification to be async to avoid reentrancy into 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // ChunkDemxuer. 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci main_task_runner_->PostTask(FROM_HERE, base::Bind( 323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &MediaSourceDelegate::OnDurationChanged, main_weak_this_, duration)); 324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaSourceDelegate::OnDurationChanged(const base::TimeDelta& duration) { 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (demuxer_client_) 329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) demuxer_client_->DurationChanged(demuxer_client_id_, duration); 3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!duration_change_cb_.is_null()) 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) duration_change_cb_.Run(duration); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << type << ") : " << demuxer_client_id_; 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsSeeking()) 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; // Drop the request during seeking. 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The access unit size should have been initialized properly at this stage. 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_GT(access_unit_size_, 0u); 343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<DemuxerData> data(new DemuxerData()); 344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->type = type; 345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units.resize(access_unit_size_); 346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ReadFromDemuxerStream(type, data.Pass(), 0); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourceDelegate::ReadFromDemuxerStream(media::DemuxerStream::Type type, 350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<DemuxerData> data, 351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t index) { 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // DemuxerStream::Read() always returns the read callback asynchronously. 354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DemuxerStream* stream = 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_; 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) stream->Read(base::Bind( 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &MediaSourceDelegate::OnBufferReady, 35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_weak_factory_.GetWeakPtr(), type, base::Passed(&data), index)); 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::OnBufferReady( 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media::DemuxerStream::Type type, 363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<DemuxerData> data, 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t index, 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream::Status status, 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const scoped_refptr<media::DecoderBuffer>& buffer) { 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << index << ", " << status << ", " 369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << ((!buffer || buffer->end_of_stream()) ? 370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) -1 : buffer->timestamp().InMilliseconds()) 371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << ") : " << demuxer_client_id_; 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(chunk_demuxer_); 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // No new OnReadFromDemuxer() will be called during seeking. So this callback 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // must be from previous OnReadFromDemuxer() call and should be ignored. 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsSeeking()) { 377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << ": Ignore previous read during seeking."; 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool is_audio = (type == DemuxerStream::AUDIO); 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status != DemuxerStream::kAborted && 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) index >= data->access_units.size()) { 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "The internal state inconsistency onBufferReady: " 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << (is_audio ? "Audio" : "Video") << ", index " << index 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << ", size " << data->access_units.size() 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ", status " << static_cast<int>(status); 388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NOTREACHED(); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (status) { 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case DemuxerStream::kAborted: 394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : Aborted"; 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].status = status; 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units.resize(index + 1); 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case DemuxerStream::kConfigChanged: 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK((is_audio && audio_stream_) || (!is_audio && video_stream_)); 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data->demuxer_configs.resize(1); 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(GetDemuxerConfigFromStream(&data->demuxer_configs[0], is_audio)); 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_audio) { 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Size size = data->demuxer_configs[0].video_size; 405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DVLOG(1) << "Video config is changed: " << size.width() << "x" 406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << size.height(); 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].status = status; 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units.resize(index + 1); 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case DemuxerStream::kOk: 413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].status = status; 414ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (buffer->end_of_stream()) { 415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].end_of_stream = true; 416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units.resize(index + 1); 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(ycheo): We assume that the inputed stream will be decoded 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // right away. 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Need to implement this properly using MediaPlayer.OnInfoListener. 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (is_audio) { 423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch statistics_.audio_bytes_decoded += buffer->data_size(); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch statistics_.video_bytes_decoded += buffer->data_size(); 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) statistics_.video_frames_decoded++; 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].timestamp = buffer->timestamp(); 4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data->access_units[index].data.assign( 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer->data(), buffer->data() + buffer->data_size()); 43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Vorbis needs 4 extra bytes padding on Android. Check 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NuMediaExtractor.cpp in Android source code. 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_audio && media::kCodecVorbis == 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_stream_->audio_decoder_config().codec()) { 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].data.insert( 437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].data.end(), kVorbisPadding, 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kVorbisPadding + 4); 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (buffer->decrypt_config()) { 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].key_id = std::vector<char>( 442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->decrypt_config()->key_id().begin(), 443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->decrypt_config()->key_id().end()); 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].iv = std::vector<char>( 445ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->decrypt_config()->iv().begin(), 446ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->decrypt_config()->iv().end()); 447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data->access_units[index].subsamples = 448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->decrypt_config()->subsamples(); 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (++index < data->access_units.size()) { 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ReadFromDemuxerStream(type, data.Pass(), index); 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 460d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!IsSeeking() && demuxer_client_) 461d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) demuxer_client_->ReadFromDemuxerAck(demuxer_client_id_, *data); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) { 465d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; 4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |update_network_state_cb_| is bound to the main thread. 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status != media::PIPELINE_OK && !update_network_state_cb_.is_null()) 46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) update_network_state_cb_.Run(PipelineErrorToNetworkState(status)); 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaSourceDelegate::AddTextStream( 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::DemuxerStream* /* text_stream */ , 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const media::TextTrackConfig& /* config */ ) { 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(matthewjheaney): add text stream (http://crbug/322115). 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTIMPLEMENTED(); 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaSourceDelegate::RemoveTextStream( 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::DemuxerStream* /* text_stream */ ) { 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(matthewjheaney): remove text stream (http://crbug/322115). 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTIMPLEMENTED(); 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(chunk_demuxer_); 488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (status != media::PIPELINE_OK) { 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnDemuxerError(status); 491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_stream_ = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_stream_ = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); 496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (audio_stream_ && audio_stream_->audio_decoder_config().is_encrypted() && 4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch !set_decryptor_ready_cb_.is_null()) { 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InitAudioDecryptingDemuxerStream(); 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // InitVideoDecryptingDemuxerStream() will be called in 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // OnAudioDecryptingDemuxerStreamInitDone(). 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (video_stream_ && video_stream_->video_decoder_config().is_encrypted() && 5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch !set_decryptor_ready_cb_.is_null()) { 507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InitVideoDecryptingDemuxerStream(); 508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Notify demuxer ready when both streams are not encrypted. 512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_demuxer_ready_ = true; 513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NotifyDemuxerReady(); 514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { 5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!set_decryptor_ready_cb_.is_null()); 5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( 5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_, set_decryptor_ready_cb_)); 523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_decrypting_demuxer_stream_->Initialize( 524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_stream_, 5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone, 52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_weak_factory_.GetWeakPtr())); 527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { 5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!set_decryptor_ready_cb_.is_null()); 5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( 5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_, set_decryptor_ready_cb_)); 536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_decrypting_demuxer_stream_->Initialize( 537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_stream_, 5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone, 53958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_weak_factory_.GetWeakPtr())); 540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( 543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media::PipelineStatus status) { 5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 545d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(chunk_demuxer_); 547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (status != media::PIPELINE_OK) 549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_decrypting_demuxer_stream_.reset(); 550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_stream_ = audio_decrypting_demuxer_stream_.get(); 552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (video_stream_ && video_stream_->video_decoder_config().is_encrypted()) { 554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InitVideoDecryptingDemuxerStream(); 555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Try to notify demuxer ready when audio DDS initialization finished and 559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // video is not encrypted. 560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_demuxer_ready_ = true; 561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NotifyDemuxerReady(); 562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) media::PipelineStatus status) { 5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; 5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(chunk_demuxer_); 569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (status != media::PIPELINE_OK) 571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_decrypting_demuxer_stream_.reset(); 572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else 573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch video_stream_ = video_decrypting_demuxer_stream_.get(); 574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Try to notify demuxer ready when video DDS initialization finished. 576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_demuxer_ready_ = true; 577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NotifyDemuxerReady(); 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::OnDemuxerSeekDone(media::PipelineStatus status) { 5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 582d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; 5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(IsSeeking()); 584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status != media::PIPELINE_OK) { 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnDemuxerError(status); 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ResetAudioDecryptingDemuxerStream(); 591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { 5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 595d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (audio_decrypting_demuxer_stream_) { 597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch audio_decrypting_demuxer_stream_->Reset( 598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream, 59958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_weak_factory_.GetWeakPtr())); 60058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 60258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ResetVideoDecryptingDemuxerStream(); 604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { 6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 608d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (video_decrypting_demuxer_stream_) { 61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) video_decrypting_demuxer_stream_->Reset(base::Bind( 61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams, 61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_weak_factory_.GetWeakPtr())); 61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 61558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 61658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FinishResettingDecryptingDemuxerStreams(); 61758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 61858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 61958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams() { 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 621d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 6221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 6231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::AutoLock auto_lock(seeking_lock_); 6241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(seeking_); 6251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) seeking_ = false; 6261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) doing_browser_seek_ = false; 6271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) demuxer_client_->DemuxerSeekDone(demuxer_client_id_, browser_seek_time_); 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::NotifyDemuxerReady() { 6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 632d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; 633f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(is_demuxer_ready_); 634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 635424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<DemuxerConfigs> configs(new DemuxerConfigs()); 636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetDemuxerConfigFromStream(configs.get(), true); 637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetDemuxerConfigFromStream(configs.get(), false); 6380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch configs->duration = GetDuration(); 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 640d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (demuxer_client_) 641d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) demuxer_client_->DemuxerReady(demuxer_client_id_, *configs); 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::AutoLock auto_lock(is_video_encrypted_lock_); 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_video_encrypted_ = configs->is_video_encrypted; 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::TimeDelta MediaSourceDelegate::GetDuration() const { 6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!chunk_demuxer_) 6500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return media::kNoTimestamp(); 651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch double duration = chunk_demuxer_->GetDuration(); 6530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (duration == std::numeric_limits<double>::infinity()) 6540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return media::kInfiniteDuration(); 6550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return media::ConvertSecondsToTimestamp(duration); 657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::OnDemuxerOpened() { 6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (media_source_opened_cb_.is_null()) 66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 66390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_source_opened_cb_.Run(new media::WebMediaSourceImpl( 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourceDelegate::OnNeedKey(const std::string& type, 669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<uint8>& init_data) { 6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(main_task_runner_->BelongsToCurrentThread()); 671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (need_key_cb_.is_null()) 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) need_key_cb_.Run(type, init_data); 67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaSourceDelegate::IsSeeking() const { 6783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::AutoLock auto_lock(seeking_lock_); 6793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return seeking_; 6803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::TimeDelta MediaSourceDelegate::FindBufferedBrowserSeekTime_Locked( 6831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const base::TimeDelta& seek_time) const { 6841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) seeking_lock_.AssertAcquired(); 6851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(seeking_); 6861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(doing_browser_seek_); 6871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(chunk_demuxer_) << "Browser seek requested, but no chunk demuxer"; 6881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 6891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) media::Ranges<base::TimeDelta> buffered = 6901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chunk_demuxer_->GetBufferedRanges(); 6911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 6921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (size_t i = 0; i < buffered.size(); ++i) { 6931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::TimeDelta range_start = buffered.start(i); 6941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::TimeDelta range_end = buffered.end(i); 6951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (range_start <= seek_time) { 6961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (range_end >= seek_time) 6971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return seek_time; 6981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) continue; 6991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If the start of the next buffered range after |seek_time| is too far 7021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // into the future, do not jump forward. 7031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if ((range_start - seek_time) > base::TimeDelta::FromMilliseconds(100)) 7041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 7051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TODO(wolenetz): Remove possibility that this browser seek jumps 7071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // into future when the requested range is unbuffered but there is some 7081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // other buffered range after it. See http://crbug.com/304234. 7091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return range_start; 7101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // We found no range containing |seek_time| or beginning shortly after 7131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // |seek_time|. While possible that such data at and beyond the player's 7141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // current time have been garbage collected or removed by the web app, this is 7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // unlikely. This may cause unexpected playback stall due to seek pending an 7161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // append for a GOP prior to the last GOP demuxed. 7171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TODO(wolenetz): Remove the possibility for this seek to cause unexpected 7181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // player stall by replaying cached data since last keyframe in browser player 7191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // rather than issuing browser seek. See http://crbug.com/304234. 7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return seek_time; 7211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 7221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MediaSourceDelegate::GetDemuxerConfigFromStream( 724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media::DemuxerConfigs* configs, bool is_audio) { 7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(media_task_runner_->BelongsToCurrentThread()); 726f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!is_demuxer_ready_) 727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_audio && audio_stream_) { 729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media::AudioDecoderConfig config = audio_stream_->audio_decoder_config(); 730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->audio_codec = config.codec(); 731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->audio_channels = 732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media::ChannelLayoutToChannelCount(config.channel_layout()); 733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->audio_sampling_rate = config.samples_per_second(); 734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->is_audio_encrypted = config.is_encrypted(); 735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->audio_extra_data = std::vector<uint8>( 736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) config.extra_data(), config.extra_data() + config.extra_data_size()); 737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_audio && video_stream_) { 740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media::VideoDecoderConfig config = video_stream_->video_decoder_config(); 741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->video_codec = config.codec(); 742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->video_size = config.natural_size(); 743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->is_video_encrypted = config.is_encrypted(); 744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configs->video_extra_data = std::vector<uint8>( 745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) config.extra_data(), config.extra_data() + config.extra_data_size()); 746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace content 752