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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/callback.h" | 6 #include "base/callback.h" |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 : message_loop_(message_loop), | 282 : message_loop_(message_loop), |
283 local_source_(local_source), | 283 local_source_(local_source), |
284 format_context_(NULL), | 284 format_context_(NULL), |
285 read_event_(false, false), | 285 read_event_(false, false), |
286 read_has_failed_(false), | 286 read_has_failed_(false), |
287 last_read_bytes_(0), | 287 last_read_bytes_(0), |
288 read_position_(0), | 288 read_position_(0), |
289 max_duration_(base::TimeDelta::FromMicroseconds(-1)), | 289 max_duration_(base::TimeDelta::FromMicroseconds(-1)), |
290 deferred_status_(PIPELINE_OK), | 290 deferred_status_(PIPELINE_OK), |
291 first_seek_hack_(true), | 291 first_seek_hack_(true), |
292 start_time_(kNoTimestamp()) { | 292 start_time_(kNoTimestamp()), |
293 audio_disabled_(false) { | |
293 DCHECK(message_loop_); | 294 DCHECK(message_loop_); |
294 } | 295 } |
295 | 296 |
296 FFmpegDemuxer::~FFmpegDemuxer() { | 297 FFmpegDemuxer::~FFmpegDemuxer() { |
297 // In this destructor, we clean up resources held by FFmpeg. It is ugly to | 298 // In this destructor, we clean up resources held by FFmpeg. It is ugly to |
298 // close the codec contexts here because the corresponding codecs are opened | 299 // close the codec contexts here because the corresponding codecs are opened |
299 // in the decoder filters. By reaching this point, all filters should have | 300 // in the decoder filters. By reaching this point, all filters should have |
300 // stopped, so this is the only safe place to do the global clean up. | 301 // stopped, so this is the only safe place to do the global clean up. |
301 // TODO(hclam): close the codecs in the corresponding decoders. | 302 // TODO(hclam): close the codecs in the corresponding decoders. |
302 if (!format_context_) | 303 if (!format_context_) |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
655 // Queue the packet with the appropriate stream. | 656 // Queue the packet with the appropriate stream. |
656 // TODO(scherkus): should we post this back to the pipeline thread? I'm | 657 // TODO(scherkus): should we post this back to the pipeline thread? I'm |
657 // worried about downstream filters (i.e., decoders) executing on this | 658 // worried about downstream filters (i.e., decoders) executing on this |
658 // thread. | 659 // thread. |
659 DCHECK_GE(packet->stream_index, 0); | 660 DCHECK_GE(packet->stream_index, 0); |
660 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size())); | 661 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size())); |
661 | 662 |
662 // Defend against ffmpeg giving us a bad stream index. | 663 // Defend against ffmpeg giving us a bad stream index. |
663 if (packet->stream_index >= 0 && | 664 if (packet->stream_index >= 0 && |
664 packet->stream_index < static_cast<int>(streams_.size()) && | 665 packet->stream_index < static_cast<int>(streams_.size()) && |
665 streams_[packet->stream_index]) { | 666 streams_[packet->stream_index] && |
667 (!audio_disabled_ || | |
668 streams_[packet->stream_index]->type() != DemuxerStream::AUDIO)) { | |
666 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; | 669 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; |
667 | 670 |
668 // If a packet is returned by FFmpeg's av_parser_parse2() | 671 // If a packet is returned by FFmpeg's av_parser_parse2() |
669 // the packet will reference an inner memory of FFmpeg. | 672 // the packet will reference an inner memory of FFmpeg. |
670 // In this case, the packet's "destruct" member is NULL, | 673 // In this case, the packet's "destruct" member is NULL, |
671 // and it MUST be duplicated. This fixes issue with MP3 and possibly | 674 // and it MUST be duplicated. This fixes issue with MP3 and possibly |
672 // other codecs. It is safe to call this function even if the packet does | 675 // other codecs. It is safe to call this function even if the packet does |
673 // not refer to inner memory from FFmpeg. | 676 // not refer to inner memory from FFmpeg. |
674 av_dup_packet(packet.get()); | 677 av_dup_packet(packet.get()); |
675 | 678 |
(...skipping 16 matching lines...) Expand all Loading... | |
692 } | 695 } |
693 if (data_source_) { | 696 if (data_source_) { |
694 data_source_->Stop(callback); | 697 data_source_->Stop(callback); |
695 } else { | 698 } else { |
696 callback.Run(); | 699 callback.Run(); |
697 } | 700 } |
698 } | 701 } |
699 | 702 |
700 void FFmpegDemuxer::DisableAudioStreamTask() { | 703 void FFmpegDemuxer::DisableAudioStreamTask() { |
701 DCHECK_EQ(MessageLoop::current(), message_loop_); | 704 DCHECK_EQ(MessageLoop::current(), message_loop_); |
705 audio_disabled_ = true; | |
scherkus (not reviewing)
2012/01/26 21:46:13
any reason not to use FFmpegDemuxerStream::stopped
Ami GONE FROM CHROMIUM
2012/01/26 22:11:01
Just that that would be a more intrusive change, s
| |
702 StreamVector::iterator iter; | 706 StreamVector::iterator iter; |
703 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 707 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
704 if (*iter && (*iter)->type() == DemuxerStream::AUDIO) { | 708 if (*iter && (*iter)->type() == DemuxerStream::AUDIO) { |
705 (*iter)->Stop(); | 709 (*iter)->Stop(); |
706 } | 710 } |
707 } | 711 } |
708 } | 712 } |
709 | 713 |
710 bool FFmpegDemuxer::StreamsHavePendingReads() { | 714 bool FFmpegDemuxer::StreamsHavePendingReads() { |
711 DCHECK_EQ(MessageLoop::current(), message_loop_); | 715 DCHECK_EQ(MessageLoop::current(), message_loop_); |
712 StreamVector::iterator iter; | 716 StreamVector::iterator iter; |
713 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 717 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
714 if (*iter && (*iter)->HasPendingReads()) { | 718 if (*iter && (*iter)->HasPendingReads()) { |
715 return true; | 719 return true; |
716 } | 720 } |
717 } | 721 } |
718 return false; | 722 return false; |
719 } | 723 } |
720 | 724 |
721 void FFmpegDemuxer::StreamHasEnded() { | 725 void FFmpegDemuxer::StreamHasEnded() { |
722 DCHECK_EQ(MessageLoop::current(), message_loop_); | 726 DCHECK_EQ(MessageLoop::current(), message_loop_); |
723 StreamVector::iterator iter; | 727 StreamVector::iterator iter; |
724 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 728 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
725 if (!*iter) | 729 if (!*iter || |
730 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { | |
726 continue; | 731 continue; |
732 } | |
727 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet(new AVPacket()); | 733 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet(new AVPacket()); |
728 memset(packet.get(), 0, sizeof(*packet.get())); | 734 memset(packet.get(), 0, sizeof(*packet.get())); |
729 (*iter)->EnqueuePacket(packet.Pass()); | 735 (*iter)->EnqueuePacket(packet.Pass()); |
730 } | 736 } |
731 } | 737 } |
732 | 738 |
733 void FFmpegDemuxer::OnReadCompleted(size_t size) { | 739 void FFmpegDemuxer::OnReadCompleted(size_t size) { |
734 SignalReadCompleted(size); | 740 SignalReadCompleted(size); |
735 } | 741 } |
736 | 742 |
737 size_t FFmpegDemuxer::WaitForRead() { | 743 size_t FFmpegDemuxer::WaitForRead() { |
738 read_event_.Wait(); | 744 read_event_.Wait(); |
739 return last_read_bytes_; | 745 return last_read_bytes_; |
740 } | 746 } |
741 | 747 |
742 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 748 void FFmpegDemuxer::SignalReadCompleted(size_t size) { |
743 last_read_bytes_ = size; | 749 last_read_bytes_ = size; |
744 read_event_.Signal(); | 750 read_event_.Signal(); |
745 } | 751 } |
746 | 752 |
747 } // namespace media | 753 } // namespace media |
OLD | NEW |