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

Unified Diff: media/filters/chunk_demuxer.cc

Issue 16867010: Move pending seek cancellation logic from ChunkDemuxerStream to ChunkDemuxer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments Created 7 years, 6 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/chunk_demuxer.h ('k') | media/filters/chunk_demuxer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/chunk_demuxer.cc
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 768473c0f3ee9c8b0b79afe00887805943f48ac2..09fa2019682574b67911c5b146ec38ba316458c2 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -205,9 +205,8 @@ class ChunkDemuxerStream : public DemuxerStream {
const LogCB& log_cb);
virtual ~ChunkDemuxerStream();
- void StartWaitingForSeek();
+ void AbortReads();
void Seek(TimeDelta time);
- void CancelPendingSeek();
bool IsSeekWaitingForData() const;
// Add buffers to this stream. Buffers are stored in SourceBufferStreams,
@@ -245,9 +244,9 @@ class ChunkDemuxerStream : public DemuxerStream {
private:
enum State {
+ UNINITIALIZED,
RETURNING_DATA_FOR_READS,
- WAITING_FOR_SEEK,
- CANCELED,
+ RETURNING_ABORT_FOR_READS,
SHUTDOWN,
};
@@ -283,23 +282,23 @@ class ChunkDemuxerStream : public DemuxerStream {
ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config,
const LogCB& log_cb)
: type_(AUDIO),
- state_(RETURNING_DATA_FOR_READS) {
+ state_(UNINITIALIZED) {
stream_.reset(new SourceBufferStream(audio_config, log_cb));
}
ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config,
const LogCB& log_cb)
: type_(VIDEO),
- state_(RETURNING_DATA_FOR_READS) {
+ state_(UNINITIALIZED) {
stream_.reset(new SourceBufferStream(video_config, log_cb));
}
-void ChunkDemuxerStream::StartWaitingForSeek() {
- DVLOG(1) << "ChunkDemuxerStream::StartWaitingForSeek()";
+void ChunkDemuxerStream::AbortReads() {
+ DVLOG(1) << "ChunkDemuxerStream::AbortReads()";
ReadCBQueue read_cbs;
{
base::AutoLock auto_lock(lock_);
- ChangeState_Locked(WAITING_FOR_SEEK);
+ ChangeState_Locked(RETURNING_ABORT_FOR_READS);
std::swap(read_cbs_, read_cbs);
}
@@ -309,30 +308,11 @@ void ChunkDemuxerStream::StartWaitingForSeek() {
void ChunkDemuxerStream::Seek(TimeDelta time) {
base::AutoLock auto_lock(lock_);
-
DCHECK(read_cbs_.empty());
-
- // Ignore seek requests when canceled.
- if (state_ == CANCELED)
- return;
+ DCHECK(state_ == UNINITIALIZED || state_ == RETURNING_ABORT_FOR_READS);
stream_->Seek(time);
-
- if (state_ == WAITING_FOR_SEEK)
- ChangeState_Locked(RETURNING_DATA_FOR_READS);
-}
-
-void ChunkDemuxerStream::CancelPendingSeek() {
- DVLOG(1) << "ChunkDemuxerStream::CancelPendingSeek()";
- ReadCBQueue read_cbs;
- {
- base::AutoLock auto_lock(lock_);
- ChangeState_Locked(CANCELED);
- std::swap(read_cbs_, read_cbs);
- }
-
- for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
- it->Run(kAborted, NULL);
+ ChangeState_Locked(RETURNING_DATA_FOR_READS);
}
bool ChunkDemuxerStream::IsSeekWaitingForData() const {
@@ -449,14 +429,15 @@ static void RunOnMessageLoop(
// DemuxerStream methods.
void ChunkDemuxerStream::Read(const ReadCB& read_cb) {
+ base::AutoLock auto_lock(lock_);
+ DCHECK_NE(state_, UNINITIALIZED);
+
DemuxerStream::Status status = kOk;
scoped_refptr<StreamParserBuffer> buffer;
- {
- base::AutoLock auto_lock(lock_);
- if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) {
- DeferRead_Locked(read_cb);
- return;
- }
+
+ if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) {
+ DeferRead_Locked(read_cb);
+ return;
}
base::MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(
@@ -520,6 +501,9 @@ bool ChunkDemuxerStream::GetNextBuffer_Locked(
lock_.AssertAcquired();
switch (state_) {
+ case UNINITIALIZED:
+ NOTREACHED();
+ return false;
case RETURNING_DATA_FOR_READS:
switch (stream_->GetNextBuffer(buffer)) {
case SourceBufferStream::kSuccess:
@@ -538,8 +522,7 @@ bool ChunkDemuxerStream::GetNextBuffer_Locked(
return true;
}
break;
- case CANCELED:
- case WAITING_FOR_SEEK:
+ case RETURNING_ABORT_FOR_READS:
// Null buffers should be returned in this state since we are waiting
// for a seek. Any buffers in the SourceBuffer should NOT be returned
// because they are associated with the seek.
@@ -563,6 +546,7 @@ ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb,
const AddTextTrackCB& add_text_track_cb,
const LogCB& log_cb)
: state_(WAITING_FOR_INIT),
+ cancel_next_seek_(false),
host_(NULL),
open_cb_(open_cb),
need_key_cb_(need_key_cb),
@@ -601,28 +585,34 @@ void ChunkDemuxer::Stop(const base::Closure& callback) {
void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) {
DVLOG(1) << "Seek(" << time.InSecondsF() << ")";
DCHECK(time >= TimeDelta());
- DCHECK(seek_cb_.is_null());
- PipelineStatus status = PIPELINE_ERROR_INVALID_STATE;
base::AutoLock auto_lock(lock_);
+ DCHECK(seek_cb_.is_null());
seek_cb_ = BindToCurrentLoop(cb);
- if (state_ == INITIALIZED || state_ == ENDED) {
- if (audio_)
- audio_->Seek(time);
+ if (state_ != INITIALIZED && state_ != ENDED) {
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_ERROR_INVALID_STATE);
+ return;
+ }
- if (video_)
- video_->Seek(time);
+ if (cancel_next_seek_) {
+ cancel_next_seek_ = false;
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
+ return;
+ }
- if (IsSeekWaitingForData_Locked()) {
- DVLOG(1) << "Seek() : waiting for more data to arrive.";
- return;
- }
+ if (audio_)
+ audio_->Seek(time);
- status = PIPELINE_OK;
+ if (video_)
+ video_->Seek(time);
+
+ if (IsSeekWaitingForData_Locked()) {
+ DVLOG(1) << "Seek() : waiting for more data to arrive.";
+ return;
}
- base::ResetAndReturn(&seek_cb_).Run(status);
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
}
void ChunkDemuxer::OnAudioRendererDisabled() {
@@ -651,29 +641,42 @@ void ChunkDemuxer::StartWaitingForSeek() {
DVLOG(1) << "StartWaitingForSeek()";
base::AutoLock auto_lock(lock_);
DCHECK(state_ == INITIALIZED || state_ == ENDED || state_ == SHUTDOWN);
+ DCHECK(seek_cb_.is_null());
if (state_ == SHUTDOWN)
return;
if (audio_)
- audio_->StartWaitingForSeek();
+ audio_->AbortReads();
if (video_)
- video_->StartWaitingForSeek();
+ video_->AbortReads();
+
+ // Cancel state set in CancelPendingSeek() since we want to
+ // accept the next Seek().
+ cancel_next_seek_ = false;
}
void ChunkDemuxer::CancelPendingSeek() {
base::AutoLock auto_lock(lock_);
- DCHECK(seek_cb_.is_null() != IsSeekWaitingForData_Locked());
+ DCHECK_NE(state_, INITIALIZING);
+ DCHECK(seek_cb_.is_null() || IsSeekWaitingForData_Locked());
+
+ if (cancel_next_seek_)
+ return;
if (audio_)
- audio_->CancelPendingSeek();
+ audio_->AbortReads();
if (video_)
- video_->CancelPendingSeek();
+ video_->AbortReads();
- if (!seek_cb_.is_null())
- base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
+ if (seek_cb_.is_null()) {
+ cancel_next_seek_ = true;
+ return;
+ }
+
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
}
ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
@@ -1084,11 +1087,12 @@ void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
(!source_id_video_.empty() && !video_))
return;
+ TimeDelta start_time = GetStartTime();
if (audio_)
- audio_->Seek(TimeDelta());
+ audio_->Seek(start_time);
if (video_)
- video_->Seek(TimeDelta());
+ video_->Seek(start_time);
if (duration_ == kNoTimestamp())
duration_ = kInfiniteDuration();
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | media/filters/chunk_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698