avcodec: Add max_pixels options

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
pull/242/head
Michael Niedermayer 8 years ago
parent f542b152aa
commit 2f07830e69
  1. 4
      doc/codecs.texi
  2. 8
      libavcodec/avcodec.h
  3. 1
      libavcodec/options_table.h
  4. 12
      libavcodec/utils.c
  5. 2
      tests/ref/fate/api-mjpeg-codec-param
  6. 2
      tests/ref/fate/api-png-codec-param

@ -1272,6 +1272,10 @@ ffprobe -dump_separator "
" -i ~/videos/matrixbench_mpeg2.mpg " -i ~/videos/matrixbench_mpeg2.mpg
@end example @end example
@item max_pixels @var{integer} (@emph{decoding/encoding,video})
Maximum number of pixels per image. This value can be used to avoid out of
memory failures due to large images.
@end table @end table
@c man end CODEC OPTIONS @c man end CODEC OPTIONS

@ -3570,6 +3570,14 @@ typedef struct AVCodecContext {
*/ */
int trailing_padding; int trailing_padding;
/**
* The number of pixels per image to maximally accept.
*
* - decoding: set by user
* - encoding: set by user
*/
int64_t max_pixels;
} AVCodecContext; } AVCodecContext;
AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);

@ -570,6 +570,7 @@ static const AVOption avcodec_options[] = {
{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, A|V|S|D }, {"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, A|V|S|D },
{"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 }, {"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
{"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 }, {"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 },
{"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E },
{NULL}, {NULL},
}; };

@ -209,7 +209,7 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
int ff_set_dimensions(AVCodecContext *s, int width, int height) int ff_set_dimensions(AVCodecContext *s, int width, int height)
{ {
int ret = av_image_check_size(width, height, 0, s); int ret = av_image_check_size2(width, height, s->max_pixels, AV_PIX_FMT_NONE, 0, s);
if (ret < 0) if (ret < 0)
width = height = 0; width = height = 0;
@ -904,7 +904,7 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
int ret; int ret;
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0 || avctx->pix_fmt<0) { if ((ret = av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) {
av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
@ -1338,8 +1338,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
} }
if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height)
&& ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0 && ( av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0
|| av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)) { || av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)) {
av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n");
ff_set_dimensions(avctx, 0, 0); ff_set_dimensions(avctx, 0, 0);
} }
@ -1982,7 +1982,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
return 0; return 0;
} }
if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx))
return AVERROR(EINVAL); return AVERROR(EINVAL);
if (frame && frame->format == AV_PIX_FMT_NONE) if (frame && frame->format == AV_PIX_FMT_NONE)
@ -2233,7 +2233,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
} }
*got_picture_ptr = 0; *got_picture_ptr = 0;
if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) if ((avctx->coded_width || avctx->coded_height) && av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx))
return AVERROR(EINVAL); return AVERROR(EINVAL);
avctx->internal->pkt = avpkt; avctx->internal->pkt = avpkt;

@ -155,6 +155,7 @@ stream=0, decode=0
codec_whitelist= codec_whitelist=
pixel_format=yuvj422p pixel_format=yuvj422p
video_size=400x225 video_size=400x225
max_pixels=2147483647
stream=0, decode=1 stream=0, decode=1
b=0 b=0
ab=0 ab=0
@ -312,3 +313,4 @@ stream=0, decode=1
codec_whitelist= codec_whitelist=
pixel_format=yuvj422p pixel_format=yuvj422p
video_size=400x225 video_size=400x225
max_pixels=2147483647

@ -155,6 +155,7 @@ stream=0, decode=0
codec_whitelist= codec_whitelist=
pixel_format=rgba pixel_format=rgba
video_size=128x128 video_size=128x128
max_pixels=2147483647
stream=0, decode=1 stream=0, decode=1
b=0 b=0
ab=0 ab=0
@ -312,3 +313,4 @@ stream=0, decode=1
codec_whitelist= codec_whitelist=
pixel_format=rgba pixel_format=rgba
video_size=128x128 video_size=128x128
max_pixels=2147483647

Loading…
Cancel
Save