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

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

Issue 10669022: Add status parameter to DemuxerStream::ReadCB (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 5 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/audio_renderer_impl_unittest.cc ('k') | media/filters/chunk_demuxer_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) 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 204
205 // Adds the callback to |read_cbs_| so it can be called later when we 205 // Adds the callback to |read_cbs_| so it can be called later when we
206 // have data. 206 // have data.
207 void DeferRead_Locked(const ReadCB& read_cb); 207 void DeferRead_Locked(const ReadCB& read_cb);
208 208
209 // Creates closures that bind ReadCBs in |read_cbs_| to data in 209 // Creates closures that bind ReadCBs in |read_cbs_| to data in
210 // |buffers_| and pops the callbacks & buffers from the respecive queues. 210 // |buffers_| and pops the callbacks & buffers from the respecive queues.
211 void CreateReadDoneClosures_Locked(ClosureQueue* closures); 211 void CreateReadDoneClosures_Locked(ClosureQueue* closures);
212 212
213 // Gets the value to pass to the next Read() callback. Returns true if 213 // Gets the value to pass to the next Read() callback. Returns true if
214 // |buffer| should be passed to the callback. False indicates that |buffer| 214 // |status| and |buffer| should be passed to the callback. False indicates
215 // was not set and more data is needed. 215 // that |status| and |buffer| were not set and more data is needed.
216 bool GetNextBuffer_Locked(scoped_refptr<StreamParserBuffer>* buffer); 216 bool GetNextBuffer_Locked(DemuxerStream::Status* status,
217 scoped_refptr<StreamParserBuffer>* buffer);
217 218
218 // Specifies the type of the stream (must be AUDIO or VIDEO for now). 219 // Specifies the type of the stream (must be AUDIO or VIDEO for now).
219 Type type_; 220 Type type_;
220 221
221 scoped_ptr<SourceBufferStream> stream_; 222 scoped_ptr<SourceBufferStream> stream_;
222 223
223 mutable base::Lock lock_; 224 mutable base::Lock lock_;
224 State state_; 225 State state_;
225 ReadCBQueue read_cbs_; 226 ReadCBQueue read_cbs_;
226 bool end_of_stream_; 227 bool end_of_stream_;
(...skipping 19 matching lines...) Expand all
246 DVLOG(1) << "StartWaitingForSeek()"; 247 DVLOG(1) << "StartWaitingForSeek()";
247 ReadCBQueue read_cbs; 248 ReadCBQueue read_cbs;
248 { 249 {
249 base::AutoLock auto_lock(lock_); 250 base::AutoLock auto_lock(lock_);
250 ChangeState_Locked(WAITING_FOR_SEEK); 251 ChangeState_Locked(WAITING_FOR_SEEK);
251 end_of_stream_ = false; 252 end_of_stream_ = false;
252 std::swap(read_cbs_, read_cbs); 253 std::swap(read_cbs_, read_cbs);
253 } 254 }
254 255
255 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) 256 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
256 it->Run(NULL); 257 it->Run(kAborted, NULL);
257 } 258 }
258 259
259 void ChunkDemuxerStream::Seek(TimeDelta time) { 260 void ChunkDemuxerStream::Seek(TimeDelta time) {
260 base::AutoLock auto_lock(lock_); 261 base::AutoLock auto_lock(lock_);
261 262
262 DCHECK(read_cbs_.empty()); 263 DCHECK(read_cbs_.empty());
263 264
264 stream_->Seek(time); 265 stream_->Seek(time);
265 266
266 if (state_ == WAITING_FOR_SEEK) 267 if (state_ == WAITING_FOR_SEEK)
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 ReadCBQueue read_cbs; 379 ReadCBQueue read_cbs;
379 { 380 {
380 base::AutoLock auto_lock(lock_); 381 base::AutoLock auto_lock(lock_);
381 ChangeState_Locked(SHUTDOWN); 382 ChangeState_Locked(SHUTDOWN);
382 std::swap(read_cbs_, read_cbs); 383 std::swap(read_cbs_, read_cbs);
383 } 384 }
384 385
385 // Pass end of stream buffers to all callbacks to signal that no more data 386 // Pass end of stream buffers to all callbacks to signal that no more data
386 // will be sent. 387 // will be sent.
387 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) 388 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
388 it->Run(StreamParserBuffer::CreateEOSBuffer()); 389 it->Run(DemuxerStream::kOk, StreamParserBuffer::CreateEOSBuffer());
389 } 390 }
390 391
391 // Helper function that makes sure |read_cb| runs on |message_loop|. 392 // Helper function that makes sure |read_cb| runs on |message_loop|.
392 static void RunOnMessageLoop(const DemuxerStream::ReadCB& read_cb, 393 static void RunOnMessageLoop(const DemuxerStream::ReadCB& read_cb,
393 MessageLoop* message_loop, 394 MessageLoop* message_loop,
395 DemuxerStream::Status status,
394 const scoped_refptr<DecoderBuffer>& buffer) { 396 const scoped_refptr<DecoderBuffer>& buffer) {
395 if (MessageLoop::current() != message_loop) { 397 if (MessageLoop::current() != message_loop) {
396 message_loop->PostTask(FROM_HERE, base::Bind( 398 message_loop->PostTask(FROM_HERE, base::Bind(
397 &RunOnMessageLoop, read_cb, message_loop, buffer)); 399 &RunOnMessageLoop, read_cb, message_loop, status, buffer));
398 return; 400 return;
399 } 401 }
400 402
401 read_cb.Run(buffer); 403 read_cb.Run(status, buffer);
402 } 404 }
403 405
404 // DemuxerStream methods. 406 // DemuxerStream methods.
405 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { 407 void ChunkDemuxerStream::Read(const ReadCB& read_cb) {
408 DemuxerStream::Status status = kOk;
406 scoped_refptr<StreamParserBuffer> buffer; 409 scoped_refptr<StreamParserBuffer> buffer;
407 { 410 {
408 base::AutoLock auto_lock(lock_); 411 base::AutoLock auto_lock(lock_);
409 if (!read_cbs_.empty() || !GetNextBuffer_Locked(&buffer)) { 412 if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) {
410 DeferRead_Locked(read_cb); 413 DeferRead_Locked(read_cb);
411 return; 414 return;
412 } 415 }
413 } 416 }
414 417
415 read_cb.Run(buffer); 418 read_cb.Run(status, buffer);
416 } 419 }
417 420
418 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } 421 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; }
419 422
420 void ChunkDemuxerStream::EnableBitstreamConverter() {} 423 void ChunkDemuxerStream::EnableBitstreamConverter() {}
421 424
422 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { 425 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() {
423 CHECK_EQ(type_, AUDIO); 426 CHECK_EQ(type_, AUDIO);
424 base::AutoLock auto_lock(lock_); 427 base::AutoLock auto_lock(lock_);
425 return stream_->GetCurrentAudioDecoderConfig(); 428 return stream_->GetCurrentAudioDecoderConfig();
(...skipping 19 matching lines...) Expand all
445 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, read_cb, 448 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, read_cb,
446 MessageLoop::current())); 449 MessageLoop::current()));
447 } 450 }
448 451
449 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { 452 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) {
450 lock_.AssertAcquired(); 453 lock_.AssertAcquired();
451 454
452 if (state_ != RETURNING_DATA_FOR_READS) 455 if (state_ != RETURNING_DATA_FOR_READS)
453 return; 456 return;
454 457
458 DemuxerStream::Status status;
455 scoped_refptr<StreamParserBuffer> buffer; 459 scoped_refptr<StreamParserBuffer> buffer;
456 while (!read_cbs_.empty()) { 460 while (!read_cbs_.empty()) {
457 if (!GetNextBuffer_Locked(&buffer)) 461 if (!GetNextBuffer_Locked(&status, &buffer))
458 return; 462 return;
459 closures->push_back(base::Bind(read_cbs_.front(), buffer)); 463 closures->push_back(base::Bind(read_cbs_.front(),
464 status, buffer));
460 read_cbs_.pop_front(); 465 read_cbs_.pop_front();
461 } 466 }
462 } 467 }
463 468
464 bool ChunkDemuxerStream::GetNextBuffer_Locked( 469 bool ChunkDemuxerStream::GetNextBuffer_Locked(
470 DemuxerStream::Status* status,
465 scoped_refptr<StreamParserBuffer>* buffer) { 471 scoped_refptr<StreamParserBuffer>* buffer) {
466 lock_.AssertAcquired(); 472 lock_.AssertAcquired();
467 473
468 switch (state_) { 474 switch (state_) {
469 case RETURNING_DATA_FOR_READS: 475 case RETURNING_DATA_FOR_READS:
470 if (stream_->GetNextBuffer(buffer)) 476 if (stream_->GetNextBuffer(buffer)) {
477 *status = DemuxerStream::kOk;
471 return true; 478 return true;
479 }
472 480
473 if (end_of_stream_) { 481 if (end_of_stream_) {
482 *status = DemuxerStream::kOk;
474 *buffer = StreamParserBuffer::CreateEOSBuffer(); 483 *buffer = StreamParserBuffer::CreateEOSBuffer();
475 return true; 484 return true;
476 } 485 }
477 return false; 486 return false;
478 case WAITING_FOR_SEEK: 487 case WAITING_FOR_SEEK:
479 // Null buffers should be returned in this state since we are waiting 488 // Null buffers should be returned in this state since we are waiting
480 // for a seek. Any buffers in the SourceBuffer should NOT be returned 489 // for a seek. Any buffers in the SourceBuffer should NOT be returned
481 // because they are associated with the seek. 490 // because they are associated with the seek.
482 DCHECK(read_cbs_.empty()); 491 DCHECK(read_cbs_.empty());
492 *status = DemuxerStream::kAborted;
483 *buffer = NULL; 493 *buffer = NULL;
484 return true; 494 return true;
485 case SHUTDOWN: 495 case SHUTDOWN:
486 DCHECK(read_cbs_.empty()); 496 DCHECK(read_cbs_.empty());
497 *status = DemuxerStream::kOk;
487 *buffer = StreamParserBuffer::CreateEOSBuffer(); 498 *buffer = StreamParserBuffer::CreateEOSBuffer();
488 return true; 499 return true;
489 } 500 }
490 501
491 NOTREACHED(); 502 NOTREACHED();
492 return false; 503 return false;
493 } 504 }
494 505
495 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) 506 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client)
496 : state_(WAITING_FOR_INIT), 507 : state_(WAITING_FOR_INIT),
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 video_->SetStartTime(start_time_); 1049 video_->SetStartTime(start_time_);
1039 video_->Seek(start_time_); 1050 video_->Seek(start_time_);
1040 } 1051 }
1041 1052
1042 // The demuxer is now initialized after the |start_timestamp_| was set. 1053 // The demuxer is now initialized after the |start_timestamp_| was set.
1043 ChangeState_Locked(INITIALIZED); 1054 ChangeState_Locked(INITIALIZED);
1044 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 1055 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
1045 } 1056 }
1046 1057
1047 } // namespace media 1058 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_impl_unittest.cc ('k') | media/filters/chunk_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698