int current_frame;
uint8_t *frame[4];
+ int dirty[4];
int frame_size;
int video_size;
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;
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)
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;
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
.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,
};