]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/pafvideo.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / pafvideo.c
index 7c5861dfaf6c609cba1124b19a351bf6f5e5a307..bb5c17b6a10ca9c7392b63abc18d3bc2d406485a 100644 (file)
@@ -55,6 +55,7 @@ typedef struct PAFVideoDecContext {
 
     int current_frame;
     uint8_t *frame[4];
+    int dirty[4];
     int frame_size;
     int video_size;
 
@@ -103,10 +104,8 @@ static av_cold int paf_video_init(AVCodecContext *avctx)
     c->video_size = avctx->width * avctx->height;
     for (i = 0; i < 4; i++) {
         c->frame[i] = av_mallocz(c->frame_size);
-        if (!c->frame[i]) {
-            paf_video_close(avctx);
+        if (!c->frame[i])
             return AVERROR(ENOMEM);
-        }
     }
 
     return 0;
@@ -187,6 +186,7 @@ static int decode_0(PAFVideoDecContext *c, uint8_t *pkt, uint8_t code)
             j      = bytestream2_get_le16(&c->gb) + offset;
             if (bytestream2_get_bytes_left(&c->gb) < (j - offset) * 16)
                 return AVERROR_INVALIDDATA;
+            c->dirty[page] = 1;
             do {
                 offset++;
                 if (dst + 3 * c->width + 4 > dend)
@@ -285,13 +285,14 @@ static int paf_video_decode(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
+    if ((code & 0xF) == 0 &&
+        c->video_size / 32 - (int64_t)bytestream2_get_bytes_left(&c->gb) > c->video_size / 32 * (int64_t)avctx->discard_damaged_percentage / 100)
+        return AVERROR_INVALIDDATA;
+
+    if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
         return ret;
 
     if (code & 0x20) {  // frame is keyframe
-        for (i = 0; i < 4; i++)
-            memset(c->frame[i], 0, c->frame_size);
-
         memset(c->pic->data[1], 0, AVPALETTE_SIZE);
         c->current_frame  = 0;
         c->pic->key_frame = 1;
@@ -328,6 +329,14 @@ static int paf_video_decode(AVCodecContext *avctx, void *data,
         c->pic->palette_has_changed = 1;
     }
 
+    c->dirty[c->current_frame] = 1;
+    if (code & 0x20)
+        for (i = 0; i < 4; i++) {
+            if (c->dirty[i])
+                memset(c->frame[i], 0, c->frame_size);
+            c->dirty[i] = 0;
+        }
+
     switch (code & 0x0F) {
     case 0:
         /* Block-based motion compensation using 4x4 blocks with either
@@ -398,7 +407,7 @@ static int paf_video_decode(AVCodecContext *avctx, void *data,
     return pkt->size;
 }
 
-AVCodec ff_paf_video_decoder = {
+const AVCodec ff_paf_video_decoder = {
     .name           = "paf_video",
     .long_name      = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -408,4 +417,5 @@ AVCodec ff_paf_video_decoder = {
     .close          = paf_video_close,
     .decode         = paf_video_decode,
     .capabilities   = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };