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