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

Unified 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: Fix copyright year. Created 8 years, 11 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/audio_renderer_base.cc
diff --git a/media/filters/audio_renderer_base.cc b/media/filters/audio_renderer_base.cc
index b80536a219ab468d2fcc0f3fadb6d2752b1feead..23c17a92a3f60301eead37ad8cbad62021fffaa1 100644
--- a/media/filters/audio_renderer_base.cc
+++ b/media/filters/audio_renderer_base.cc
@@ -67,6 +67,7 @@ void AudioRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) {
base::AutoLock auto_lock(lock_);
DCHECK_EQ(kPaused, state_);
DCHECK(!pending_read_) << "Pending read must complete before seeking";
+ DCHECK(pause_callback_.is_null());
DCHECK(seek_cb_.is_null());
state_ = kSeeking;
seek_cb_ = cb;
@@ -144,46 +145,46 @@ void AudioRendererBase::DecodedAudioReady(scoped_refptr<Buffer> buffer) {
CHECK(pending_read_);
pending_read_ = false;
- // TODO(scherkus): this happens due to a race, primarily because Stop() is a
- // synchronous call when it should be asynchronous and accept a callback.
- // Refer to http://crbug.com/16059
- if (state_ == kStopped) {
- return;
- }
-
- // Don't enqueue an end-of-stream buffer because it has no data, otherwise
- // discard decoded audio data until we reach our desired seek timestamp.
- if (buffer->IsEndOfStream()) {
+ if (buffer && buffer->IsEndOfStream()) {
recieved_end_of_stream_ = true;
- // Transition to kPlaying if we are currently handling an underflow since no
- // more data will be arriving.
+ // Transition to kPlaying if we are currently handling an underflow since
+ // no more data will be arriving.
if (state_ == kUnderflow || state_ == kRebuffering)
state_ = kPlaying;
- } else if (state_ == kSeeking && !buffer->IsEndOfStream() &&
- (buffer->GetTimestamp() + buffer->GetDuration()) <
- seek_timestamp_) {
- ScheduleRead_Locked();
- } else {
- // Note: Calling this may schedule more reads.
- algorithm_->EnqueueBuffer(buffer);
}
- // Check for our preroll complete condition.
- if (state_ == kSeeking) {
- DCHECK(!seek_cb_.is_null());
- if (algorithm_->IsQueueFull() || recieved_end_of_stream_) {
- // Transition into paused whether we have data in |algorithm_| or not.
- // FillBuffer() will play silence if there's nothing to fill.
+ switch (state_) {
+ case kUninitialized:
+ NOTREACHED();
+ return;
+ case kPaused:
+ if (buffer && !buffer->IsEndOfStream())
+ algorithm_->EnqueueBuffer(buffer);
+ DCHECK(!pending_read_);
+ ResetAndRunCB(&pause_callback_);
+ return;
+ case kSeeking:
+ if (IsBeforeSeekTime(buffer)) {
+ ScheduleRead_Locked();
+ return;
+ }
+ if (buffer && !buffer->IsEndOfStream()) {
+ algorithm_->EnqueueBuffer(buffer);
+ if (!algorithm_->IsQueueFull())
+ return;
+ }
state_ = kPaused;
ResetAndRunCB(&seek_cb_, PIPELINE_OK);
- }
- } else if (state_ == kPaused && !pending_read_) {
- // No more pending read! We're now officially "paused".
- if (!pause_callback_.is_null()) {
- pause_callback_.Run();
- pause_callback_.Reset();
- }
+ return;
+ case kPlaying:
+ case kUnderflow:
+ case kRebuffering:
+ if (buffer && !buffer->IsEndOfStream())
+ algorithm_->EnqueueBuffer(buffer);
+ return;
+ case kStopped:
+ return;
}
}
@@ -278,7 +279,7 @@ void AudioRendererBase::SignalEndOfStream() {
void AudioRendererBase::ScheduleRead_Locked() {
lock_.AssertAcquired();
- if (pending_read_)
+ if (pending_read_ || state_ == kPaused)
return;
pending_read_ = true;
decoder_->Read(read_cb_);
@@ -294,4 +295,9 @@ float AudioRendererBase::GetPlaybackRate() {
return algorithm_->playback_rate();
}
+bool AudioRendererBase::IsBeforeSeekTime(const scoped_refptr<Buffer>& buffer) {
+ return (state_ == kSeeking) && buffer && !buffer->IsEndOfStream() &&
+ (buffer->GetTimestamp() + buffer->GetDuration()) < seek_timestamp_;
+}
+
} // namespace media
« 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