diff options
author | Matthieu Bouron <matthieu.bouron@stupeflix.com> | 2015-10-09 15:14:11 +0200 |
---|---|---|
committer | Matthieu Bouron <matthieu.bouron@stupeflix.com> | 2015-10-29 12:04:06 +0100 |
commit | cbe2dfa4e51b92b0e291ed71be6fcee595c4201d (patch) | |
tree | 294b1a707f1c2ba7d27678b7389e35f225d2d02d | |
parent | fc460fe618478982829950f9a806ba29c6607517 (diff) | |
download | ffmpeg-cbe2dfa4e51b92b0e291ed71be6fcee595c4201d.tar.gz |
lavc/pngdec: honor skip_frame option
-rw-r--r-- | libavcodec/pngdec.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 99111d4ecc..0bdd04e6d7 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1088,6 +1088,13 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, for (;;) { length = bytestream2_get_bytes_left(&s->gb); if (length <= 0) { + + if (avctx->codec_id == AV_CODEC_ID_PNG && + avctx->skip_frame == AVDISCARD_ALL) { + av_frame_set_metadata(p, metadata); + return 0; + } + if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && length == 0) { if (!(s->state & PNG_IDAT)) return 0; @@ -1115,6 +1122,20 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, ((tag >> 8) & 0xff), ((tag >> 16) & 0xff), ((tag >> 24) & 0xff), length); + + if (avctx->codec_id == AV_CODEC_ID_PNG && + avctx->skip_frame == AVDISCARD_ALL) { + switch(tag) { + case MKTAG('I', 'H', 'D', 'R'): + case MKTAG('p', 'H', 'Y', 's'): + case MKTAG('t', 'E', 'X', 't'): + case MKTAG('I', 'D', 'A', 'T'): + break; + default: + goto skip_tag; + } + } + switch (tag) { case MKTAG('I', 'H', 'D', 'R'): if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0) @@ -1197,6 +1218,11 @@ skip_tag: } } exit_loop: + if (avctx->codec_id == AV_CODEC_ID_PNG && + avctx->skip_frame == AVDISCARD_ALL) { + av_frame_set_metadata(p, metadata); + return 0; + } if (s->bits_per_pixel <= 4) handle_small_bpp(s, p); @@ -1294,6 +1320,12 @@ static int decode_frame_png(AVCodecContext *avctx, if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0) goto the_end; + if (avctx->skip_frame == AVDISCARD_ALL) { + *got_frame = 0; + ret = bytestream2_tell(&s->gb); + goto the_end; + } + if ((ret = av_frame_ref(data, s->picture.f)) < 0) return ret; |