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 <memory> | 8 #include <memory> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 is_enabled_ = enabled; | 735 is_enabled_ = enabled; |
736 if (is_enabled_) { | 736 if (is_enabled_) { |
737 waiting_for_keyframe_ = true; | 737 waiting_for_keyframe_ = true; |
738 } | 738 } |
739 if (!is_enabled_ && !read_cb_.is_null()) { | 739 if (!is_enabled_ && !read_cb_.is_null()) { |
740 DVLOG(1) << "Read from disabled stream, returning EOS"; | 740 DVLOG(1) << "Read from disabled stream, returning EOS"; |
741 base::ResetAndReturn(&read_cb_).Run(kOk, DecoderBuffer::CreateEOSBuffer()); | 741 base::ResetAndReturn(&read_cb_).Run(kOk, DecoderBuffer::CreateEOSBuffer()); |
742 return; | 742 return; |
743 } | 743 } |
744 if (!stream_status_change_cb_.is_null()) | 744 if (!stream_status_change_cb_.is_null()) |
745 stream_status_change_cb_.Run(is_enabled_, timestamp); | 745 stream_status_change_cb_.Run(this, is_enabled_, timestamp); |
746 } | 746 } |
747 | 747 |
748 void FFmpegDemuxerStream::SetStreamStatusChangeCB( | 748 void FFmpegDemuxerStream::SetStreamStatusChangeCB( |
749 const StreamStatusChangeCB& cb) { | 749 const StreamStatusChangeCB& cb) { |
750 DCHECK(!cb.is_null()); | 750 DCHECK(!cb.is_null()); |
751 stream_status_change_cb_ = cb; | 751 stream_status_change_cb_ = cb; |
752 } | 752 } |
753 | 753 |
754 void FFmpegDemuxerStream::SetLiveness(Liveness liveness) { | 754 void FFmpegDemuxerStream::SetLiveness(Liveness liveness) { |
755 DCHECK(task_runner_->BelongsToCurrentThread()); | 755 DCHECK(task_runner_->BelongsToCurrentThread()); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 // Additionally, to workaround limitations in how we expose seekable ranges to | 984 // Additionally, to workaround limitations in how we expose seekable ranges to |
985 // Blink (http://crbug.com/137275), we also want to clamp seeks before the | 985 // Blink (http://crbug.com/137275), we also want to clamp seeks before the |
986 // start time to the start time. | 986 // start time to the start time. |
987 base::TimeDelta seek_time = start_time_ < base::TimeDelta() | 987 base::TimeDelta seek_time = start_time_ < base::TimeDelta() |
988 ? time + start_time_ | 988 ? time + start_time_ |
989 : time < start_time_ ? start_time_ : time; | 989 : time < start_time_ ? start_time_ : time; |
990 | 990 |
991 // When seeking in an opus stream we need to ensure we deliver enough data to | 991 // When seeking in an opus stream we need to ensure we deliver enough data to |
992 // satisfy the seek preroll; otherwise the audio at the actual seek time will | 992 // satisfy the seek preroll; otherwise the audio at the actual seek time will |
993 // not be entirely accurate. | 993 // not be entirely accurate. |
994 FFmpegDemuxerStream* audio_stream = GetFFmpegStream(DemuxerStream::AUDIO); | 994 FFmpegDemuxerStream* audio_stream = |
| 995 GetFirstEnabledFFmpegStream(DemuxerStream::AUDIO); |
995 if (audio_stream) { | 996 if (audio_stream) { |
996 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 997 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
997 if (config.codec() == kCodecOpus) | 998 if (config.codec() == kCodecOpus) |
998 seek_time = std::max(start_time_, seek_time - config.seek_preroll()); | 999 seek_time = std::max(start_time_, seek_time - config.seek_preroll()); |
999 } | 1000 } |
1000 | 1001 |
1001 // Choose the seeking stream based on whether it contains the seek time, if no | 1002 // Choose the seeking stream based on whether it contains the seek time, if no |
1002 // match can be found prefer the preferred stream. | 1003 // match can be found prefer the preferred stream. |
1003 // | 1004 // |
1004 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a | 1005 // TODO(dalecurtis): Currently FFmpeg does not ensure that all streams in a |
(...skipping 14 matching lines...) Expand all Loading... |
1019 ConvertToTimeBase(seeking_stream->time_base, seek_time), | 1020 ConvertToTimeBase(seeking_stream->time_base, seek_time), |
1020 // Always seek to a timestamp <= to the desired timestamp. | 1021 // Always seek to a timestamp <= to the desired timestamp. |
1021 AVSEEK_FLAG_BACKWARD), | 1022 AVSEEK_FLAG_BACKWARD), |
1022 base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr())); | 1023 base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr())); |
1023 } | 1024 } |
1024 | 1025 |
1025 base::Time FFmpegDemuxer::GetTimelineOffset() const { | 1026 base::Time FFmpegDemuxer::GetTimelineOffset() const { |
1026 return timeline_offset_; | 1027 return timeline_offset_; |
1027 } | 1028 } |
1028 | 1029 |
1029 DemuxerStream* FFmpegDemuxer::GetStream(DemuxerStream::Type type) { | 1030 std::vector<DemuxerStream*> FFmpegDemuxer::GetStreams() { |
1030 DCHECK(task_runner_->BelongsToCurrentThread()); | 1031 DCHECK(task_runner_->BelongsToCurrentThread()); |
1031 return GetFFmpegStream(type); | 1032 std::vector<DemuxerStream*> result; |
| 1033 for (const auto& stream : streams_) { |
| 1034 if (stream) |
| 1035 result.push_back(stream.get()); |
| 1036 } |
| 1037 return result; |
1032 } | 1038 } |
1033 | 1039 |
1034 FFmpegDemuxerStream* FFmpegDemuxer::GetFFmpegStream( | 1040 void FFmpegDemuxer::SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) { |
| 1041 for (const auto& stream : streams_) { |
| 1042 if (stream) |
| 1043 stream->SetStreamStatusChangeCB(cb); |
| 1044 } |
| 1045 } |
| 1046 |
| 1047 FFmpegDemuxerStream* FFmpegDemuxer::GetFirstEnabledFFmpegStream( |
1035 DemuxerStream::Type type) const { | 1048 DemuxerStream::Type type) const { |
1036 for (const auto& stream : streams_) { | 1049 for (const auto& stream : streams_) { |
1037 if (stream && stream->type() == type && stream->enabled()) { | 1050 if (stream && stream->type() == type && stream->enabled()) { |
1038 return stream.get(); | 1051 return stream.get(); |
1039 } | 1052 } |
1040 } | 1053 } |
1041 return NULL; | 1054 return NULL; |
1042 } | 1055 } |
1043 | 1056 |
1044 base::TimeDelta FFmpegDemuxer::GetStartTime() const { | 1057 base::TimeDelta FFmpegDemuxer::GetStartTime() const { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 } | 1094 } |
1082 | 1095 |
1083 void FFmpegDemuxer::NotifyCapacityAvailable() { | 1096 void FFmpegDemuxer::NotifyCapacityAvailable() { |
1084 DCHECK(task_runner_->BelongsToCurrentThread()); | 1097 DCHECK(task_runner_->BelongsToCurrentThread()); |
1085 ReadFrameIfNeeded(); | 1098 ReadFrameIfNeeded(); |
1086 } | 1099 } |
1087 | 1100 |
1088 void FFmpegDemuxer::NotifyBufferingChanged() { | 1101 void FFmpegDemuxer::NotifyBufferingChanged() { |
1089 DCHECK(task_runner_->BelongsToCurrentThread()); | 1102 DCHECK(task_runner_->BelongsToCurrentThread()); |
1090 Ranges<base::TimeDelta> buffered; | 1103 Ranges<base::TimeDelta> buffered; |
1091 FFmpegDemuxerStream* audio = GetFFmpegStream(DemuxerStream::AUDIO); | 1104 bool initialized_buffered_ranges = false; |
1092 FFmpegDemuxerStream* video = GetFFmpegStream(DemuxerStream::VIDEO); | 1105 for (const auto& stream : streams_) { |
1093 if (audio && video) { | 1106 if (!stream) |
1094 buffered = | 1107 continue; |
1095 audio->GetBufferedRanges().IntersectionWith(video->GetBufferedRanges()); | 1108 if (initialized_buffered_ranges) { |
1096 } else if (audio) { | 1109 buffered = buffered.IntersectionWith(stream->GetBufferedRanges()); |
1097 buffered = audio->GetBufferedRanges(); | 1110 } else { |
1098 } else if (video) { | 1111 buffered = stream->GetBufferedRanges(); |
1099 buffered = video->GetBufferedRanges(); | 1112 initialized_buffered_ranges = true; |
| 1113 } |
1100 } | 1114 } |
1101 host_->OnBufferedTimeRangesChanged(buffered); | 1115 host_->OnBufferedTimeRangesChanged(buffered); |
1102 } | 1116 } |
1103 | 1117 |
1104 // Helper for calculating the bitrate of the media based on information stored | 1118 // Helper for calculating the bitrate of the media based on information stored |
1105 // in |format_context| or failing that the size and duration of the media. | 1119 // in |format_context| or failing that the size and duration of the media. |
1106 // | 1120 // |
1107 // Returns 0 if a bitrate could not be determined. | 1121 // Returns 0 if a bitrate could not be determined. |
1108 static int CalculateBitrate(AVFormatContext* format_context, | 1122 static int CalculateBitrate(AVFormatContext* format_context, |
1109 const base::TimeDelta& duration, | 1123 const base::TimeDelta& duration, |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 | 1830 |
1817 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { | 1831 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { |
1818 DCHECK(task_runner_->BelongsToCurrentThread()); | 1832 DCHECK(task_runner_->BelongsToCurrentThread()); |
1819 for (const auto& stream : streams_) { | 1833 for (const auto& stream : streams_) { |
1820 if (stream) | 1834 if (stream) |
1821 stream->SetLiveness(liveness); | 1835 stream->SetLiveness(liveness); |
1822 } | 1836 } |
1823 } | 1837 } |
1824 | 1838 |
1825 } // namespace media | 1839 } // namespace media |
OLD | NEW |