Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(315)

Side by Side Diff: chromecast/media/cma/base/buffering_frame_provider.cc

Issue 554893003: Introduce some buffering into the cast media pipeline. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address CR comments from patch set #1. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chromecast/media/cma/base/buffering_frame_provider.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "chromecast/media/cma/base/buffering_state.h"
10 #include "chromecast/media/cma/base/decoder_buffer_base.h"
11 #include "media/base/bind_to_current_loop.h"
12 #include "media/base/buffers.h"
13
14 namespace chromecast {
15 namespace media {
16
17 BufferingFrameProvider::BufferWithConfig::BufferWithConfig(
18 const scoped_refptr<DecoderBufferBase>& buffer,
19 const ::media::AudioDecoderConfig& audio_config,
20 const ::media::VideoDecoderConfig& video_config)
21 : buffer_(buffer),
22 audio_config_(audio_config),
23 video_config_(video_config) {
24 }
25
26 BufferingFrameProvider::BufferWithConfig::~BufferWithConfig() {
27 }
28
29 BufferingFrameProvider::BufferingFrameProvider(
30 scoped_ptr<CodedFrameProvider> coded_frame_provider,
31 size_t max_buffer_size,
32 size_t max_frame_size,
33 const FrameBufferedCB& frame_buffered_cb)
34 : coded_frame_provider_(coded_frame_provider.Pass()),
35 is_pending_request_(false),
36 is_eos_(false),
37 total_buffer_size_(0),
38 max_buffer_size_(max_buffer_size),
39 max_frame_size_(max_frame_size),
40 frame_buffered_cb_(frame_buffered_cb),
41 weak_factory_(new base::WeakPtrFactory<BufferingFrameProvider>(this)),
42 weak_this_(weak_factory_->GetWeakPtr()) {
43 DCHECK_LE(max_frame_size, max_buffer_size);
44 thread_checker_.DetachFromThread();
45 }
46
47 BufferingFrameProvider::~BufferingFrameProvider() {
48 // Required since some weak pointers might be released in the destructor.
49 DCHECK(thread_checker_.CalledOnValidThread());
50 }
51
52 void BufferingFrameProvider::Read(const ReadCB& read_cb) {
53 DCHECK(thread_checker_.CalledOnValidThread());
54
55 DCHECK(!read_cb.is_null());
56 read_cb_ = read_cb;
57
58 CompleteReadIfNeeded();
59
60 RequestBufferIfNeeded();
61 }
62
63 void BufferingFrameProvider::Flush(const base::Closure& flush_cb) {
64 DCHECK(thread_checker_.CalledOnValidThread());
65
66 // Invalidate all the buffers that belong to this media timeline.
67 // This is needed since even though, |coded_frame_provider_| is flushed later
gunsch 2014/09/09 20:11:11 Comma nit: "This is needed since, even though |cod
damienv1 2014/09/09 20:29:17 Done.
68 // in this function, there might be a pending task holding onto a buffer.
69 weak_factory_->InvalidateWeakPtrs();
70 weak_factory_.reset(new base::WeakPtrFactory<BufferingFrameProvider>(this));
gunsch 2014/09/09 20:11:11 do you need to actually reset this? shouldn't Inva
damienv1 2014/09/09 20:29:16 Yes, it should be enough. Somehow, I believed this
71 weak_this_ = weak_factory_->GetWeakPtr();
72
73 is_pending_request_ = false;
74 is_eos_ = false;
75 buffer_list_.clear();
76 total_buffer_size_ = 0;
77 read_cb_.Reset();
78 coded_frame_provider_->Flush(flush_cb);
79 }
80
81 void BufferingFrameProvider::OnNewBuffer(
82 const scoped_refptr<DecoderBufferBase>& buffer,
83 const ::media::AudioDecoderConfig& audio_config,
84 const ::media::VideoDecoderConfig& video_config) {
85 is_pending_request_ = false;
86 buffer_list_.push_back(
87 BufferWithConfig(buffer, audio_config, video_config));
88
89 if (buffer->end_of_stream()) {
90 is_eos_ = true;
91 } else {
92 total_buffer_size_ += buffer->data_size();
93 }
94
95 if (!frame_buffered_cb_.is_null()) {
96 // If the next upcoming frame is possibly filling the whole buffer,
97 // then the buffer is considered as having reached its max capacity.
98 bool max_capacity_flag =
99 (total_buffer_size_ + max_frame_size_ >= max_buffer_size_);
100 frame_buffered_cb_.Run(buffer, max_capacity_flag);
101 }
102
103 RequestBufferIfNeeded();
104
105 CompleteReadIfNeeded();
106 }
107
108 void BufferingFrameProvider::RequestBufferIfNeeded() {
109 if (is_pending_request_)
110 return;
111
112 if (is_eos_ || total_buffer_size_ >= max_buffer_size_)
113 return;
114
115 is_pending_request_ = true;
116 coded_frame_provider_->Read(BindToCurrentLoop(
117 base::Bind(&BufferingFrameProvider::OnNewBuffer, weak_this_)));
118 }
119
120 void BufferingFrameProvider::CompleteReadIfNeeded() {
121 if (read_cb_.is_null())
122 return;
123
124 if (buffer_list_.empty())
125 return;
126
127 BufferWithConfig buffer_with_config(buffer_list_.front());
128 buffer_list_.pop_front();
129 if (!buffer_with_config.buffer()->end_of_stream())
130 total_buffer_size_ -= buffer_with_config.buffer()->data_size();
131
132 base::ResetAndReturn(&read_cb_).Run(
133 buffer_with_config.buffer(),
134 buffer_with_config.audio_config(),
135 buffer_with_config.video_config());
136 }
137
138 } // namespace media
139 } // namespace chromecast
OLDNEW
« no previous file with comments | « chromecast/media/cma/base/buffering_frame_provider.h ('k') | chromecast/media/cma/base/buffering_frame_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698