11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/filters/demuxer_stream_adapter.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback_helpers.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/single_thread_task_runner.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/cma_logging.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/decoder_buffer_adapter.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/media_task_runner.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/bind_to_current_loop.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/buffers.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/decoder_buffer.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/demuxer_stream.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromecast { 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media { 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass DummyMediaTaskRunner : public MediaTaskRunner { 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DummyMediaTaskRunner( 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // MediaTaskRunner implementation. 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool PostMediaTask( 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const tracked_objects::Location& from_here, 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::Closure& task, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta timestamp) OVERRIDE; 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual ~DummyMediaTaskRunner(); 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<base::SingleThreadTaskRunner> const task_runner_; 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(DummyMediaTaskRunner); 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDummyMediaTaskRunner::DummyMediaTaskRunner( 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : task_runner_(task_runner) { 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDummyMediaTaskRunner::~DummyMediaTaskRunner() { 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool DummyMediaTaskRunner::PostMediaTask( 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const tracked_objects::Location& from_here, 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::Closure& task, 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta timestamp) { 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return task_runner_->PostTask(from_here, task); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDemuxerStreamAdapter::DemuxerStreamAdapter( 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<BalancedMediaTaskRunnerFactory>& 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_factory, 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ::media::DemuxerStream* demuxer_stream) 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : task_runner_(task_runner), 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_factory_(media_task_runner_factory), 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_(new DummyMediaTaskRunner(task_runner)), 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_(demuxer_stream), 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_read_(false), 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_demuxer_read_(false), 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this), 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_this_(weak_factory_.GetWeakPtr()) { 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResetMediaTaskRunner(); 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread_checker_.DetachFromThread(); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDemuxerStreamAdapter::~DemuxerStreamAdapter() { 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Needed since we use weak pointers: 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // weak pointers must be invalidated on the same thread. 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DemuxerStreamAdapter::Read(const ReadCB& read_cb) { 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(flush_cb_.is_null()); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Support only one read at a time. 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!is_pending_read_); 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_read_ = true; 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadInternal(read_cb); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DemuxerStreamAdapter::ReadInternal(const ReadCB& read_cb) { 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool may_run_in_future = media_task_runner_->PostMediaTask( 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&DemuxerStreamAdapter::RequestBuffer, weak_this_, read_cb), 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_pts_); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(may_run_in_future); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DemuxerStreamAdapter::Flush(const base::Closure& flush_cb) { 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CMALOG(kLogControl) << __FUNCTION__; 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Flush cancels any pending read. 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_read_ = false; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Reset the decoder configurations. 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_config_ = ::media::AudioDecoderConfig(); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_config_ = ::media::VideoDecoderConfig(); 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Create a new media task runner for the upcoming media timeline. 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResetMediaTaskRunner(); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(flush_cb_.is_null()); 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (is_pending_demuxer_read_) { 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If there is a pending demuxer read, the implicit contract 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // is that the pending read must be completed before invoking the 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // flush callback. 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flush_cb_ = flush_cb; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // At this point, there is no more pending demuxer read, 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // so all the previous tasks associated with the current timeline 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // can be cancelled. 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.InvalidateWeakPtrs(); 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_this_ = weak_factory_.GetWeakPtr(); 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CMALOG(kLogControl) << "Flush done"; 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flush_cb.Run(); 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DemuxerStreamAdapter::ResetMediaTaskRunner() { 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_pts_ = ::media::kNoTimestamp(); 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (media_task_runner_factory_.get()) { 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_ = 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci media_task_runner_factory_->CreateMediaTaskRunner(task_runner_); 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DemuxerStreamAdapter::RequestBuffer(const ReadCB& read_cb) { 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_demuxer_read_ = true; 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_->Read(::media::BindToCurrentLoop( 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&DemuxerStreamAdapter::OnNewBuffer, weak_this_, read_cb))); 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DemuxerStreamAdapter::OnNewBuffer( 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ReadCB& read_cb, 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ::media::DemuxerStream::Status status, 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr< ::media::DecoderBuffer>& input) { 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_demuxer_read_ = false; 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Just discard the buffer in the flush stage. 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!flush_cb_.is_null()) { 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CMALOG(kLogControl) << "Flush done"; 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&flush_cb_).Run(); 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (status == ::media::DemuxerStream::kAborted) { 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(input.get() == NULL); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (status == ::media::DemuxerStream::kConfigChanged) { 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(input.get() == NULL); 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (demuxer_stream_->type() == ::media::DemuxerStream::VIDEO) 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_config_ = demuxer_stream_->video_decoder_config(); 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (demuxer_stream_->type() == ::media::DemuxerStream::AUDIO) 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_config_ = demuxer_stream_->audio_decoder_config(); 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Got a new config, but we still need to get a frame. 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadInternal(read_cb); 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(status, ::media::DemuxerStream::kOk); 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Updates the timestamp used for task scheduling. 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!input->end_of_stream() && 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci input->timestamp() != ::media::kNoTimestamp() && 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (max_pts_ == ::media::kNoTimestamp() || input->timestamp() > max_pts_)) { 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_pts_ = input->timestamp(); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Provides the buffer as well as possibly valid audio and video configs. 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_read_ = false; 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<DecoderBufferBase> buffer(new DecoderBufferAdapter(input)); 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_cb.Run(buffer, audio_config_, video_config_); 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Back to the default audio/video config: 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // an invalid audio/video config means there is no config update. 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (audio_config_.IsValidConfig()) 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_config_ = ::media::AudioDecoderConfig(); 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (video_config_.IsValidConfig()) 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_config_ = ::media::VideoDecoderConfig(); 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace media 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace chromecast 208