diff --git a/Changelog b/Changelog index c071637d14..92383a723a 100644 --- a/Changelog +++ b/Changelog @@ -29,6 +29,7 @@ version next: - add libavresample audio conversion library for compatibility - MicroDVD decoder - Avid Meridien (AVUI) decoder +- accept + prefix to -pix_fmt option to disable automatic conversions. version 0.10: diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 00a27373a7..6765121680 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -418,6 +418,14 @@ also sources and sinks). This is an alias for @code{-filter:v}. @item -pix_fmt[:@var{stream_specifier}] @var{format} (@emph{input/output,per-stream}) Set pixel format. Use @code{-pix_fmts} to show all the supported pixel formats. +If the selected pixel format can not be selected, ffmpeg will print a +warning and select the best pixel format supported by the encoder. +If @var{pix_fmt} is prefixed by a @code{+}, ffmpeg will exit with an error +if the requested pixel format can not be selected, and automatic conversions +inside filter graphs are disabled. +If @var{pix_fmt} is a single @code{+}, ffmpeg selects the same pixel format +as the input (or graph output) and automatic conversions are disabled. + @item -sws_flags @var{flags} (@emph{input/output}) Set SwScaler flags. @item -vdt @var{n} diff --git a/ffmpeg.c b/ffmpeg.c index 0bd318abc8..fa2c444664 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -319,6 +319,7 @@ typedef struct OutputStream { int copy_initial_nonkeyframes; enum PixelFormat pix_fmts[2]; + int keep_pix_fmt; } OutputStream; @@ -706,6 +707,15 @@ static enum PixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum Pixe static char *choose_pixel_fmts(OutputStream *ost) { + if (ost->keep_pix_fmt) { + if (ost->filter) + avfilter_graph_set_auto_convert(ost->filter->graph->graph, + AVFILTER_AUTO_CONVERT_NONE); + if (ost->st->codec->pix_fmt == PIX_FMT_NONE) + return NULL; + ost->pix_fmts[0] = ost->st->codec->pix_fmt; + return ost->pix_fmts; + } if (ost->st->codec->pix_fmt != PIX_FMT_NONE) { return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc, ost->st->codec->pix_fmt))); } else if (ost->enc->pix_fmts) { @@ -835,6 +845,10 @@ static int configure_video_filters(FilterGraph *fg) return ret; } + if (ost->keep_pix_fmt) + avfilter_graph_set_auto_convert(fg->graph, + AVFILTER_AUTO_CONVERT_NONE); + if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) return ret; @@ -4661,6 +4675,11 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st); + if (frame_pix_fmt && *frame_pix_fmt == '+') { + ost->keep_pix_fmt = 1; + if (!*++frame_pix_fmt) + frame_pix_fmt = NULL; + } if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == PIX_FMT_NONE) { av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt); exit_program(1);