aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-03-18 08:19:05 +0100
committerMax Kellermann <max@duempel.org>2014-03-18 09:16:09 +0100
commitce18c36ed9328b4b5d376562594d8acb13a6723d (patch)
treecad0dd8470923dcf4765c5d159ab5e530cd8ed19
parent8e39cf62e7f84eca6f8b431bf721281d50653892 (diff)
downloadmpd-ce18c36ed9328b4b5d376562594d8acb13a6723d.tar.gz
mpd-ce18c36ed9328b4b5d376562594d8acb13a6723d.tar.xz
mpd-ce18c36ed9328b4b5d376562594d8acb13a6723d.zip
decoder/ffmpeg: handle unknown stream start time
-rw-r--r--NEWS1
-rw-r--r--src/decoder/FfmpegDecoderPlugin.cxx27
2 files changed, 26 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 5abed4964..66db1f6d8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
ver 0.18.10 (not yet released)
* decoder
- ffmpeg: fix seeking bug
+ - ffmpeg: handle unknown stream start time
- gme: fix memory leak
ver 0.18.9 (2014/03/02)
diff --git a/src/decoder/FfmpegDecoderPlugin.cxx b/src/decoder/FfmpegDecoderPlugin.cxx
index e1e848bf3..bcb1ae3c9 100644
--- a/src/decoder/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/FfmpegDecoderPlugin.cxx
@@ -197,6 +197,29 @@ time_to_ffmpeg(double t, const AVRational time_base)
time_base);
}
+/**
+ * Replace #AV_NOPTS_VALUE with the given fallback.
+ */
+static constexpr int64_t
+timestamp_fallback(int64_t t, int64_t fallback)
+{
+ return gcc_likely(t != int64_t(AV_NOPTS_VALUE))
+ ? t
+ : fallback;
+}
+
+/**
+ * Accessor for AVStream::start_time that replaces AV_NOPTS_VALUE with
+ * zero. We can't use AV_NOPTS_VALUE in calculations, and we simply
+ * assume that the stream's start time is zero, which appears to be
+ * the best way out of that situation.
+ */
+static int64_t
+start_time_fallback(const AVStream &stream)
+{
+ return timestamp_fallback(stream.start_time, 0);
+}
+
static void
copy_interleave_frame2(uint8_t *dest, uint8_t **src,
unsigned nframes, unsigned nchannels,
@@ -263,7 +286,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
{
if (packet->pts >= 0 && packet->pts != (int64_t)AV_NOPTS_VALUE)
decoder_timestamp(decoder,
- time_from_ffmpeg(packet->pts - stream->start_time,
+ time_from_ffmpeg(packet->pts - start_time_fallback(*stream),
stream->time_base));
AVPacket packet2 = *packet;
@@ -493,7 +516,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
int64_t where =
time_to_ffmpeg(decoder_seek_where(decoder),
av_stream->time_base) +
- av_stream->start_time;
+ start_time_fallback(*av_stream);
if (av_seek_frame(format_context, audio_stream, where,
AVSEEK_FLAG_ANY) < 0)