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

Unified Diff: media/filters/ffmpeg_demuxer.cc

Issue 2281843002: Refactor stream selection for seeking in FFmpegDemuxer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR feedback Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/ffmpeg_demuxer.cc
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index b34d8bc3cb784c81bdae8ca48c4c1ee5d77076b5..49d18d3823f115a335a1e0b88df7c572b2c46960 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -264,6 +264,7 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(
: demuxer_(demuxer),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
stream_(stream),
+ start_time_(kNoTimestamp),
audio_config_(audio_config.release()),
video_config_(video_config.release()),
type_(UNKNOWN),
@@ -825,8 +826,6 @@ FFmpegDemuxer::FFmpegDemuxer(
media_log_(media_log),
bitrate_(0),
start_time_(kNoTimestamp),
- preferred_stream_for_seeking_(-1, kNoTimestamp),
- fallback_stream_for_seeking_(-1, kNoTimestamp),
text_enabled_(false),
duration_known_(false),
encrypted_media_init_data_cb_(encrypted_media_init_data_cb),
@@ -951,16 +950,10 @@ void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
// be demuxed. It's an open question whether FFmpeg should fix this:
// http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html
// Tracked by http://crbug.com/387996.
- DCHECK(preferred_stream_for_seeking_.second != kNoTimestamp);
- const int stream_index =
- seek_time < preferred_stream_for_seeking_.second &&
- seek_time >= fallback_stream_for_seeking_.second
- ? fallback_stream_for_seeking_.first
- : preferred_stream_for_seeking_.first;
- DCHECK_NE(stream_index, -1);
-
- const AVStream* seeking_stream =
- glue_->format_context()->streams[stream_index];
+ FFmpegDemuxerStream* demux_stream = FindPreferredStreamForSeeking(seek_time);
+ DCHECK(demux_stream);
+ const AVStream* seeking_stream = demux_stream->av_stream();
+ DCHECK(seeking_stream);
pending_seek_ = true;
base::PostTaskAndReplyWithResult(
@@ -1318,22 +1311,12 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
ExtractStartTime(stream, start_time_estimates[i]);
const bool has_start_time = start_time != kNoTimestamp;
- // Always prefer the video stream for seeking. If none exists, we'll swap
- // the fallback stream with the preferred stream below.
- if (codec_type == AVMEDIA_TYPE_VIDEO) {
- preferred_stream_for_seeking_ =
- StreamSeekInfo(i, has_start_time ? start_time : base::TimeDelta());
- }
-
if (!has_start_time)
continue;
+ streams_[i]->set_start_time(start_time);
if (start_time < start_time_) {
start_time_ = start_time;
-
- // Choose the stream with the lowest starting time as the fallback stream
- // for seeking. Video should always be preferred.
- fallback_stream_for_seeking_ = StreamSeekInfo(i, start_time);
}
}
@@ -1383,28 +1366,22 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
(strcmp(format_context->iformat->name, "ogg") == 0 &&
audio_stream->codec->codec_id == AV_CODEC_ID_VORBIS))) {
for (size_t i = 0; i < streams_.size(); ++i) {
- if (streams_[i])
- streams_[i]->enable_negative_timestamp_fixups();
- }
+ if (!streams_[i])
+ continue;
+ streams_[i]->enable_negative_timestamp_fixups();
- // Fixup the seeking information to avoid selecting the audio stream simply
- // because it has a lower starting time.
- if (fallback_stream_for_seeking_.first == audio_stream->index &&
- fallback_stream_for_seeking_.second < base::TimeDelta()) {
- fallback_stream_for_seeking_.second = base::TimeDelta();
+ // Fixup the seeking information to avoid selecting the audio stream
+ // simply because it has a lower starting time.
+ if (streams_[i]->av_stream() == audio_stream &&
+ streams_[i]->start_time() < base::TimeDelta()) {
+ streams_[i]->set_start_time(base::TimeDelta());
+ }
}
}
- // If no start time could be determined, default to zero and prefer the video
- // stream over the audio stream for seeking. E.g., The WAV demuxer does not
- // put timestamps on its frames.
+ // If no start time could be determined, default to zero.
if (start_time_ == kInfiniteDuration) {
start_time_ = base::TimeDelta();
- preferred_stream_for_seeking_ = StreamSeekInfo(
- video_stream ? video_stream->index : audio_stream->index, start_time_);
- } else if (!video_stream) {
- // If no video stream exists, use the audio or text stream found above.
- preferred_stream_for_seeking_ = fallback_stream_for_seeking_;
}
// MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
@@ -1490,6 +1467,45 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
status_cb.Run(PIPELINE_OK);
}
+FFmpegDemuxerStream* FFmpegDemuxer::FindPreferredStreamForSeeking(
+ base::TimeDelta seek_time) {
+ // If we have a selected/enabled video stream and its start time is lower
+ // than the |seek_time| or unknown, then always prefer it for seeking.
+ FFmpegDemuxerStream* video_stream = nullptr;
+ for (const auto& stream : streams_) {
+ if (stream && stream->type() == DemuxerStream::VIDEO && stream->enabled()) {
+ video_stream = stream;
+ if (video_stream->start_time() == kNoTimestamp ||
+ video_stream->start_time() <= seek_time) {
+ return stream;
+ }
+ break;
+ }
+ }
+
+ // If video stream is not present or |seek_time| is lower than the video start
+ // time, then try to find an enabled stream with the lowest start time.
+ FFmpegDemuxerStream* lowest_start_time_stream = nullptr;
+ for (const auto& stream : streams_) {
+ if (!stream || !stream->enabled() || stream->start_time() == kNoTimestamp)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream;
+ }
+ }
+ // If we found a stream with start time lower than |seek_time|, then use it.
+ if (lowest_start_time_stream &&
+ lowest_start_time_stream->start_time() <= seek_time) {
+ return lowest_start_time_stream;
+ }
+
+ // If we couldn't find any streams with the start time lower than |seek_time|
+ // then use either video (if one exists) or any audio stream.
+ return video_stream ? video_stream : static_cast<FFmpegDemuxerStream*>(
+ GetStream(DemuxerStream::AUDIO));
+}
+
void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
DCHECK(task_runner_->BelongsToCurrentThread());
CHECK(pending_seek_);
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698