OLD | NEW |
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/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 DVLOG(1) << "StartWaitingForSeek()"; | 240 DVLOG(1) << "StartWaitingForSeek()"; |
241 ReadCBQueue read_cbs; | 241 ReadCBQueue read_cbs; |
242 { | 242 { |
243 base::AutoLock auto_lock(lock_); | 243 base::AutoLock auto_lock(lock_); |
244 ChangeState_Locked(WAITING_FOR_SEEK); | 244 ChangeState_Locked(WAITING_FOR_SEEK); |
245 | 245 |
246 std::swap(read_cbs_, read_cbs); | 246 std::swap(read_cbs_, read_cbs); |
247 } | 247 } |
248 | 248 |
249 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) | 249 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) |
250 it->Run(NULL); | 250 it->Run(kAborted, NULL); |
251 } | 251 } |
252 | 252 |
253 void ChunkDemuxerStream::Seek(TimeDelta time) { | 253 void ChunkDemuxerStream::Seek(TimeDelta time) { |
254 base::AutoLock auto_lock(lock_); | 254 base::AutoLock auto_lock(lock_); |
255 | 255 |
256 DCHECK(read_cbs_.empty()); | 256 DCHECK(read_cbs_.empty()); |
257 | 257 |
258 stream_->Seek(time); | 258 stream_->Seek(time); |
259 | 259 |
260 if (state_ == WAITING_FOR_SEEK) | 260 if (state_ == WAITING_FOR_SEEK) |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 ReadCBQueue read_cbs; | 367 ReadCBQueue read_cbs; |
368 { | 368 { |
369 base::AutoLock auto_lock(lock_); | 369 base::AutoLock auto_lock(lock_); |
370 ChangeState_Locked(SHUTDOWN); | 370 ChangeState_Locked(SHUTDOWN); |
371 std::swap(read_cbs_, read_cbs); | 371 std::swap(read_cbs_, read_cbs); |
372 } | 372 } |
373 | 373 |
374 // Pass end of stream buffers to all callbacks to signal that no more data | 374 // Pass end of stream buffers to all callbacks to signal that no more data |
375 // will be sent. | 375 // will be sent. |
376 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) | 376 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) |
377 it->Run(StreamParserBuffer::CreateEOSBuffer()); | 377 it->Run(DemuxerStream::kOk, StreamParserBuffer::CreateEOSBuffer()); |
378 } | 378 } |
379 | 379 |
380 // Helper function that makes sure |read_cb| runs on |message_loop|. | 380 // Helper function that makes sure |read_cb| runs on |message_loop|. |
381 static void RunOnMessageLoop(const DemuxerStream::ReadCB& read_cb, | 381 static void RunOnMessageLoop(const DemuxerStream::ReadCB& read_cb, |
382 MessageLoop* message_loop, | 382 MessageLoop* message_loop, |
| 383 DemuxerStream::Status status, |
383 const scoped_refptr<DecoderBuffer>& buffer) { | 384 const scoped_refptr<DecoderBuffer>& buffer) { |
384 if (MessageLoop::current() != message_loop) { | 385 if (MessageLoop::current() != message_loop) { |
385 message_loop->PostTask(FROM_HERE, base::Bind( | 386 message_loop->PostTask(FROM_HERE, base::Bind( |
386 &RunOnMessageLoop, read_cb, message_loop, buffer)); | 387 &RunOnMessageLoop, read_cb, message_loop, status, buffer)); |
387 return; | 388 return; |
388 } | 389 } |
389 | 390 |
390 read_cb.Run(buffer); | 391 read_cb.Run(status, buffer); |
391 } | 392 } |
392 | 393 |
393 // DemuxerStream methods. | 394 // DemuxerStream methods. |
394 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { | 395 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { |
| 396 DemuxerStream::Status status = kOk; |
395 scoped_refptr<StreamParserBuffer> buffer; | 397 scoped_refptr<StreamParserBuffer> buffer; |
396 { | 398 { |
397 base::AutoLock auto_lock(lock_); | 399 base::AutoLock auto_lock(lock_); |
398 | 400 |
399 switch (state_) { | 401 switch (state_) { |
400 case RETURNING_DATA_FOR_READS: | 402 case RETURNING_DATA_FOR_READS: |
401 // If we already have pending reads or we don't have any buffers ready, | 403 // If we already have pending reads or we don't have any buffers ready, |
402 // then defer this read. | 404 // then defer this read. |
403 if (!read_cbs_.empty() || !stream_->GetNextBuffer(&buffer)) { | 405 if (!read_cbs_.empty() || !stream_->GetNextBuffer(&buffer)) { |
404 DeferRead_Locked(read_cb); | 406 DeferRead_Locked(read_cb); |
405 return; | 407 return; |
406 } | 408 } |
407 break; | 409 break; |
408 case WAITING_FOR_SEEK: | 410 case WAITING_FOR_SEEK: |
409 // Null buffers should be returned in this state since we are waiting | 411 // Null buffers should be returned in this state since we are waiting |
410 // for a seek. Any buffers in the SourceBuffer should NOT be returned | 412 // for a seek. Any buffers in the SourceBuffer should NOT be returned |
411 // because they are associated with the seek. | 413 // because they are associated with the seek. |
412 DCHECK(read_cbs_.empty()); | 414 DCHECK(read_cbs_.empty()); |
| 415 status = kAborted; |
413 break; | 416 break; |
414 case SHUTDOWN: | 417 case SHUTDOWN: |
415 DCHECK(read_cbs_.empty()); | 418 DCHECK(read_cbs_.empty()); |
416 buffer = StreamParserBuffer::CreateEOSBuffer(); | 419 buffer = StreamParserBuffer::CreateEOSBuffer(); |
417 } | 420 } |
418 } | 421 } |
419 | 422 |
420 read_cb.Run(buffer); | 423 read_cb.Run(status, buffer); |
421 } | 424 } |
422 | 425 |
423 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } | 426 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } |
424 | 427 |
425 void ChunkDemuxerStream::EnableBitstreamConverter() {} | 428 void ChunkDemuxerStream::EnableBitstreamConverter() {} |
426 | 429 |
427 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { | 430 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { |
428 CHECK_EQ(type_, AUDIO); | 431 CHECK_EQ(type_, AUDIO); |
429 base::AutoLock auto_lock(lock_); | 432 base::AutoLock auto_lock(lock_); |
430 return stream_->GetCurrentAudioDecoderConfig(); | 433 return stream_->GetCurrentAudioDecoderConfig(); |
(...skipping 23 matching lines...) Expand all Loading... |
454 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { | 457 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { |
455 lock_.AssertAcquired(); | 458 lock_.AssertAcquired(); |
456 | 459 |
457 if (state_ != RETURNING_DATA_FOR_READS) | 460 if (state_ != RETURNING_DATA_FOR_READS) |
458 return; | 461 return; |
459 | 462 |
460 scoped_refptr<StreamParserBuffer> buffer; | 463 scoped_refptr<StreamParserBuffer> buffer; |
461 while (!read_cbs_.empty()) { | 464 while (!read_cbs_.empty()) { |
462 if (!stream_->GetNextBuffer(&buffer)) | 465 if (!stream_->GetNextBuffer(&buffer)) |
463 return; | 466 return; |
464 closures->push_back(base::Bind(read_cbs_.front(), buffer)); | 467 closures->push_back(base::Bind(read_cbs_.front(), |
| 468 DemuxerStream::kOk, buffer)); |
465 read_cbs_.pop_front(); | 469 read_cbs_.pop_front(); |
466 } | 470 } |
467 } | 471 } |
468 | 472 |
469 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 473 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
470 : state_(WAITING_FOR_INIT), | 474 : state_(WAITING_FOR_INIT), |
471 host_(NULL), | 475 host_(NULL), |
472 client_(client) { | 476 client_(client) { |
473 DCHECK(client); | 477 DCHECK(client); |
474 } | 478 } |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 // TODO(vrk): There should be a special case for the first appends where all | 998 // TODO(vrk): There should be a special case for the first appends where all |
995 // streams (for both demuxed and muxed case) begin at the earliest stream | 999 // streams (for both demuxed and muxed case) begin at the earliest stream |
996 // timestamp. (crbug.com/132815) | 1000 // timestamp. (crbug.com/132815) |
997 if (audio_ && source_id == source_id_audio_) | 1001 if (audio_ && source_id == source_id_audio_) |
998 audio_->OnNewMediaSegment(start_timestamp); | 1002 audio_->OnNewMediaSegment(start_timestamp); |
999 if (video_ && source_id == source_id_video_) | 1003 if (video_ && source_id == source_id_video_) |
1000 video_->OnNewMediaSegment(start_timestamp); | 1004 video_->OnNewMediaSegment(start_timestamp); |
1001 } | 1005 } |
1002 | 1006 |
1003 } // namespace media | 1007 } // namespace media |
OLD | NEW |