[FFmpeg-devel] [PATCH 10/10] avcodec/pngdec: split frame decoding in its own function.

Benoit Fouet benoit.fouet at free.fr
Fri Nov 14 10:17:39 CET 2014


---
 libavcodec/pngdec.c | 88 +++++++++++++++++++++++++++++------------------------
 1 file changed, 49 insertions(+), 39 deletions(-)

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index d3c8ef9..57b73c1 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -786,44 +786,12 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
     }
 }
 
-static int decode_frame_png(AVCodecContext *avctx,
-                        void *data, int *got_frame,
-                        AVPacket *avpkt)
+static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
+                               AVFrame *p, AVPacket *avpkt)
 {
-    PNGDecContext *const s = avctx->priv_data;
-    const uint8_t *buf     = avpkt->data;
-    int buf_size           = avpkt->size;
-    AVFrame *p;
     AVDictionary *metadata  = NULL;
     uint32_t tag, length;
-    int64_t sig;
-    int ret;
 
-    ff_thread_release_buffer(avctx, &s->last_picture);
-    FFSWAP(ThreadFrame, s->picture, s->last_picture);
-    p = s->picture.f;
-
-    bytestream2_init(&s->gb, buf, buf_size);
-
-    /* check signature */
-    sig = bytestream2_get_be64(&s->gb);
-    if (sig != PNGSIG &&
-        sig != MNGSIG) {
-        av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    s->y = s->state = 0;
-
-    /* init the zlib */
-    s->zstream.zalloc = ff_png_zalloc;
-    s->zstream.zfree  = ff_png_zfree;
-    s->zstream.opaque = NULL;
-    ret = inflateInit(&s->zstream);
-    if (ret != Z_OK) {
-        av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
-        return AVERROR_EXTERNAL;
-    }
     for (;;) {
         if (bytestream2_get_bytes_left(&s->gb) <= 0) {
             av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", bytestream2_get_bytes_left(&s->gb));
@@ -921,6 +889,53 @@ exit_loop:
 
     av_frame_set_metadata(p, metadata);
     metadata   = NULL;
+    return 0;
+
+fail:
+    av_dict_free(&metadata);
+    ff_thread_report_progress(&s->picture, INT_MAX, 0);
+    return AVERROR_INVALIDDATA;
+}
+
+static int decode_frame_png(AVCodecContext *avctx,
+                        void *data, int *got_frame,
+                        AVPacket *avpkt)
+{
+    PNGDecContext *const s = avctx->priv_data;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    AVFrame *p;
+    int64_t sig;
+    int ret;
+
+    ff_thread_release_buffer(avctx, &s->last_picture);
+    FFSWAP(ThreadFrame, s->picture, s->last_picture);
+    p = s->picture.f;
+
+    bytestream2_init(&s->gb, buf, buf_size);
+
+    /* check signature */
+    sig = bytestream2_get_be64(&s->gb);
+    if (sig != PNGSIG &&
+        sig != MNGSIG) {
+        av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->y = s->state = 0;
+
+    /* init the zlib */
+    s->zstream.zalloc = ff_png_zalloc;
+    s->zstream.zfree  = ff_png_zfree;
+    s->zstream.opaque = NULL;
+    ret = inflateInit(&s->zstream);
+    if (ret != Z_OK) {
+        av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
+        return AVERROR_EXTERNAL;
+    }
+
+    if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+        goto the_end;
 
     if ((ret = av_frame_ref(data, s->picture.f)) < 0)
         return ret;
@@ -932,11 +947,6 @@ the_end:
     inflateEnd(&s->zstream);
     s->crow_buf = NULL;
     return ret;
-fail:
-    av_dict_free(&metadata);
-    ff_thread_report_progress(&s->picture, INT_MAX, 0);
-    ret = AVERROR_INVALIDDATA;
-    goto the_end;
 }
 
 static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
-- 
2.2.0.rc1.23.gf570943



More information about the ffmpeg-devel mailing list