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 "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
441 | 441 |
442 if (state_ == SHUTDOWN) | 442 if (state_ == SHUTDOWN) |
443 return; | 443 return; |
444 | 444 |
445 if (audio_.get()) | 445 if (audio_.get()) |
446 audio_->Flush(); | 446 audio_->Flush(); |
447 | 447 |
448 if (video_.get()) | 448 if (video_.get()) |
449 video_->Flush(); | 449 video_->Flush(); |
450 | 450 |
451 byte_queue_.Reset(); | |
452 stream_parser_->Flush(); | 451 stream_parser_->Flush(); |
453 | 452 |
454 seek_waits_for_data_ = true; | 453 seek_waits_for_data_ = true; |
455 ChangeState_Locked(INITIALIZED); | 454 ChangeState_Locked(INITIALIZED); |
456 } | 455 } |
457 | 456 |
458 bool ChunkDemuxer::AppendData(const uint8* data, size_t length) { | 457 bool ChunkDemuxer::AppendData(const uint8* data, size_t length) { |
459 DVLOG(1) << "AppendData(" << length << ")"; | 458 DVLOG(1) << "AppendData(" << length << ")"; |
460 | 459 |
461 if (!data || length == 0u) | 460 if (!data || length == 0u) |
462 return false; | 461 return false; |
463 | 462 |
464 int64 buffered_bytes = 0; | 463 int64 buffered_bytes = 0; |
465 base::TimeDelta buffered_ts = base::TimeDelta::FromSeconds(-1); | 464 base::TimeDelta buffered_ts = base::TimeDelta::FromSeconds(-1); |
466 | 465 |
467 PipelineStatusCB cb; | 466 PipelineStatusCB cb; |
468 { | 467 { |
469 base::AutoLock auto_lock(lock_); | 468 base::AutoLock auto_lock(lock_); |
470 | 469 |
471 byte_queue_.Push(data, length); | |
472 | |
473 const uint8* cur = NULL; | |
474 int cur_size = 0; | |
475 int bytes_parsed = 0; | |
476 int result = -1; | |
477 | |
478 // Capture |seek_waits_for_data_| state before we start parsing. | 470 // Capture |seek_waits_for_data_| state before we start parsing. |
479 // Its state can be changed by OnAudioBuffers() or OnVideoBuffers() | 471 // Its state can be changed by OnAudioBuffers() or OnVideoBuffers() |
480 // calls during the parse. | 472 // calls during the parse. |
481 bool old_seek_waits_for_data = seek_waits_for_data_; | 473 bool old_seek_waits_for_data = seek_waits_for_data_; |
482 | 474 |
483 byte_queue_.Peek(&cur, &cur_size); | 475 switch(state_) { |
476 case INITIALIZING: | |
477 if (!stream_parser_->Parse(data, length)) { | |
478 DCHECK_EQ(state_, INITIALIZING); | |
479 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | |
480 return true; | |
481 } | |
482 break; | |
484 | 483 |
485 do { | 484 case INITIALIZED: { |
486 switch(state_) { | 485 if (!stream_parser_->Parse(data, length)) { |
487 case INITIALIZING: | 486 ReportError_Locked(PIPELINE_ERROR_DECODE); |
488 result = stream_parser_->Parse(cur, cur_size); | 487 return true; |
489 if (result < 0) { | 488 } |
490 DCHECK_EQ(state_, INITIALIZING); | 489 } break; |
491 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | |
492 return true; | |
493 } | |
494 break; | |
495 | 490 |
496 case INITIALIZED: { | 491 case WAITING_FOR_INIT: |
497 result = stream_parser_->Parse(cur, cur_size); | 492 case ENDED: |
498 if (result < 0) { | 493 case PARSE_ERROR: |
499 ReportError_Locked(PIPELINE_ERROR_DECODE); | 494 case SHUTDOWN: |
500 return true; | 495 DVLOG(1) << "AppendData(): called in unexpected state " << state_; |
501 } | 496 return false; |
502 } break; | 497 } |
503 | |
504 case WAITING_FOR_INIT: | |
505 case ENDED: | |
506 case PARSE_ERROR: | |
507 case SHUTDOWN: | |
508 DVLOG(1) << "AppendData(): called in unexpected state " << state_; | |
509 return false; | |
510 } | |
511 | |
512 if (result > 0) { | |
513 cur += result; | |
514 cur_size -= result; | |
515 bytes_parsed += result; | |
516 } | |
517 } while (result > 0 && cur_size > 0); | |
518 | |
519 byte_queue_.Pop(bytes_parsed); | |
520 | 498 |
521 // Check to see if parsing triggered seek_waits_for_data_ to go from true to | 499 // Check to see if parsing triggered seek_waits_for_data_ to go from true to |
522 // false. This indicates we have parsed enough data to complete the seek. | 500 // false. This indicates we have parsed enough data to complete the seek. |
523 if (old_seek_waits_for_data && !seek_waits_for_data_ && | 501 if (old_seek_waits_for_data && !seek_waits_for_data_ && |
524 !seek_cb_.is_null()) { | 502 !seek_cb_.is_null()) { |
525 std::swap(cb, seek_cb_); | 503 std::swap(cb, seek_cb_); |
526 } | 504 } |
527 | 505 |
528 base::TimeDelta tmp; | 506 base::TimeDelta tmp; |
529 if (audio_.get() && audio_->GetLastBufferTimestamp(&tmp) && | 507 if (audio_.get() && audio_->GetLastBufferTimestamp(&tmp) && |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
667 duration_ = duration; | 645 duration_ = duration; |
668 host_->SetDuration(duration_); | 646 host_->SetDuration(duration_); |
669 host_->SetCurrentReadPosition(0); | 647 host_->SetCurrentReadPosition(0); |
670 | 648 |
671 ChangeState_Locked(INITIALIZED); | 649 ChangeState_Locked(INITIALIZED); |
672 PipelineStatusCB cb; | 650 PipelineStatusCB cb; |
673 std::swap(cb, init_cb_); | 651 std::swap(cb, init_cb_); |
674 cb.Run(PIPELINE_OK); | 652 cb.Run(PIPELINE_OK); |
675 } | 653 } |
676 | 654 |
677 bool ChunkDemuxer::OnNewAudioConfig(const AudioDecoderConfig& config) { | 655 bool ChunkDemuxer::OnNewConfigs(const AudioDecoderConfig& audio_config, |
656 const VideoDecoderConfig& video_config) { | |
657 DCHECK(audio_config.IsValidConfig() || video_config.IsValidConfig()); | |
678 lock_.AssertAcquired(); | 658 lock_.AssertAcquired(); |
679 // Only allow a single audio config for now. | 659 |
680 if (audio_.get()) | 660 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) |
scherkus (not reviewing)
2012/04/24 01:40:04
Considering we handle the DCHECK (and that the pre
acolwell GONE FROM CHROMIUM
2012/04/24 16:25:55
Done. Picked option 2
| |
681 return false; | 661 return false; |
682 | 662 |
683 audio_ = new ChunkDemuxerStream(config); | 663 // Only allow a single audio config for now. |
scherkus (not reviewing)
2012/04/24 01:40:04
nit: you can either dupe this comment below for vi
acolwell GONE FROM CHROMIUM
2012/04/24 16:25:55
Done.
| |
664 if (audio_config.IsValidConfig()) { | |
665 if (audio_.get()) | |
666 return false; | |
667 | |
668 audio_ = new ChunkDemuxerStream(audio_config); | |
669 } | |
670 | |
671 if (video_config.IsValidConfig()) { | |
672 if (video_.get()) | |
673 return false; | |
674 | |
675 video_ = new ChunkDemuxerStream(video_config); | |
676 } | |
677 | |
684 return true; | 678 return true; |
685 } | 679 } |
686 | 680 |
687 bool ChunkDemuxer::OnNewVideoConfig(const VideoDecoderConfig& config) { | |
688 lock_.AssertAcquired(); | |
689 // Only allow a single video config for now. | |
690 if (video_.get()) | |
691 return false; | |
692 | |
693 video_ = new ChunkDemuxerStream(config); | |
694 return true; | |
695 } | |
696 | |
697 bool ChunkDemuxer::OnAudioBuffers(const BufferQueue& buffers) { | 681 bool ChunkDemuxer::OnAudioBuffers(const BufferQueue& buffers) { |
698 if (!audio_.get()) | 682 if (!audio_.get()) |
699 return false; | 683 return false; |
700 | 684 |
701 if (!audio_->CanAddBuffers(buffers)) | 685 if (!audio_->CanAddBuffers(buffers)) |
702 return false; | 686 return false; |
703 | 687 |
704 audio_->AddBuffers(buffers); | 688 audio_->AddBuffers(buffers); |
705 seek_waits_for_data_ = false; | 689 seek_waits_for_data_ = false; |
706 | 690 |
707 return true; | 691 return true; |
708 } | 692 } |
709 | 693 |
710 bool ChunkDemuxer::OnVideoBuffers(const BufferQueue& buffers) { | 694 bool ChunkDemuxer::OnVideoBuffers(const BufferQueue& buffers) { |
711 if (!video_.get()) | 695 if (!video_.get()) |
712 return false; | 696 return false; |
713 | 697 |
714 if (!video_->CanAddBuffers(buffers)) | 698 if (!video_->CanAddBuffers(buffers)) |
715 return false; | 699 return false; |
716 | 700 |
717 video_->AddBuffers(buffers); | 701 video_->AddBuffers(buffers); |
718 seek_waits_for_data_ = false; | 702 seek_waits_for_data_ = false; |
719 | 703 |
720 return true; | 704 return true; |
721 } | 705 } |
722 | 706 |
723 } // namespace media | 707 } // namespace media |
OLD | NEW |