X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Ffraps.c;h=3107ba70bf57650dfd1cba4812caf3ead0e7769b;hb=1ce5dce454ea46280b188f0b7e37fc976fcfb606;hp=2bbc7b9f0113b7cda3fc1dfde62f4941ba02e628;hpb=975a1447f76e8d30fc01e6ea5466c84faf3d76e4;p=ffmpeg diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 2bbc7b9f011..3107ba70bf5 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -46,6 +46,7 @@ typedef struct FrapsContext{ AVCodecContext *avctx; AVFrame frame; uint8_t *tmpbuf; + int tmpbuf_size; DSPContext dsp; } FrapsContext; @@ -59,13 +60,13 @@ static av_cold int decode_init(AVCodecContext *avctx) { FrapsContext * const s = avctx->priv_data; - avctx->coded_frame = (AVFrame*)&s->frame; + avctx->coded_frame = &s->frame; avctx->pix_fmt= PIX_FMT_NONE; /* set in decode_frame */ s->avctx = avctx; s->tmpbuf = NULL; - dsputil_init(&s->dsp, avctx); + ff_dsputil_init(&s->dsp, avctx); return 0; } @@ -111,10 +112,14 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, */ if(j) dst[i] += dst[i - stride]; else if(Uoff) dst[i] += 0x80; + if (get_bits_left(&gb) < 0) { + ff_free_vlc(&vlc); + return AVERROR_INVALIDDATA; + } } dst += stride; } - free_vlc(&vlc); + ff_free_vlc(&vlc); return 0; } @@ -126,7 +131,7 @@ static int decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; FrapsContext * const s = avctx->priv_data; AVFrame *frame = data; - AVFrame * const f = (AVFrame*)&s->frame; + AVFrame * const f = &s->frame; uint32_t header; unsigned int version,header_size; unsigned int x, y; @@ -134,7 +139,7 @@ static int decode_frame(AVCodecContext *avctx, uint32_t *luma1,*luma2,*cb,*cr; uint32_t offs[4]; int i, j, is_chroma, planes; - + enum PixelFormat pix_fmt; header = AV_RL32(buf); version = header & 0xff; @@ -151,12 +156,16 @@ static int decode_frame(AVCodecContext *avctx, if (header_size == 8) buf+=4; + pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; + if (avctx->pix_fmt != pix_fmt && f->data[0]) { + avctx->release_buffer(avctx, f); + } + avctx->pix_fmt = pix_fmt; + switch(version) { case 0: default: /* Fraps v0 is a reordered YUV420 */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; - if ( (buf_size != avctx->width*avctx->height*3/2+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -204,8 +213,6 @@ static int decode_frame(AVCodecContext *avctx, case 1: /* Fraps v1 is an upside-down BGR24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - if ( (buf_size != avctx->width*avctx->height*3+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -240,7 +247,6 @@ static int decode_frame(AVCodecContext *avctx, * Fraps v2 is Huffman-coded YUV420 planes * Fraps v4 is virtually the same */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | @@ -272,7 +278,10 @@ static int decode_frame(AVCodecContext *avctx, offs[planes] = buf_size; for(i = 0; i < planes; i++){ is_chroma = !!i; - s->tmpbuf = av_realloc(s->tmpbuf, offs[i + 1] - offs[i] - 1024 + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, + offs[i + 1] - offs[i] - 1024); + if (!s->tmpbuf) + return AVERROR(ENOMEM); if(fraps2_decode_plane(s, f->data[i], f->linesize[i], avctx->width >> is_chroma, avctx->height >> is_chroma, buf + offs[i], offs[i + 1] - offs[i], is_chroma, 1) < 0) { av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i); @@ -283,7 +292,6 @@ static int decode_frame(AVCodecContext *avctx, case 3: case 5: /* Virtually the same as version 4, but is for RGB24 */ - avctx->pix_fmt = PIX_FMT_BGR24; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | @@ -314,7 +322,10 @@ static int decode_frame(AVCodecContext *avctx, } offs[planes] = buf_size; for(i = 0; i < planes; i++){ - s->tmpbuf = av_realloc(s->tmpbuf, offs[i + 1] - offs[i] - 1024 + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, + offs[i + 1] - offs[i] - 1024); + if (!s->tmpbuf) + return AVERROR(ENOMEM); if(fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)), -f->linesize[0], avctx->width, avctx->height, buf + offs[i], offs[i + 1] - offs[i], 0, 3) < 0) { av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i); @@ -356,14 +367,13 @@ static av_cold int decode_end(AVCodecContext *avctx) AVCodec ff_fraps_decoder = { - "fraps", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FRAPS, - sizeof(FrapsContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Fraps"), + .name = "fraps", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_FRAPS, + .priv_data_size = sizeof(FrapsContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Fraps"), };