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

Reply via email to