buffering_frame_provider.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chromecast/media/cma/base/buffering_frame_provider.h" 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromecast/media/cma/base/buffering_state.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromecast/media/cma/base/decoder_buffer_base.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/bind_to_current_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/buffers.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromecast { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferingFrameProvider::BufferWithConfig::BufferWithConfig( 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBufferBase>& buffer, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ::media::AudioDecoderConfig& audio_config, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ::media::VideoDecoderConfig& video_config) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : buffer_(buffer), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_config_(audio_config), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_config_(video_config) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferingFrameProvider::BufferWithConfig::~BufferWithConfig() { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferingFrameProvider::BufferingFrameProvider( 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CodedFrameProvider> coded_frame_provider, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_buffer_size, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_frame_size, 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const FrameBufferedCB& frame_buffered_cb) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : coded_frame_provider_(coded_frame_provider.Pass()), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pending_request_(false), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_eos_(false), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_buffer_size_(0), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_buffer_size_(max_buffer_size), 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_frame_size_(max_frame_size), 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame_buffered_cb_(frame_buffered_cb), 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) weak_factory_(this), 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) weak_this_(weak_factory_.GetWeakPtr()) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(max_frame_size, max_buffer_size); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_checker_.DetachFromThread(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferingFrameProvider::~BufferingFrameProvider() { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Required since some weak pointers might be released in the destructor. 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BufferingFrameProvider::Read(const ReadCB& read_cb) { 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!read_cb.is_null()); 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) read_cb_ = read_cb; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteReadIfNeeded(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestBufferIfNeeded(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BufferingFrameProvider::Flush(const base::Closure& flush_cb) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invalidate all the buffers that belong to this media timeline. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is needed since, even though |coded_frame_provider_| is flushed later 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in this function, there might be a pending task holding onto a buffer. 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_factory_.InvalidateWeakPtrs(); 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a new valid weak pointer that is used for the next media timeline. 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_this_ = weak_factory_.GetWeakPtr(); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_pending_request_ = false; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_eos_ = false; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_list_.clear(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_buffer_size_ = 0; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_cb_.Reset(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_frame_provider_->Flush(flush_cb); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferingFrameProvider::OnNewBuffer( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBufferBase>& buffer, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ::media::AudioDecoderConfig& audio_config, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ::media::VideoDecoderConfig& video_config) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pending_request_ = false; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_list_.push_back( 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BufferWithConfig(buffer, audio_config, video_config)); 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (buffer->end_of_stream()) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_eos_ = true; 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) total_buffer_size_ += buffer->data_size(); 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!frame_buffered_cb_.is_null()) { 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // If the next upcoming frame is possibly filling the whole buffer, 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // then the buffer is considered as having reached its max capacity. 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool max_capacity_flag = 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu (total_buffer_size_ + max_frame_size_ >= max_buffer_size_); 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu frame_buffered_cb_.Run(buffer, max_capacity_flag); 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RequestBufferIfNeeded(); 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CompleteReadIfNeeded(); 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferingFrameProvider::RequestBufferIfNeeded() { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_pending_request_) 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_eos_ || total_buffer_size_ >= max_buffer_size_) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_pending_request_ = true; 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) coded_frame_provider_->Read(BindToCurrentLoop( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BufferingFrameProvider::OnNewBuffer, weak_this_))); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferingFrameProvider::CompleteReadIfNeeded() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_cb_.is_null()) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_list_.empty()) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferWithConfig buffer_with_config(buffer_list_.front()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_list_.pop_front(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!buffer_with_config.buffer()->end_of_stream()) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_buffer_size_ -= buffer_with_config.buffer()->data_size(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ResetAndReturn(&read_cb_).Run( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_with_config.buffer(), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_with_config.audio_config(), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_with_config.video_config()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace media 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace chromecast 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch