Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: media/filters/ffmpeg_demuxer.cc

Issue 2491043003: MediaResource refactoring to support multiple streams (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698