On Fri, 15 Feb 2013 14:43:57 +0100, Janne Grunau <[email protected]> wrote: > On 2013-01-08 15:37:38 +0100, Anton Khirnov wrote: > > Additionally switch to get_bufer() and enable DR1. > > get_buf*f*er, doesn't matter since it's supposed to squashed although > I'm not too happy with doing both in a single step. > > > --- > > libavcodec/eatgv.c | 74 > > ++++++++++++++++++++++++---------------------------- > > 1 file changed, 34 insertions(+), 40 deletions(-) > > > > diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c > > index 82a12b4..8eb6137 100644 > > --- a/libavcodec/eatgv.c > > +++ b/libavcodec/eatgv.c > > @@ -31,6 +31,7 @@ > > #include "avcodec.h" > > #define BITSTREAM_READER_LE > > #include "get_bits.h" > > +#include "internal.h" > > #include "libavutil/imgutils.h" > > #include "libavutil/mem.h" > > > > @@ -39,8 +40,8 @@ > > > > typedef struct TgvContext { > > AVCodecContext *avctx; > > - AVFrame frame; > > AVFrame last_frame; > > + uint8_t *frame_buffer; > > int width,height; > > uint32_t palette[AVPALETTE_COUNT]; > > > > @@ -138,8 +139,8 @@ static int unpack(const uint8_t *src, const uint8_t > > *src_end, > > * Decode inter-frame > > * @return 0 on success, -1 on critical buffer underflow > > */ > > -static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, > > - const uint8_t *buf_end) > > +static int tgv_decode_inter(TgvContext * s, AVFrame *frame, > > + const uint8_t *buf, const uint8_t *buf_end) > > { > > int num_mvs; > > int num_blocks_raw; > > @@ -237,22 +238,13 @@ static int tgv_decode_inter(TgvContext * s, const > > uint8_t *buf, > > > > for (j = 0; j < 4; j++) > > for (i = 0; i < 4; i++) > > - s->frame.data[0][(y * 4 + j) * s->frame.linesize[0] + > > (x * 4 + i)] = > > + frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * > > 4 + i)] = > > src[j * src_stride + i]; > > } > > > > return 0; > > } > > > > -/** release AVFrame buffers if allocated */ > > -static void cond_release_buffer(AVFrame *pic) > > -{ > > - if (pic->data[0]) { > > - av_freep(&pic->data[0]); > > - av_free(pic->data[1]); > > - } > > -} > > - > > static int tgv_decode_frame(AVCodecContext *avctx, > > void *data, int *got_frame, > > AVPacket *avpkt) > > @@ -261,6 +253,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, > > int buf_size = avpkt->size; > > TgvContext *s = avctx->priv_data; > > const uint8_t *buf_end = buf + buf_size; > > + AVFrame *frame = data; > > int chunk_type, ret; > > > > chunk_type = AV_RL32(&buf[0]); > > @@ -277,8 +270,8 @@ static int tgv_decode_frame(AVCodecContext *avctx, > > s->height = AV_RL16(&buf[2]); > > if (s->avctx->width != s->width || s->avctx->height != s->height) { > > avcodec_set_dimensions(s->avctx, s->width, s->height); > > - cond_release_buffer(&s->frame); > > - cond_release_buffer(&s->last_frame); > > + av_freep(&s->frame_buffer); > > + av_frame_unref(&s->last_frame); > > } > > > > pal_count = AV_RL16(&buf[6]); > > @@ -292,46 +285,46 @@ static int tgv_decode_frame(AVCodecContext *avctx, > > if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0) > > return ret; > > > > - /* shuffle */ > > - FFSWAP(AVFrame, s->frame, s->last_frame); > > - if (!s->frame.data[0]) { > > - s->frame.reference = 1; > > - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; > > - s->frame.linesize[0] = s->width; > > + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) > > + return ret; > > > > - s->frame.data[0] = av_malloc(s->width * s->height); > > - if (!s->frame.data[0]) > > - return AVERROR(ENOMEM); > > - s->frame.data[1] = av_malloc(AVPALETTE_SIZE); > > - if (!s->frame.data[1]) { > > - av_freep(&s->frame.data[0]); > > - return AVERROR(ENOMEM); > > - } > > - } > > - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); > > + memcpy(frame->data[1], s->palette, AVPALETTE_SIZE); > > > > if (chunk_type == kVGT_TAG) { > > - s->frame.key_frame = 1; > > - s->frame.pict_type = AV_PICTURE_TYPE_I; > > - if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, > > s->avctx->height) < 0) { > > + int y; > > + frame->key_frame = 1; > > + frame->pict_type = AV_PICTURE_TYPE_I; > > + > > + if (!s->frame_buffer && > > + !(s->frame_buffer = av_malloc(s->width * s->height))) > > + return AVERROR(ENOMEM); > > + > > + if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, > > s->avctx->height) < 0) { > > av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n"); > > return AVERROR_INVALIDDATA; > > } > > + for (y = 0; y < s->height; y++) > > + memcpy(frame->data[0] + y * frame->linesize[0], > > + s->frame_buffer + y * s->width, > > + s->width); > > I guess there is no way to guarantee that get_buffer2() returns a frame > without edges. Although I'm suspect we already have decoders depending > on it. The seperate buffer and memcpy is ugly and direct rendering is a > lie. >
I don't disagree, but Kostya preferred this solution to manually allocating the AVBuffers and constructing the frame from them. I guess for such an obscure decoder it does not really matter. -- Anton Khirnov _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
