typedef struct BlockInfo {
uint8_t *pos;
int size;
- int unp_size;
} BlockInfo;
typedef struct FlashSVContext {
av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
return 1;
}
- avctx->pix_fmt = PIX_FMT_BGR24;
+ avctx->pix_fmt = AV_PIX_FMT_BGR24;
s->frame.data[0] = NULL;
return 0;
}
-static void flashsv2_prime(FlashSVContext *s, uint8_t *src,
- int size, int unp_size)
+static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
{
z_stream zs;
+ int zret; // Zlib return code
zs.zalloc = NULL;
zs.zfree = NULL;
deflate(&zs, Z_SYNC_FLUSH);
deflateEnd(&zs);
- inflateReset(&s->zstream);
+ if ((zret = inflateReset(&s->zstream)) != Z_OK) {
+ av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
+ return AVERROR_UNKNOWN;
+ }
s->zstream.next_in = s->deflate_block;
s->zstream.avail_in = s->deflate_block_size - zs.avail_out;
s->zstream.next_out = s->tmpblock;
s->zstream.avail_out = s->block_size * 3;
inflate(&s->zstream, Z_SYNC_FLUSH);
+
+ return 0;
}
static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
int k;
int ret = inflateReset(&s->zstream);
if (ret != Z_OK) {
- //return -1;
+ av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
+ return AVERROR_UNKNOWN;
}
if (s->zlibprime_curr || s->zlibprime_prev) {
- flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size,
- s->blocks[blk_idx].unp_size);
+ ret = flashsv2_prime(s,
+ s->blocks[blk_idx].pos,
+ s->blocks[blk_idx].size);
+ if (ret < 0)
+ return ret;
}
s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8;
s->zstream.avail_in = block_size;
if (s->is_keyframe) {
s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8);
s->blocks[blk_idx].size = block_size;
- s->blocks[blk_idx].unp_size = s->block_size * 3 - s->zstream.avail_out;
}
if (!s->color_depth) {
/* Flash Screen Video stores the image upside down, so copy
}
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame, AVPacket *avpkt)
{
int buf_size = avpkt->size;
FlashSVContext *s = avctx->priv_data;
return AVERROR_PATCHWELCOME;
}
if (get_bits1(&gb)) {
- av_log_missing_feature(avctx, "custom palette", 1);
+ av_log_missing_feature(avctx, "Custom palette", 1);
return AVERROR_PATCHWELCOME;
}
}
}
if (has_diff) {
+ if (!s->keyframe) {
+ av_log(avctx, AV_LOG_ERROR,
+ "inter frame without keyframe\n");
+ return AVERROR_INVALIDDATA;
+ }
s->diff_start = get_bits(&gb, 8);
s->diff_height = get_bits(&gb, 8);
av_log(avctx, AV_LOG_DEBUG,
av_log_missing_feature(avctx, "zlibprime_curr", 1);
return AVERROR_PATCHWELCOME;
}
+ if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
+ av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
+ "priming\n");
+ return AVERROR_INVALIDDATA;
+ }
size--; // account for flags byte
}
memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
}
- *data_size = sizeof(AVFrame);
+ *got_frame = 1;
*(AVFrame*)data = s->frame;
if ((get_bits_count(&gb) / 8) != buf_size)
.close = flashsv_decode_end,
.decode = flashsv_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_BGR24, PIX_FMT_NONE },
+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
};
#endif /* CONFIG_FLASHSV_DECODER */
.close = flashsv2_decode_end,
.decode = flashsv_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_BGR24, PIX_FMT_NONE },
+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
};
#endif /* CONFIG_FLASHSV2_DECODER */