From 2704fe5ce4ecfcb9214c032117be719079b93d89 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Jul 2016 00:44:40 +0100 Subject: [PATCH] Fix start-trim of audio-only content (#915). --- ChangeLog | 4 ++++ src/lib/ffmpeg_decoder.cc | 18 ++++++++++++++++-- src/lib/ffmpeg_stream.cc | 15 +++++++++++++++ src/lib/ffmpeg_stream.h | 6 ++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a099425f6..8904eef6c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-07-28 Carl Hetherington + + * Fix start-trim of audio-only content (#915). + 2016-07-26 Carl Hetherington * Expand vertical size of servers list in preferences (#913). diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 164785c83..f7c435a74 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -40,6 +40,7 @@ #include "audio_decoder.h" #include "compose.hpp" #include "subtitle_content.h" +#include "audio_content.h" #include #include #include @@ -73,6 +74,8 @@ using std::map; using boost::shared_ptr; using boost::is_any_of; using boost::split; +using boost::optional; +using boost::dynamic_pointer_cast; using dcp::Size; FFmpegDecoder::FFmpegDecoder (shared_ptr c, shared_ptr log) @@ -326,7 +329,18 @@ FFmpegDecoder::seek (ContentTime time, bool accurate) http://www.mjbshaw.com/2012/04/seeking-in-ffmpeg-know-your-timestamp.html */ - DCPOMATIC_ASSERT (_video_stream); + optional stream; + + if (_video_stream) { + stream = _video_stream; + } else { + shared_ptr s = dynamic_pointer_cast (_ffmpeg_content->audio->stream ()); + if (s) { + stream = s->index (_format_context); + } + } + + DCPOMATIC_ASSERT (stream); ContentTime u = time - _pts_offset; if (u < ContentTime ()) { @@ -376,7 +390,7 @@ FFmpegDecoder::decode_audio_packet () if (decode_result < 0) { /* avcodec_decode_audio4 can sometimes return an error even though it has decoded some valid data; for example dca_subframe_footer can return AVERROR_INVALIDDATA - if it overreads the auxiliary data. ffplay carries on if frame_finished is true, + if it overreads the auxiliary data. ffplay carries on if frame_finished is true, even in the face of such an error, so I think we should too. Returning from the method here caused mantis #352. diff --git a/src/lib/ffmpeg_stream.cc b/src/lib/ffmpeg_stream.cc index 085c78fa8..7a8748e4e 100644 --- a/src/lib/ffmpeg_stream.cc +++ b/src/lib/ffmpeg_stream.cc @@ -62,3 +62,18 @@ FFmpegStream::stream (AVFormatContext const * fc) const DCPOMATIC_ASSERT (false); return 0; } + +int +FFmpegStream::index (AVFormatContext const * fc) const +{ + size_t i = 0; + while (i < fc->nb_streams) { + if (fc->streams[i]->id == _id) { + return i; + } + ++i; + } + + DCPOMATIC_ASSERT (false); + return 0; +} diff --git a/src/lib/ffmpeg_stream.h b/src/lib/ffmpeg_stream.h index 317ee2e9c..ec27a30f0 100644 --- a/src/lib/ffmpeg_stream.h +++ b/src/lib/ffmpeg_stream.h @@ -54,6 +54,12 @@ public: return boost::lexical_cast (_id); } + int id () const { + return _id; + } + + int index (AVFormatContext const * c) const; + std::string name; friend bool operator== (FFmpegStream const & a, FFmpegStream const & b); -- 2.30.2