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/base/buffering_frame_provider.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback_helpers.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/buffering_state.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/decoder_buffer_base.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/bind_to_current_loop.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/buffers.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromecast { 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media { 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBufferingFrameProvider::BufferWithConfig::BufferWithConfig( 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<DecoderBufferBase>& buffer, 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ::media::AudioDecoderConfig& audio_config, 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ::media::VideoDecoderConfig& video_config) 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : buffer_(buffer), 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_config_(audio_config), 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_config_(video_config) { 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBufferingFrameProvider::BufferWithConfig::~BufferWithConfig() { 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBufferingFrameProvider::BufferingFrameProvider( 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<CodedFrameProvider> coded_frame_provider, 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t max_buffer_size, 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t max_frame_size, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const FrameBufferedCB& frame_buffered_cb) 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : coded_frame_provider_(coded_frame_provider.Pass()), 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_request_(false), 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_eos_(false), 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_buffer_size_(0), 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_buffer_size_(max_buffer_size), 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_frame_size_(max_frame_size), 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci frame_buffered_cb_(frame_buffered_cb), 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this), 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_this_(weak_factory_.GetWeakPtr()) { 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_LE(max_frame_size, max_buffer_size); 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread_checker_.DetachFromThread(); 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBufferingFrameProvider::~BufferingFrameProvider() { 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Required since some weak pointers might be released in the destructor. 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BufferingFrameProvider::Read(const ReadCB& read_cb) { 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!read_cb.is_null()); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_cb_ = read_cb; 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CompleteReadIfNeeded(); 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RequestBufferIfNeeded(); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BufferingFrameProvider::Flush(const base::Closure& flush_cb) { 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Invalidate all the buffers that belong to this media timeline. 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This is needed since, even though |coded_frame_provider_| is flushed later 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // in this function, there might be a pending task holding onto a buffer. 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.InvalidateWeakPtrs(); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Create a new valid weak pointer that is used for the next media timeline. 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_this_ = weak_factory_.GetWeakPtr(); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_request_ = false; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_eos_ = false; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_list_.clear(); 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_buffer_size_ = 0; 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_cb_.Reset(); 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci coded_frame_provider_->Flush(flush_cb); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BufferingFrameProvider::OnNewBuffer( 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<DecoderBufferBase>& buffer, 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ::media::AudioDecoderConfig& audio_config, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ::media::VideoDecoderConfig& video_config) { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_request_ = false; 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_list_.push_back( 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BufferWithConfig(buffer, audio_config, video_config)); 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (buffer->end_of_stream()) { 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_eos_ = true; 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_buffer_size_ += buffer->data_size(); 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!frame_buffered_cb_.is_null()) { 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the next upcoming frame is possibly filling the whole buffer, 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // then the buffer is considered as having reached its max capacity. 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool max_capacity_flag = 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (total_buffer_size_ + max_frame_size_ >= max_buffer_size_); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci frame_buffered_cb_.Run(buffer, max_capacity_flag); 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RequestBufferIfNeeded(); 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CompleteReadIfNeeded(); 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BufferingFrameProvider::RequestBufferIfNeeded() { 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (is_pending_request_) 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (is_eos_ || total_buffer_size_ >= max_buffer_size_) 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_pending_request_ = true; 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci coded_frame_provider_->Read(BindToCurrentLoop( 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&BufferingFrameProvider::OnNewBuffer, weak_this_))); 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BufferingFrameProvider::CompleteReadIfNeeded() { 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_cb_.is_null()) 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (buffer_list_.empty()) 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BufferWithConfig buffer_with_config(buffer_list_.front()); 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_list_.pop_front(); 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!buffer_with_config.buffer()->end_of_stream()) 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_buffer_size_ -= buffer_with_config.buffer()->data_size(); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&read_cb_).Run( 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_with_config.buffer(), 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_with_config.audio_config(), 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_with_config.video_config()); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace media 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace chromecast 141