[FFmpeg-cvslog] avformat/apngdec: transmit all the chunks between consecutive fcTL ones.

Benoit Fouet git at videolan.org
Mon Nov 24 21:16:28 CET 2014


ffmpeg | branch: master | Benoit Fouet <benoit.fouet at free.fr> | Mon Nov 24 16:12:26 2014 +0100| [9e1cfbd38a18f8ed8ba5ba1f7d21c73a8162ba19] | committer: Michael Niedermayer

avformat/apngdec: transmit all the chunks between consecutive fcTL ones.

In order to support multiple IDAT of fdAT chunks following an fcTL one,
transmit all the chunks between two fcTL ones (or between fcTL and IEND
one).

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

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

 libavformat/apngdec.c |   34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c
index 1e0f1c7..d766a87 100644
--- a/libavformat/apngdec.c
+++ b/libavformat/apngdec.c
@@ -24,10 +24,6 @@
  * APNG demuxer.
  * @see https://wiki.mozilla.org/APNG_Specification
  * @see http://www.w3.org/TR/PNG
- *
- * Not supported (yet):
- *     - streams with chunks other than fcTL / fdAT / IEND after the first fcTL
- *     - streams with multiple fdAT chunks after an fcTL one
  */
 
 #include "avformat.h"
@@ -325,8 +321,6 @@ static int apng_read_packet(AVFormatContext *s, AVPacket *pkt)
      * and needed next:
      *  4 (length)
      *  4 (tag (must be fdAT or IDAT))
-     *
-     *  TODO: support multiple fdAT following an fcTL
      */
     /* if num_play is not 1, then the seekback is already guaranteed */
     if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 46)) < 0)
@@ -350,15 +344,35 @@ static int apng_read_packet(AVFormatContext *s, AVPacket *pkt)
             tag != MKTAG('I', 'D', 'A', 'T'))
             return AVERROR_INVALIDDATA;
 
-        if ((ret = avio_seek(pb, -46, SEEK_CUR)) < 0)
-            return ret;
-
         size = 38 /* fcTL */ + 8 /* len, tag */ + len + 4 /* crc */;
         if (size > INT_MAX)
             return AVERROR(EINVAL);
 
-        if ((ret = av_get_packet(pb, pkt, size)) < 0)
+        if ((ret = avio_seek(pb, -46, SEEK_CUR)) < 0 ||
+            (ret = av_append_packet(pb, pkt, size)) < 0)
+            return ret;
+
+        if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
+            return ret;
+
+        len = avio_rb32(pb);
+        tag = avio_rl32(pb);
+        while (tag &&
+               tag != MKTAG('f', 'c', 'T', 'L') &&
+               tag != MKTAG('I', 'E', 'N', 'D')) {
+            if (len > 0x7fffffff)
+                return AVERROR_INVALIDDATA;
+            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
+                (ret = av_append_packet(pb, pkt, len + 12)) < 0)
+                return ret;
+            if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
+                return ret;
+            len = avio_rb32(pb);
+            tag = avio_rl32(pb);
+        }
+        if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
             return ret;
+
         if (ctx->is_key_frame)
             pkt->flags |= AV_PKT_FLAG_KEY;
         return ret;



More information about the ffmpeg-cvslog mailing list