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

Unified Diff: media/filters/ffmpeg_demuxer.cc

Issue 334163002: Revert of Fix seeking when the start time is non-zero. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 aac8002145c6625d29394c73210230aaf01ef9c3..f5b4fddad3b97f03040d8f5f209f940f9d8d3d4c 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -55,39 +55,19 @@
frames * base::Time::kMicrosecondsPerSecond / sample_rate);
}
-static base::TimeDelta ExtractStartTime(AVStream* stream) {
- if (stream->start_time == static_cast<int64_t>(AV_NOPTS_VALUE))
- return kNoTimestamp();
-
- // First try to use the |start_time| value directly.
- const base::TimeDelta start_time =
- ConvertFromTimeBase(stream->time_base, stream->start_time);
-
- // Then compare against the first timestamp to see if adjustment is required.
- if (stream->first_dts == static_cast<int64_t>(AV_NOPTS_VALUE))
- return start_time;
-
- const base::TimeDelta first_dts =
- ConvertFromTimeBase(stream->time_base, stream->first_dts);
-
- return first_dts < start_time ? first_dts : start_time;
-}
-
//
// FFmpegDemuxerStream
//
FFmpegDemuxerStream::FFmpegDemuxerStream(
FFmpegDemuxer* demuxer,
- AVStream* stream,
- bool discard_negative_timestamps)
+ AVStream* stream)
: demuxer_(demuxer),
task_runner_(base::MessageLoopProxy::current()),
stream_(stream),
type_(UNKNOWN),
end_of_stream_(false),
last_packet_timestamp_(kNoTimestamp()),
- bitstream_converter_enabled_(false),
- discard_negative_timestamps_(discard_negative_timestamps) {
+ bitstream_converter_enabled_(false) {
DCHECK(demuxer_);
bool is_encrypted = false;
@@ -246,44 +226,16 @@
buffer->set_decrypt_config(decrypt_config.Pass());
}
- buffer->set_duration(
- ConvertStreamTimestamp(stream_->time_base, packet->duration));
-
- // Note: If pts is AV_NOPTS_VALUE, stream_timestamp will be kNoTimestamp().
- const base::TimeDelta stream_timestamp =
- ConvertStreamTimestamp(stream_->time_base, packet->pts);
-
- if (stream_timestamp != kNoTimestamp()) {
- buffer->set_timestamp(stream_timestamp - demuxer_->start_time());
-
- // If enabled, mark packets with negative timestamps for post-decode
- // discard.
- if (discard_negative_timestamps_ && stream_timestamp < base::TimeDelta()) {
- if (stream_timestamp + buffer->duration() < base::TimeDelta()) {
- // Discard the entier packet if it's entirely before zero.
- buffer->set_discard_padding(
- std::make_pair(kInfiniteDuration(), base::TimeDelta()));
- } else {
- // Only discard part of the frame if it overlaps zero.
- buffer->set_discard_padding(
- std::make_pair(-stream_timestamp, base::TimeDelta()));
- }
- }
-
- if (last_packet_timestamp_ != kNoTimestamp() &&
- last_packet_timestamp_ < buffer->timestamp()) {
- buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
- demuxer_->NotifyBufferingChanged();
- }
-
- // The demuxer should always output positive timestamps.
- DCHECK(buffer->timestamp() >= base::TimeDelta());
- } else {
- buffer->set_timestamp(kNoTimestamp());
- }
-
- // TODO(dalecurtis): This allows transitions from <valid ts> -> <no timestamp>
- // which shouldn't be allowed. See http://crbug.com/384532
+ buffer->set_timestamp(ConvertStreamTimestamp(
+ stream_->time_base, packet->pts));
+ buffer->set_duration(ConvertStreamTimestamp(
+ stream_->time_base, packet->duration));
+ if (buffer->timestamp() != kNoTimestamp() &&
+ last_packet_timestamp_ != kNoTimestamp() &&
+ last_packet_timestamp_ < buffer->timestamp()) {
+ buffered_ranges_.Add(last_packet_timestamp_, buffer->timestamp());
+ demuxer_->NotifyBufferingChanged();
+ }
last_packet_timestamp_ = buffer->timestamp();
buffer_queue_.Push(buffer);
@@ -314,6 +266,10 @@
demuxer_ = NULL;
stream_ = NULL;
end_of_stream_ = true;
+}
+
+base::TimeDelta FFmpegDemuxerStream::duration() {
+ return duration_;
}
DemuxerStream::Type FFmpegDemuxerStream::type() {
@@ -464,7 +420,6 @@
text_enabled_(false),
duration_known_(false),
need_key_cb_(need_key_cb),
- stream_index_for_seeking_(0),
weak_factory_(this) {
DCHECK(task_runner_.get());
DCHECK(data_source_);
@@ -490,20 +445,21 @@
// otherwise we can end up waiting for a pre-seek read to complete even though
// we know we're going to drop it on the floor.
- const AVStream* seeking_stream =
- glue_->format_context()->streams[stream_index_for_seeking_];
-
+ // Always seek to a timestamp less than or equal to the desired timestamp.
+ int flags = AVSEEK_FLAG_BACKWARD;
+
+ // Passing -1 as our stream index lets FFmpeg pick a default stream. FFmpeg
+ // will attempt to use the lowest-index video stream, if present, followed by
+ // the lowest-index audio stream.
pending_seek_ = true;
base::PostTaskAndReplyWithResult(
blocking_thread_.message_loop_proxy().get(),
FROM_HERE,
- base::Bind(
- &av_seek_frame,
- glue_->format_context(),
- stream_index_for_seeking_,
- ConvertToTimeBase(seeking_stream->time_base, time + start_time()),
- // Always seek to a timestamp <= to the desired timestamp.
- AVSEEK_FLAG_BACKWARD),
+ base::Bind(&av_seek_frame,
+ glue_->format_context(),
+ -1,
+ time.InMicroseconds(),
+ flags),
base::Bind(
&FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr(), cb));
}
@@ -550,6 +506,11 @@
}
}
return NULL;
+}
+
+base::TimeDelta FFmpegDemuxer::GetStartTime() const {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ return start_time_;
}
base::Time FFmpegDemuxer::GetTimelineOffset() const {
@@ -667,15 +628,11 @@
AVStream* video_stream = NULL;
VideoDecoderConfig video_config;
- // If available, |start_time_| will be set to the lowest stream start time.
- start_time_ = kInfiniteDuration();
-
base::TimeDelta max_duration;
for (size_t i = 0; i < format_context->nb_streams; ++i) {
AVStream* stream = format_context->streams[i];
- const AVCodecContext* codec_context = stream->codec;
- const AVMediaType codec_type = codec_context->codec_type;
- bool discard_negative_timestamps = false;
+ AVCodecContext* codec_context = stream->codec;
+ AVMediaType codec_type = codec_context->codec_type;
if (codec_type == AVMEDIA_TYPE_AUDIO) {
if (audio_stream)
@@ -690,13 +647,6 @@
if (!audio_config.IsValidConfig())
continue;
audio_stream = stream;
-
- // Enable post-decode frame dropping for packets with negative timestamps
- // as outlined in section A.2 in the Ogg Vorbis spec:
- // http://xiph.org/vorbis/doc/Vorbis_I_spec.html
- discard_negative_timestamps =
- audio_config.codec() == kCodecVorbis &&
- strcmp(glue_->format_context()->iformat->name, "ogg") == 0;
} else if (codec_type == AVMEDIA_TYPE_VIDEO) {
if (video_stream)
continue;
@@ -719,20 +669,14 @@
continue;
}
- streams_[i] =
- new FFmpegDemuxerStream(this, stream, discard_negative_timestamps);
+ streams_[i] = new FFmpegDemuxerStream(this, stream);
max_duration = std::max(max_duration, streams_[i]->duration());
- const base::TimeDelta start_time = ExtractStartTime(stream);
- if (start_time == kNoTimestamp())
- continue;
-
- // Find the lowest stream start time. Prefer the video stream for seeking
- // in the event of matching stream start times.
- if (start_time < start_time_ ||
- (codec_type == AVMEDIA_TYPE_VIDEO && start_time <= start_time_)) {
- stream_index_for_seeking_ = i;
- start_time_ = start_time;
+ if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) {
+ const base::TimeDelta first_dts = ConvertFromTimeBase(
+ stream->time_base, stream->first_dts);
+ if (start_time_ == kNoTimestamp() || first_dts < start_time_)
+ start_time_ = first_dts;
}
}
@@ -756,14 +700,10 @@
max_duration = kInfiniteDuration();
}
- // 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 (start_time_ == kInfiniteDuration()) {
+ // Some demuxers, like WAV, do not put timestamps on their frames. We
+ // assume the the start time is 0.
+ if (start_time_ == kNoTimestamp())
start_time_ = base::TimeDelta();
- stream_index_for_seeking_ =
- video_stream ? video_stream->index : audio_stream->index;
- }
// MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
// generation so we always get timestamps, see http://crbug.com/169570
@@ -771,11 +711,6 @@
format_context->flags |= AVFMT_FLAG_GENPTS;
timeline_offset_ = ExtractTimelineOffset(format_context);
-
- // Since we're shifting the externally visible start time to zero, we need to
- // adjust the timeline offset to compensate.
- if (!timeline_offset_.is_null())
- timeline_offset_ += start_time_;
if (max_duration == kInfiniteDuration() && !timeline_offset_.is_null()) {
liveness_ = LIVENESS_LIVE;
@@ -848,6 +783,7 @@
media_log_->SetBooleanProperty("found_video_stream", false);
}
+
media_log_->SetTimeProperty("max_duration", max_duration);
media_log_->SetTimeProperty("start_time", start_time_);
media_log_->SetIntegerProperty("bitrate", bitrate_);
« 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