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

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

Issue 10835044: Cancel pending seek in ChunkDemuxer when a new seek occurs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase ToT + fix threading issue Created 8 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | webkit/media/webmediaplayer_impl.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) 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/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 public: 166 public:
167 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; 167 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
168 typedef std::deque<ReadCB> ReadCBQueue; 168 typedef std::deque<ReadCB> ReadCBQueue;
169 typedef std::deque<base::Closure> ClosureQueue; 169 typedef std::deque<base::Closure> ClosureQueue;
170 170
171 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); 171 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config);
172 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); 172 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config);
173 173
174 void StartWaitingForSeek(); 174 void StartWaitingForSeek();
175 void Seek(TimeDelta time); 175 void Seek(TimeDelta time);
176 void BeginReturningNullBuffers();
176 bool IsSeekPending() const; 177 bool IsSeekPending() const;
177 178
178 // Add buffers to this stream. Buffers are stored in SourceBufferStreams, 179 // Add buffers to this stream. Buffers are stored in SourceBufferStreams,
179 // which handle ordering and overlap resolution. 180 // which handle ordering and overlap resolution.
180 // Returns true if buffers were successfully added. 181 // Returns true if buffers were successfully added.
181 bool Append(const StreamParser::BufferQueue& buffers); 182 bool Append(const StreamParser::BufferQueue& buffers);
182 183
183 // Returns the range of buffered data in this stream, capped at |duration|. 184 // Returns the range of buffered data in this stream, capped at |duration|.
184 Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const; 185 Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const;
185 186
(...skipping 21 matching lines...) Expand all
207 virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE; 208 virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE;
208 virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE; 209 virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE;
209 210
210 protected: 211 protected:
211 virtual ~ChunkDemuxerStream(); 212 virtual ~ChunkDemuxerStream();
212 213
213 private: 214 private:
214 enum State { 215 enum State {
215 RETURNING_DATA_FOR_READS, 216 RETURNING_DATA_FOR_READS,
216 WAITING_FOR_SEEK, 217 WAITING_FOR_SEEK,
218 CANCELED,
217 SHUTDOWN, 219 SHUTDOWN,
218 }; 220 };
219 221
220 // Assigns |state_| to |state| 222 // Assigns |state_| to |state|
221 void ChangeState_Locked(State state); 223 void ChangeState_Locked(State state);
222 224
223 // Adds the callback to |read_cbs_| so it can be called later when we 225 // Adds the callback to |read_cbs_| so it can be called later when we
224 // have data. 226 // have data.
225 void DeferRead_Locked(const ReadCB& read_cb); 227 void DeferRead_Locked(const ReadCB& read_cb);
226 228
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 275
274 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) 276 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
275 it->Run(kAborted, NULL); 277 it->Run(kAborted, NULL);
276 } 278 }
277 279
278 void ChunkDemuxerStream::Seek(TimeDelta time) { 280 void ChunkDemuxerStream::Seek(TimeDelta time) {
279 base::AutoLock auto_lock(lock_); 281 base::AutoLock auto_lock(lock_);
280 282
281 DCHECK(read_cbs_.empty()); 283 DCHECK(read_cbs_.empty());
282 284
285 // Ignore seek requests when cancelled.
286 if (state_ == CANCELED)
287 return;
288
283 stream_->Seek(time); 289 stream_->Seek(time);
284 290
285 if (state_ == WAITING_FOR_SEEK) 291 if (state_ == WAITING_FOR_SEEK)
286 ChangeState_Locked(RETURNING_DATA_FOR_READS); 292 ChangeState_Locked(RETURNING_DATA_FOR_READS);
287 } 293 }
288 294
295 void ChunkDemuxerStream::BeginReturningNullBuffers() {
296 base::AutoLock auto_lock(lock_);
297 ChangeState_Locked(CANCELED);
acolwell GONE FROM CHROMIUM 2012/08/07 20:26:51 I think you may need to copy the read_cbs code fro
vrk (LEFT CHROMIUM) 2012/08/07 22:44:51 Done.
298 }
299
289 bool ChunkDemuxerStream::IsSeekPending() const { 300 bool ChunkDemuxerStream::IsSeekPending() const {
290 base::AutoLock auto_lock(lock_); 301 base::AutoLock auto_lock(lock_);
291 return stream_->IsSeekPending(); 302 return stream_->IsSeekPending();
292 } 303 }
293 304
294 void ChunkDemuxerStream::OnNewMediaSegment(TimeDelta start_timestamp) { 305 void ChunkDemuxerStream::OnNewMediaSegment(TimeDelta start_timestamp) {
295 base::AutoLock auto_lock(lock_); 306 base::AutoLock auto_lock(lock_);
296 DCHECK(!end_of_stream_); 307 DCHECK(!end_of_stream_);
297 stream_->OnNewMediaSegment(start_timestamp); 308 stream_->OnNewMediaSegment(start_timestamp);
298 } 309 }
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 *buffer = StreamParserBuffer::CreateEOSBuffer(); 494 *buffer = StreamParserBuffer::CreateEOSBuffer();
484 return true; 495 return true;
485 } 496 }
486 return false; 497 return false;
487 case SourceBufferStream::kConfigChange: 498 case SourceBufferStream::kConfigChange:
488 *status = kConfigChanged; 499 *status = kConfigChanged;
489 *buffer = NULL; 500 *buffer = NULL;
490 return true; 501 return true;
491 } 502 }
492 break; 503 break;
504 case CANCELED:
493 case WAITING_FOR_SEEK: 505 case WAITING_FOR_SEEK:
494 // Null buffers should be returned in this state since we are waiting 506 // Null buffers should be returned in this state since we are waiting
495 // for a seek. Any buffers in the SourceBuffer should NOT be returned 507 // for a seek. Any buffers in the SourceBuffer should NOT be returned
496 // because they are associated with the seek. 508 // because they are associated with the seek.
497 DCHECK(read_cbs_.empty()); 509 DCHECK(read_cbs_.empty());
498 *status = DemuxerStream::kAborted; 510 *status = DemuxerStream::kAborted;
499 *buffer = NULL; 511 *buffer = NULL;
500 return true; 512 return true;
501 case SHUTDOWN: 513 case SHUTDOWN:
502 DCHECK(read_cbs_.empty()); 514 DCHECK(read_cbs_.empty());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 610
599 if (audio_) 611 if (audio_)
600 audio_->StartWaitingForSeek(); 612 audio_->StartWaitingForSeek();
601 613
602 if (video_) 614 if (video_)
603 video_->StartWaitingForSeek(); 615 video_->StartWaitingForSeek();
604 616
605 ChangeState_Locked(INITIALIZED); 617 ChangeState_Locked(INITIALIZED);
606 } 618 }
607 619
620 void ChunkDemuxer::CancelPendingSeek() {
621 PipelineStatusCB cb;
622 {
623 base::AutoLock auto_lock(lock_);
624 if (IsSeekPending_Locked() && !seek_cb_.is_null()) {
625 std::swap(cb, seek_cb_);
626 }
627 }
628
629 if (audio_)
630 audio_->BeginReturningNullBuffers();
acolwell GONE FROM CHROMIUM 2012/08/07 20:26:51 nit:s/BeginReturningNullBuffers/CancelPendingSeek/
vrk (LEFT CHROMIUM) 2012/08/07 22:44:51 ...yeah that would make more sense :P Done!
631
632 if (video_)
633 video_->BeginReturningNullBuffers();
634
635 if (!cb.is_null())
636 cb.Run(PIPELINE_OK);
637 }
638
608 ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, 639 ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
609 const std::string& type, 640 const std::string& type,
610 std::vector<std::string>& codecs) { 641 std::vector<std::string>& codecs) {
611 DCHECK_GT(codecs.size(), 0u); 642 DCHECK_GT(codecs.size(), 0u);
612 base::AutoLock auto_lock(lock_); 643 base::AutoLock auto_lock(lock_);
613 644
614 if (state_ != WAITING_FOR_INIT && state_ != INITIALIZING) 645 if (state_ != WAITING_FOR_INIT && state_ != INITIALIZING)
615 return kReachedIdLimit; 646 return kReachedIdLimit;
616 647
617 bool has_audio = false; 648 bool has_audio = false;
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 1181
1151 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { 1182 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const {
1152 if (audio_ && !video_) 1183 if (audio_ && !video_)
1153 return audio_->GetBufferedRanges(duration_); 1184 return audio_->GetBufferedRanges(duration_);
1154 else if (!audio_ && video_) 1185 else if (!audio_ && video_)
1155 return video_->GetBufferedRanges(duration_); 1186 return video_->GetBufferedRanges(duration_);
1156 return ComputeIntersection(); 1187 return ComputeIntersection();
1157 } 1188 }
1158 1189
1159 } // namespace media 1190 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | webkit/media/webmediaplayer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698