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

Side by Side Diff: media/filters/audio_renderer_base.cc

Issue 164403: Implemented end-of-stream callback for media::PipelineImpl. (Closed)
Patch Set: Baz Created 11 years, 4 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
« no previous file with comments | « media/filters/audio_renderer_base.h ('k') | media/filters/audio_renderer_base_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/audio_renderer_base.h" 5 #include "media/filters/audio_renderer_base.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "media/base/filter_host.h" 9 #include "media/base/filter_host.h"
10 #include "media/filters/audio_renderer_algorithm_ola.h" 10 #include "media/filters/audio_renderer_algorithm_ola.h"
11 11
12 namespace media { 12 namespace media {
13 13
14 AudioRendererBase::AudioRendererBase() 14 AudioRendererBase::AudioRendererBase()
15 : state_(kUninitialized), 15 : state_(kUninitialized),
16 recieved_end_of_stream_(false),
17 rendered_end_of_stream_(false),
16 pending_reads_(0) { 18 pending_reads_(0) {
17 } 19 }
18 20
19 AudioRendererBase::~AudioRendererBase() { 21 AudioRendererBase::~AudioRendererBase() {
20 // Stop() should have been called and |algorithm_| should have been destroyed. 22 // Stop() should have been called and |algorithm_| should have been destroyed.
21 DCHECK(state_ == kUninitialized || state_ == kStopped); 23 DCHECK(state_ == kUninitialized || state_ == kStopped);
22 DCHECK(!algorithm_.get()); 24 DCHECK(!algorithm_.get());
23 } 25 }
24 26
25 void AudioRendererBase::Play(FilterCallback* callback) { 27 void AudioRendererBase::Play(FilterCallback* callback) {
(...skipping 28 matching lines...) Expand all
54 56
55 void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { 57 void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) {
56 AutoLock auto_lock(lock_); 58 AutoLock auto_lock(lock_);
57 DCHECK_EQ(kPaused, state_); 59 DCHECK_EQ(kPaused, state_);
58 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; 60 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed";
59 state_ = kSeeking; 61 state_ = kSeeking;
60 seek_callback_.reset(callback); 62 seek_callback_.reset(callback);
61 63
62 // Throw away everything and schedule our reads. 64 // Throw away everything and schedule our reads.
63 last_fill_buffer_time_ = base::TimeDelta(); 65 last_fill_buffer_time_ = base::TimeDelta();
66 recieved_end_of_stream_ = false;
67 rendered_end_of_stream_ = false;
64 68
65 // |algorithm_| will request more reads. 69 // |algorithm_| will request more reads.
66 algorithm_->FlushBuffers(); 70 algorithm_->FlushBuffers();
67 } 71 }
68 72
69 void AudioRendererBase::Initialize(AudioDecoder* decoder, 73 void AudioRendererBase::Initialize(AudioDecoder* decoder,
70 FilterCallback* callback) { 74 FilterCallback* callback) {
71 DCHECK(decoder); 75 DCHECK(decoder);
72 DCHECK(callback); 76 DCHECK(callback);
73 DCHECK_EQ(kUninitialized, state_); 77 DCHECK_EQ(kUninitialized, state_);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 sample_rate, 111 sample_rate,
108 sample_bits, 112 sample_bits,
109 GetPlaybackRate(), 113 GetPlaybackRate(),
110 cb); 114 cb);
111 115
112 // Finally, execute the start callback. 116 // Finally, execute the start callback.
113 state_ = kPaused; 117 state_ = kPaused;
114 callback->Run(); 118 callback->Run();
115 } 119 }
116 120
121 bool AudioRendererBase::HasEnded() {
122 AutoLock auto_lock(lock_);
123 if (rendered_end_of_stream_) {
124 DCHECK(algorithm_->IsQueueEmpty())
125 << "Audio queue should be empty if we have rendered end of stream";
126 }
127 return recieved_end_of_stream_ && rendered_end_of_stream_;
128 }
129
117 void AudioRendererBase::OnReadComplete(Buffer* buffer_in) { 130 void AudioRendererBase::OnReadComplete(Buffer* buffer_in) {
118 AutoLock auto_lock(lock_); 131 AutoLock auto_lock(lock_);
119 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying); 132 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying);
120 DCHECK_GT(pending_reads_, 0u); 133 DCHECK_GT(pending_reads_, 0u);
121 --pending_reads_; 134 --pending_reads_;
122 135
123 // Don't enqueue an end-of-stream buffer because it has no data. 136 // Don't enqueue an end-of-stream buffer because it has no data.
124 if (!buffer_in->IsEndOfStream()) { 137 if (buffer_in->IsEndOfStream()) {
138 recieved_end_of_stream_ = true;
139 } else {
125 // Note: Calling this may schedule more reads. 140 // Note: Calling this may schedule more reads.
126 algorithm_->EnqueueBuffer(buffer_in); 141 algorithm_->EnqueueBuffer(buffer_in);
127 } 142 }
128 143
129 // Check for our preroll complete condition. 144 // Check for our preroll complete condition.
130 if (state_ == kSeeking) { 145 if (state_ == kSeeking) {
131 DCHECK(seek_callback_.get()); 146 DCHECK(seek_callback_.get());
132 if (algorithm_->IsQueueFull() || buffer_in->IsEndOfStream()) { 147 if (algorithm_->IsQueueFull() || recieved_end_of_stream_) {
133 // Transition into paused whether we have data in |algorithm_| or not. 148 // Transition into paused whether we have data in |algorithm_| or not.
134 // FillBuffer() will play silence if there's nothing to fill. 149 // FillBuffer() will play silence if there's nothing to fill.
135 state_ = kPaused; 150 state_ = kPaused;
136 seek_callback_->Run(); 151 seek_callback_->Run();
137 seek_callback_.reset(); 152 seek_callback_.reset();
138 } 153 }
139 } else if (state_ == kPaused && pending_reads_ == 0) { 154 } else if (state_ == kPaused && pending_reads_ == 0) {
140 // No more pending reads! We're now officially "paused". 155 // No more pending reads! We're now officially "paused".
141 if (pause_callback_.get()) { 156 if (pause_callback_.get()) {
142 pause_callback_->Run(); 157 pause_callback_->Run();
(...skipping 24 matching lines...) Expand all
167 return dest_written; 182 return dest_written;
168 } 183 }
169 184
170 // Save a local copy of last fill buffer time and reset the member. 185 // Save a local copy of last fill buffer time and reset the member.
171 last_fill_buffer_time = last_fill_buffer_time_; 186 last_fill_buffer_time = last_fill_buffer_time_;
172 last_fill_buffer_time_ = base::TimeDelta(); 187 last_fill_buffer_time_ = base::TimeDelta();
173 188
174 // Do the fill. 189 // Do the fill.
175 dest_written = algorithm_->FillBuffer(dest, dest_len); 190 dest_written = algorithm_->FillBuffer(dest, dest_len);
176 191
192 // Check if we finally reached end of stream by emptying |algorithm_|.
193 if (recieved_end_of_stream_ && algorithm_->IsQueueEmpty()) {
194 if (!rendered_end_of_stream_) {
195 rendered_end_of_stream_ = true;
196 host()->NotifyEnded();
197 }
198 }
199
177 // Get the current time. 200 // Get the current time.
178 last_fill_buffer_time_ = algorithm_->GetTime(); 201 last_fill_buffer_time_ = algorithm_->GetTime();
179 } 202 }
180 203
181 // Update the pipeline's time if it was set last time. 204 // Update the pipeline's time if it was set last time.
182 if (last_fill_buffer_time.InMicroseconds() > 0 && 205 if (last_fill_buffer_time.InMicroseconds() > 0 &&
183 last_fill_buffer_time != last_fill_buffer_time_) { 206 last_fill_buffer_time != last_fill_buffer_time_) {
184 // Adjust the |last_fill_buffer_time| with the playback delay. 207 // Adjust the |last_fill_buffer_time| with the playback delay.
185 // TODO(hclam): If there is a playback delay, the pipeline would not be 208 // TODO(hclam): If there is a playback delay, the pipeline would not be
186 // updated with a correct timestamp when the stream is played at the very 209 // updated with a correct timestamp when the stream is played at the very
(...skipping 30 matching lines...) Expand all
217 240
218 void AudioRendererBase::SetPlaybackRate(float playback_rate) { 241 void AudioRendererBase::SetPlaybackRate(float playback_rate) {
219 algorithm_->set_playback_rate(playback_rate); 242 algorithm_->set_playback_rate(playback_rate);
220 } 243 }
221 244
222 float AudioRendererBase::GetPlaybackRate() { 245 float AudioRendererBase::GetPlaybackRate() {
223 return algorithm_->playback_rate(); 246 return algorithm_->playback_rate();
224 } 247 }
225 248
226 } // namespace media 249 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_base.h ('k') | media/filters/audio_renderer_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698