[FFmpeg-devel] [PATCH] ffmpeg: Add option to force a specific decode format
Mark Thompson
sw at jkqxz.net
Sun Nov 11 16:54:41 EET 2018
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
More information about the ffmpeg-devel
mailing list