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

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

Issue 9295020: Fix ChunkDemuxer seek deadlock (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: _ Created 8 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 } 60 }
61 if (!callback.is_null()) { 61 if (!callback.is_null()) {
62 callback.Run(); 62 callback.Run();
63 } 63 }
64 } 64 }
65 65
66 void AudioRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) { 66 void AudioRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) {
67 base::AutoLock auto_lock(lock_); 67 base::AutoLock auto_lock(lock_);
68 DCHECK_EQ(kPaused, state_); 68 DCHECK_EQ(kPaused, state_);
69 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 69 DCHECK(!pending_read_) << "Pending read must complete before seeking";
70 DCHECK(pause_callback_.is_null());
70 DCHECK(seek_cb_.is_null()); 71 DCHECK(seek_cb_.is_null());
71 state_ = kSeeking; 72 state_ = kSeeking;
72 seek_cb_ = cb; 73 seek_cb_ = cb;
73 seek_timestamp_ = time; 74 seek_timestamp_ = time;
74 75
75 // Throw away everything and schedule our reads. 76 // Throw away everything and schedule our reads.
76 last_fill_buffer_time_ = base::TimeDelta(); 77 last_fill_buffer_time_ = base::TimeDelta();
77 recieved_end_of_stream_ = false; 78 recieved_end_of_stream_ = false;
78 rendered_end_of_stream_ = false; 79 rendered_end_of_stream_ = false;
79 80
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 CHECK(pending_read_); 145 CHECK(pending_read_);
145 pending_read_ = false; 146 pending_read_ = false;
146 147
147 // TODO(scherkus): this happens due to a race, primarily because Stop() is a 148 // TODO(scherkus): this happens due to a race, primarily because Stop() is a
148 // synchronous call when it should be asynchronous and accept a callback. 149 // synchronous call when it should be asynchronous and accept a callback.
149 // Refer to http://crbug.com/16059 150 // Refer to http://crbug.com/16059
150 if (state_ == kStopped) { 151 if (state_ == kStopped) {
151 return; 152 return;
152 } 153 }
153 154
154 // Don't enqueue an end-of-stream buffer because it has no data, otherwise 155 if (buffer) {
Ami GONE FROM CHROMIUM 2012/01/27 23:44:58 that you can't reverse the test and early-return (
acolwell GONE FROM CHROMIUM 2012/01/29 03:00:41 Done. Cleaned things up nicely and uncovered an un
155 // discard decoded audio data until we reach our desired seek timestamp. 156 // Don't enqueue an end-of-stream buffer because it has no data, otherwise
156 if (buffer->IsEndOfStream()) { 157 // discard decoded audio data until we reach our desired seek timestamp.
157 recieved_end_of_stream_ = true; 158 if (buffer->IsEndOfStream()) {
159 recieved_end_of_stream_ = true;
158 160
159 // Transition to kPlaying if we are currently handling an underflow since no 161 // Transition to kPlaying if we are currently handling an underflow since
160 // more data will be arriving. 162 // no more data will be arriving.
161 if (state_ == kUnderflow || state_ == kRebuffering) 163 if (state_ == kUnderflow || state_ == kRebuffering)
162 state_ = kPlaying; 164 state_ = kPlaying;
163 } else if (state_ == kSeeking && !buffer->IsEndOfStream() && 165 } else if (state_ == kSeeking && !buffer->IsEndOfStream() &&
164 (buffer->GetTimestamp() + buffer->GetDuration()) < 166 (buffer->GetTimestamp() + buffer->GetDuration()) <
165 seek_timestamp_) { 167 seek_timestamp_) {
166 ScheduleRead_Locked(); 168 ScheduleRead_Locked();
167 } else { 169 } else {
168 // Note: Calling this may schedule more reads. 170 // Note: Calling this may schedule more reads.
169 algorithm_->EnqueueBuffer(buffer); 171 algorithm_->EnqueueBuffer(buffer);
172 }
170 } 173 }
171 174
172 // Check for our preroll complete condition. 175 // Check for our preroll complete condition.
173 if (state_ == kSeeking) { 176 if (state_ == kSeeking) {
174 DCHECK(!seek_cb_.is_null()); 177 DCHECK(!seek_cb_.is_null());
175 if (algorithm_->IsQueueFull() || recieved_end_of_stream_) { 178
176 // Transition into paused whether we have data in |algorithm_| or not. 179 // Transition to paused if we have enough data or have reached the end of
177 // FillBuffer() will play silence if there's nothing to fill. 180 // the stream. A NULL buffer also triggers the transition because it
181 // indicates that another seek will happen right after we complete this one
182 // so there is no point in continuing to preroll.
183 if (algorithm_->IsQueueFull() || recieved_end_of_stream_ || !buffer) {
178 state_ = kPaused; 184 state_ = kPaused;
179 ResetAndRunCB(&seek_cb_, PIPELINE_OK); 185 ResetAndRunCB(&seek_cb_, PIPELINE_OK);
180 } 186 }
181 } else if (state_ == kPaused && !pending_read_) { 187 } else if (state_ == kPaused && !pending_read_) {
182 // No more pending read! We're now officially "paused". 188 // No more pending read! We're now officially "paused".
183 if (!pause_callback_.is_null()) { 189 if (!pause_callback_.is_null()) {
184 pause_callback_.Run(); 190 pause_callback_.Run();
185 pause_callback_.Reset(); 191 pause_callback_.Reset();
186 } 192 }
187 } 193 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 base::AutoLock auto_lock(lock_); 287 base::AutoLock auto_lock(lock_);
282 algorithm_->SetPlaybackRate(playback_rate); 288 algorithm_->SetPlaybackRate(playback_rate);
283 } 289 }
284 290
285 float AudioRendererBase::GetPlaybackRate() { 291 float AudioRendererBase::GetPlaybackRate() {
286 base::AutoLock auto_lock(lock_); 292 base::AutoLock auto_lock(lock_);
287 return algorithm_->playback_rate(); 293 return algorithm_->playback_rate();
288 } 294 }
289 295
290 } // namespace media 296 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698