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/ffmpeg_demuxer.h" | 5 #include "media/filters/ffmpeg_demuxer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 } else { | 765 } else { |
766 continue; | 766 continue; |
767 } | 767 } |
768 | 768 |
769 streams_[i] = | 769 streams_[i] = |
770 new FFmpegDemuxerStream(this, stream, discard_negative_timestamps); | 770 new FFmpegDemuxerStream(this, stream, discard_negative_timestamps); |
771 max_duration = std::max(max_duration, streams_[i]->duration()); | 771 max_duration = std::max(max_duration, streams_[i]->duration()); |
772 | 772 |
773 const base::TimeDelta start_time = | 773 const base::TimeDelta start_time = |
774 ExtractStartTime(stream, start_time_estimates[i]); | 774 ExtractStartTime(stream, start_time_estimates[i]); |
775 if (start_time == kNoTimestamp()) | 775 const bool has_start_time = start_time != kNoTimestamp(); |
| 776 |
| 777 // Always prefer the video stream for seeking. If none exists, we'll swap |
| 778 // the fallback stream with the preferred stream below. |
| 779 if (codec_type == AVMEDIA_TYPE_VIDEO) { |
| 780 preferred_stream_for_seeking_ = |
| 781 StreamSeekInfo(i, has_start_time ? start_time : base::TimeDelta()); |
| 782 } |
| 783 |
| 784 if (!has_start_time) |
776 continue; | 785 continue; |
777 | 786 |
778 if (start_time < start_time_) { | 787 if (start_time < start_time_) { |
779 start_time_ = start_time; | 788 start_time_ = start_time; |
780 | 789 |
781 // Choose the stream with the lowest starting time as the fallback stream | 790 // Choose the stream with the lowest starting time as the fallback stream |
782 // for seeking. Video should always be preferred. | 791 // for seeking. Video should always be preferred. |
783 fallback_stream_for_seeking_ = std::make_pair(i, start_time); | 792 fallback_stream_for_seeking_ = StreamSeekInfo(i, start_time); |
784 } | 793 } |
785 | |
786 // Always prefer the video stream for seeking. If none exists, we'll swap | |
787 // the fallback stream with the preferred stream below. | |
788 if (codec_type == AVMEDIA_TYPE_VIDEO) | |
789 preferred_stream_for_seeking_ = std::make_pair(i, start_time); | |
790 } | 794 } |
791 | 795 |
792 if (!audio_stream && !video_stream) { | 796 if (!audio_stream && !video_stream) { |
793 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); | 797 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); |
794 return; | 798 return; |
795 } | 799 } |
796 | 800 |
797 if (text_enabled_) | 801 if (text_enabled_) |
798 AddTextStreams(); | 802 AddTextStreams(); |
799 | 803 |
800 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) { | 804 if (format_context->duration != static_cast<int64_t>(AV_NOPTS_VALUE)) { |
801 // If there is a duration value in the container use that to find the | 805 // If there is a duration value in the container use that to find the |
802 // maximum between it and the duration from A/V streams. | 806 // maximum between it and the duration from A/V streams. |
803 const AVRational av_time_base = {1, AV_TIME_BASE}; | 807 const AVRational av_time_base = {1, AV_TIME_BASE}; |
804 max_duration = | 808 max_duration = |
805 std::max(max_duration, | 809 std::max(max_duration, |
806 ConvertFromTimeBase(av_time_base, format_context->duration)); | 810 ConvertFromTimeBase(av_time_base, format_context->duration)); |
807 } else { | 811 } else { |
808 // The duration is unknown, in which case this is likely a live stream. | 812 // The duration is unknown, in which case this is likely a live stream. |
809 max_duration = kInfiniteDuration(); | 813 max_duration = kInfiniteDuration(); |
810 } | 814 } |
811 | 815 |
812 // If no start time could be determined, default to zero and prefer the video | 816 // If no start time could be determined, default to zero and prefer the video |
813 // stream over the audio stream for seeking. E.g., The WAV demuxer does not | 817 // stream over the audio stream for seeking. E.g., The WAV demuxer does not |
814 // put timestamps on its frames. | 818 // put timestamps on its frames. |
815 if (start_time_ == kInfiniteDuration()) { | 819 if (start_time_ == kInfiniteDuration()) { |
816 start_time_ = base::TimeDelta(); | 820 start_time_ = base::TimeDelta(); |
817 preferred_stream_for_seeking_ = std::make_pair( | 821 preferred_stream_for_seeking_ = StreamSeekInfo( |
818 video_stream ? video_stream->index : audio_stream->index, start_time_); | 822 video_stream ? video_stream->index : audio_stream->index, start_time_); |
819 } else if (!video_stream) { | 823 } else if (!video_stream) { |
820 // If no video stream exists, use the audio or text stream found above. | 824 // If no video stream exists, use the audio or text stream found above. |
821 preferred_stream_for_seeking_ = fallback_stream_for_seeking_; | 825 preferred_stream_for_seeking_ = fallback_stream_for_seeking_; |
822 } | 826 } |
823 | 827 |
824 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS | 828 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS |
825 // generation so we always get timestamps, see http://crbug.com/169570 | 829 // generation so we always get timestamps, see http://crbug.com/169570 |
826 if (strcmp(format_context->iformat->name, "avi") == 0) | 830 if (strcmp(format_context->iformat->name, "avi") == 0) |
827 format_context->flags |= AVFMT_FLAG_GENPTS; | 831 format_context->flags |= AVFMT_FLAG_GENPTS; |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 } | 1138 } |
1135 for (size_t i = 0; i < buffered.size(); ++i) | 1139 for (size_t i = 0; i < buffered.size(); ++i) |
1136 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 1140 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
1137 } | 1141 } |
1138 | 1142 |
1139 void FFmpegDemuxer::OnDataSourceError() { | 1143 void FFmpegDemuxer::OnDataSourceError() { |
1140 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 1144 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
1141 } | 1145 } |
1142 | 1146 |
1143 } // namespace media | 1147 } // namespace media |
OLD | NEW |