[FFmpeg-devel] [PATCH] ffmpeg: Add option to force a specific decode format

Eoff, Ullysses A ullysses.a.eoff at intel.com
Mon Nov 12 20:13:55 EET 2018


> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf Of Mark Thompson
> Sent: Sunday, November 11, 2018 6:55 AM
> To: ffmpeg-devel at ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH] ffmpeg: Add option to force a specific decode format
> 
> Fixes #7519.
> ---
> I've had this lying around for a bit with intent to use it to support non-hwaccel hardware decoders (in particular, v4l2m2m), but it
> actually fixes the force-hwaccel use-case too in a sensible way.
> 
> 
>  doc/ffmpeg.texi      | 12 ++++++++++++
>  fftools/ffmpeg.c     |  4 ++++
>  fftools/ffmpeg.h     |  4 ++++
>  fftools/ffmpeg_opt.c | 15 +++++++++++++++
>  4 files changed, 35 insertions(+)
> 
> diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
> index 3717f22d42..9f9e693898 100644
> --- a/doc/ffmpeg.texi
> +++ b/doc/ffmpeg.texi
> @@ -920,6 +920,18 @@ would be more efficient.
>  When doing stream copy, copy also non-key frames found at the
>  beginning.
> 
> + at item -decode_format[:@var{stream_specifier}] @var{pixfmt} (@emph{input,per-stream})
> +Set the output format to be used by the decoder for this stream.  If the
> +decoder does not natively support this format for the input stream then
> +decoding will fail rather than continuing with a different format.
> +
> +In general this should not be set - the decoder will select an output
> +format based on the input stream parameters and available components, and
> +that will be automatically converted to whatever the output requires.  It
> +may be useful to force a hardware decoder supporting output in multiple
> +different memory types to pick the desired one, or to ensure that a
> +hardware decoder is used when software fallback is also available.
> +
>  @item -init_hw_device @var{type}[=@var{name}][:@var{device}[, at var{key=value}...]]
>  Initialise a new hardware device of type @var{type} called @var{name}, using the
>  given device parameters.
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 38c21e944a..73bed55e4d 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -2800,6 +2800,10 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
>          const AVCodecHWConfig  *config = NULL;
>          int i;
> 
> +        if (ist->decode_format != AV_PIX_FMT_NONE &&
> +            ist->decode_format != *p)
> +            continue;
> +
>          if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
>              break;
> 
> diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> index eb1eaf6363..88e0aa60ea 100644
> --- a/fftools/ffmpeg.h
> +++ b/fftools/ffmpeg.h
> @@ -125,6 +125,8 @@ typedef struct OptionsContext {
>      int        nb_ts_scale;
>      SpecifierOpt *dump_attachment;
>      int        nb_dump_attachment;
> +    SpecifierOpt *decode_formats;
> +    int        nb_decode_formats;
>      SpecifierOpt *hwaccels;
>      int        nb_hwaccels;
>      SpecifierOpt *hwaccel_devices;
> @@ -334,6 +336,8 @@ typedef struct InputStream {
>      int top_field_first;
>      int guess_layout_max;
> 
> +    enum AVPixelFormat decode_format;
> +
>      int autorotate;
> 
>      int fix_sub_duration;
> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
> index d4851a2cd8..0e3e8b99fe 100644
> --- a/fftools/ffmpeg_opt.c
> +++ b/fftools/ffmpeg_opt.c
> @@ -701,6 +701,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
>          AVStream *st = ic->streams[i];
>          AVCodecParameters *par = st->codecpar;
>          InputStream *ist = av_mallocz(sizeof(*ist));
> +        char *decode_format = NULL;
>          char *framerate = NULL, *hwaccel_device = NULL;
>          const char *hwaccel = NULL;
>          char *hwaccel_output_format = NULL;
> @@ -797,6 +798,17 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
>              ist->top_field_first = -1;
>              MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
> 
> +            MATCH_PER_STREAM_OPT(decode_formats, str, decode_format, ic, st);
> +            if (decode_format) {
> +                ist->decode_format = av_get_pix_fmt(decode_format);
> +                if (ist->decode_format == AV_PIX_FMT_NONE) {
> +                    av_log(NULL, AV_LOG_FATAL, "Unrecognised decode format: %s",
> +                           decode_format);
> +                }
> +            } else {
> +                ist->decode_format = AV_PIX_FMT_NONE;
> +            }
> +
>              MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
>              if (hwaccel) {
>                  // The NVDEC hwaccels use a CUDA device, so remap the name here.
> @@ -3583,6 +3595,9 @@ const OptionDef options[] = {
>          "audio bitrate (please use -b:a)", "bitrate" },
>      { "b",            OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT,            { .func_arg = opt_bitrate },
>          "video bitrate (please use -b:v)", "bitrate" },
> +    { "decode_format",  OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
> +                        OPT_SPEC | OPT_INPUT,                                    { .off = OFFSET(decode_formats) },
> +        "set output format used by decoder, fail if this format is not available", "format" },
>      { "hwaccel",          OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
>                            OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccels) },
>          "use HW accelerated decoding", "hwaccel name" },
> --
> 2.19.1
> 

[UAE] This works for me.  I tested with -decode_format vaapi_vld in the
context of #7519 stack and it did not fallback to software and command failed
as expected.  Then I tried on latest mainline stack and hw decode
succeeds.  Thanks!

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list