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.

>      } else {
>          if (!s->last_frame.data[0]) {
>              av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding 
> intra frame\n");
>              return buf_size;
>          }
> -        s->frame.key_frame = 0;
> -        s->frame.pict_type = AV_PICTURE_TYPE_P;
> -        if (tgv_decode_inter(s, buf, buf_end) < 0) {
> +        frame->key_frame = 0;
> +        frame->pict_type = AV_PICTURE_TYPE_P;
> +        if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {
>              av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
>              return AVERROR_INVALIDDATA;
>          }
>      }
>  
> +    av_frame_unref(&s->last_frame);
> +    if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
> +        return ret;
> +
>      *got_frame = 1;
> -    *(AVFrame*)data = s->frame;
>  
>      return buf_size;
>  }
> @@ -339,8 +332,8 @@ static int tgv_decode_frame(AVCodecContext *avctx,
>  static av_cold int tgv_decode_end(AVCodecContext *avctx)
>  {
>      TgvContext *s = avctx->priv_data;
> -    cond_release_buffer(&s->frame);
> -    cond_release_buffer(&s->last_frame);
> +    av_frame_unref(&s->last_frame);
> +    av_freep(&s->frame_buffer);
>      av_free(s->mv_codebook);
>      av_free(s->block_codebook);
>      return 0;
> @@ -355,4 +348,5 @@ AVCodec ff_eatgv_decoder = {
>      .close          = tgv_decode_end,
>      .decode         = tgv_decode_frame,
>      .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
> +    .capabilities   = CODEC_CAP_DR1,
>  };

probably ok

Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to