| 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 |