diff --git a/NEWS b/NEWS index 679d1b25b..510aff088 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.20.2 (not yet released) +* decoder + - flac: add options "probesize" and "analyzeduration" ver 0.20.1 (2017/01/09) * input diff --git a/doc/user.xml b/doc/user.xml index a3add674d..b9797d03a 100644 --- a/doc/user.xml +++ b/doc/user.xml @@ -2206,6 +2206,48 @@ run</programlisting> Decodes various codecs using <application>FFmpeg</application>. </para> + + <informaltable> + <tgroup cols="2"> + <thead> + <row> + <entry>Setting</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry> + <varname>analyzeduration</varname> + <parameter>VALUE</parameter> + </entry> + <entry> + Sets the FFmpeg muxer option + <varname>analyzeduration</varname>, which specifies + how many microseconds are analyzed to probe the + input. The <ulink + url="https://ffmpeg.org/ffmpeg-formats.html">FFmpeg + formats documentation</ulink> has more information. + </entry> + </row> + + <row> + <entry> + <varname>probesize</varname> + <parameter>VALUE</parameter> + </entry> + <entry> + Sets the FFmpeg muxer option + <varname>probesize</varname>, which specifies + probing size in bytes, i.e. the size of the data to + analyze to get stream information. The <ulink + url="https://ffmpeg.org/ffmpeg-formats.html">FFmpeg + formats documentation</ulink> has more information. + </entry> + </row> + </tbody> + </tgroup> + </informaltable> </section> <section id="flac_decoder"> diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 1ba0c9de2..698645380 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -56,6 +56,11 @@ extern "C" { #include <assert.h> #include <string.h> +/** + * Muxer options to be passed to avformat_open_input(). + */ +static AVDictionary *avformat_options = nullptr; + static AVFormatContext * FfmpegOpenInput(AVIOContext *pb, const char *filename, @@ -67,7 +72,11 @@ FfmpegOpenInput(AVIOContext *pb, context->pb = pb; - int err = avformat_open_input(&context, filename, fmt, nullptr); + AVDictionary *options = nullptr; + AtScopeExit(&options) { av_dict_free(&options); }; + av_dict_copy(&options, avformat_options, 0); + + int err = avformat_open_input(&context, filename, fmt, &options); if (err < 0) throw MakeFfmpegError(err, "avformat_open_input() failed"); @@ -75,12 +84,30 @@ FfmpegOpenInput(AVIOContext *pb, } static bool -ffmpeg_init(gcc_unused const ConfigBlock &block) +ffmpeg_init(const ConfigBlock &block) { FfmpegInit(); + + static constexpr const char *option_names[] = { + "probesize", + "analyzeduration", + }; + + for (const char *name : option_names) { + const char *value = block.GetBlockValue(name); + if (value != nullptr) + av_dict_set(&avformat_options, name, value, 0); + } + return true; } +static void +ffmpeg_finish() +{ + av_dict_free(&avformat_options); +} + #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 25, 0) /* FFmpeg 3.1 */ gcc_pure @@ -967,7 +994,7 @@ static const char *const ffmpeg_mime_types[] = { const struct DecoderPlugin ffmpeg_decoder_plugin = { "ffmpeg", ffmpeg_init, - nullptr, + ffmpeg_finish, ffmpeg_decode, nullptr, nullptr,