1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

avcodec/xwddec: implement FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM

This commit is contained in:
Paul B Mahol 2022-09-24 11:33:45 +02:00
parent cea1e1f261
commit 1e079525d5

View File

@ -32,8 +32,6 @@
static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p, static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
int *got_frame, AVPacket *avpkt) int *got_frame, AVPacket *avpkt)
{ {
const uint8_t *buf = avpkt->data;
int i, ret, buf_size = avpkt->size;
uint32_t version, header_size, vclass, ncolors; uint32_t version, header_size, vclass, ncolors;
uint32_t xoffset, be, bpp, lsize, rsize; uint32_t xoffset, be, bpp, lsize, rsize;
uint32_t pixformat, pixdepth, bunit, bitorder, bpad; uint32_t pixformat, pixdepth, bunit, bitorder, bpad;
@ -41,11 +39,12 @@ static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
uint8_t *ptr; uint8_t *ptr;
int width, height; int width, height;
GetByteContext gb; GetByteContext gb;
int ret;
if (buf_size < XWD_HEADER_SIZE) if (avpkt->size < XWD_HEADER_SIZE)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
bytestream2_init(&gb, buf, buf_size); bytestream2_init(&gb, avpkt->data, avpkt->size);
header_size = bytestream2_get_be32u(&gb); header_size = bytestream2_get_be32u(&gb);
version = bytestream2_get_be32u(&gb); version = bytestream2_get_be32u(&gb);
@ -54,7 +53,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (buf_size < header_size || header_size < XWD_HEADER_SIZE) { if (avpkt->size < header_size || header_size < XWD_HEADER_SIZE) {
av_log(avctx, AV_LOG_ERROR, "invalid header size\n"); av_log(avctx, AV_LOG_ERROR, "invalid header size\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -211,6 +210,9 @@ static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
if (avctx->skip_frame >= AVDISCARD_ALL)
return avpkt->size;
if ((ret = ff_get_buffer(avctx, p, 0)) < 0) if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret; return ret;
@ -221,8 +223,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
uint32_t *dst = (uint32_t *)p->data[1]; uint32_t *dst = (uint32_t *)p->data[1];
uint8_t red, green, blue; uint8_t red, green, blue;
for (i = 0; i < ncolors; i++) { for (int i = 0; i < ncolors; i++) {
bytestream2_skipu(&gb, 4); // skip colormap entry number bytestream2_skipu(&gb, 4); // skip colormap entry number
red = bytestream2_get_byteu(&gb); red = bytestream2_get_byteu(&gb);
bytestream2_skipu(&gb, 1); bytestream2_skipu(&gb, 1);
@ -236,7 +237,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
} }
ptr = p->data[0]; ptr = p->data[0];
for (i = 0; i < avctx->height; i++) { for (int i = 0; i < avctx->height; i++) {
bytestream2_get_bufferu(&gb, ptr, rsize); bytestream2_get_bufferu(&gb, ptr, rsize);
bytestream2_skipu(&gb, lsize - rsize); bytestream2_skipu(&gb, lsize - rsize);
ptr += p->linesize[0]; ptr += p->linesize[0];
@ -244,7 +245,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, AVFrame *p,
*got_frame = 1; *got_frame = 1;
return buf_size; return avpkt->size;
} }
const FFCodec ff_xwd_decoder = { const FFCodec ff_xwd_decoder = {
@ -253,5 +254,6 @@ const FFCodec ff_xwd_decoder = {
.p.type = AVMEDIA_TYPE_VIDEO, .p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_XWD, .p.id = AV_CODEC_ID_XWD,
.p.capabilities = AV_CODEC_CAP_DR1, .p.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
FF_CODEC_DECODE_CB(xwd_decode_frame), FF_CODEC_DECODE_CB(xwd_decode_frame),
}; };