[FFmpeg-cvslog] avcodec: Add max_pixels options

Michael Niedermayer git at videolan.org
Sat Dec 10 23:32:30 EET 2016


ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Sat Dec 10 21:40:44 2016 +0100| [2f07830e69bd14eaba348eb739b9503e7eb7cd4b] | committer: Michael Niedermayer

avcodec: Add max_pixels options

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2f07830e69bd14eaba348eb739b9503e7eb7cd4b
---

 doc/codecs.texi                      |  4 ++++
 libavcodec/avcodec.h                 |  8 ++++++++
 libavcodec/options_table.h           |  1 +
 libavcodec/utils.c                   | 12 ++++++------
 tests/ref/fate/api-mjpeg-codec-param |  2 ++
 tests/ref/fate/api-png-codec-param   |  2 ++
 6 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/doc/codecs.texi b/doc/codecs.texi
index ca7c523..9a3a56d 100644
--- a/doc/codecs.texi
+++ b/doc/codecs.texi
@@ -1272,6 +1272,10 @@ ffprobe -dump_separator "
                           "  -i ~/videos/matrixbench_mpeg2.mpg
 @end example
 
+ at 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
 
 @c man end CODEC OPTIONS
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 7ac2ada..02234ae 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3570,6 +3570,14 @@ typedef struct AVCodecContext {
      */
     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;
 
 AVRational av_codec_get_pkt_timebase         (const AVCodecContext *avctx);
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index ee79859..3fe7925 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -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 },
 {"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 },
+{"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},
 };
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 89a12c6..44ecc09 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -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 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)
         width = height = 0;
@@ -904,7 +904,7 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
     int ret;
 
     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");
             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)
-        && (  av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0
-           || av_image_check_size(avctx->width,       avctx->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_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");
         ff_set_dimensions(avctx, 0, 0);
     }
@@ -1982,7 +1982,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
         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);
 
     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;
-    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);
 
     avctx->internal->pkt = avpkt;
diff --git a/tests/ref/fate/api-mjpeg-codec-param b/tests/ref/fate/api-mjpeg-codec-param
index c67d1b1..08313ad 100644
--- a/tests/ref/fate/api-mjpeg-codec-param
+++ b/tests/ref/fate/api-mjpeg-codec-param
@@ -155,6 +155,7 @@ stream=0, decode=0
     codec_whitelist=
     pixel_format=yuvj422p
     video_size=400x225
+    max_pixels=2147483647
 stream=0, decode=1
     b=0
     ab=0
@@ -312,3 +313,4 @@ stream=0, decode=1
     codec_whitelist=
     pixel_format=yuvj422p
     video_size=400x225
+    max_pixels=2147483647
diff --git a/tests/ref/fate/api-png-codec-param b/tests/ref/fate/api-png-codec-param
index bd53441..7a9a921 100644
--- a/tests/ref/fate/api-png-codec-param
+++ b/tests/ref/fate/api-png-codec-param
@@ -155,6 +155,7 @@ stream=0, decode=0
     codec_whitelist=
     pixel_format=rgba
     video_size=128x128
+    max_pixels=2147483647
 stream=0, decode=1
     b=0
     ab=0
@@ -312,3 +313,4 @@ stream=0, decode=1
     codec_whitelist=
     pixel_format=rgba
     video_size=128x128
+    max_pixels=2147483647



More information about the ffmpeg-cvslog mailing list