aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthieu Bouron <matthieu.bouron@stupeflix.com>2015-10-09 15:14:11 +0200
committerMatthieu Bouron <matthieu.bouron@stupeflix.com>2015-10-29 12:04:06 +0100
commitcbe2dfa4e51b92b0e291ed71be6fcee595c4201d (patch)
tree294b1a707f1c2ba7d27678b7389e35f225d2d02d
parentfc460fe618478982829950f9a806ba29c6607517 (diff)
downloadffmpeg-cbe2dfa4e51b92b0e291ed71be6fcee595c4201d.tar.gz
lavc/pngdec: honor skip_frame option
-rw-r--r--libavcodec/pngdec.c32
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;