On 2013-01-08 15:37:40 +0100, Anton Khirnov wrote:
> ---
>  libavcodec/eacmv.c |   87 
> ++++++++++++++++++++++++++++------------------------
>  1 file changed, 47 insertions(+), 40 deletions(-)
> 
> diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
> index 0dce066..5971815 100644
> --- a/libavcodec/eacmv.c
> +++ b/libavcodec/eacmv.c
> @@ -36,9 +36,8 @@
>  
>  typedef struct CmvContext {
>      AVCodecContext *avctx;
> -    AVFrame frame;        ///< current
> -    AVFrame last_frame;   ///< last
> -    AVFrame last2_frame;  ///< second-last
> +    AVFrame *last_frame;   ///< last
> +    AVFrame *last2_frame;  ///< second-last
>      int width, height;
>      unsigned int palette[AVPALETTE_COUNT];
>  } CmvContext;
> @@ -47,16 +46,27 @@ static av_cold int cmv_decode_init(AVCodecContext *avctx){
>      CmvContext *s = avctx->priv_data;
>      s->avctx = avctx;
>      avctx->pix_fmt = AV_PIX_FMT_PAL8;
> +
> +    s->last_frame  = av_frame_alloc();
> +    s->last2_frame = av_frame_alloc();
> +    if (!s->last_frame || !s->last2_frame) {
> +        av_frame_free(&s->last_frame);
> +        av_frame_free(&s->last2_frame);
> +        return AVERROR(ENOMEM);
> +    }
> +
>      return 0;
>  }
>  
> -static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const 
> uint8_t *buf_end){
> -    unsigned char *dst = s->frame.data[0];
> +static void cmv_decode_intra(CmvContext * s, AVFrame *frame,
> +                             const uint8_t *buf, const uint8_t *buf_end)
> +{
> +    unsigned char *dst = frame->data[0];
>      int i;
>  
>      for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) 
> {
>          memcpy(dst, buf, s->avctx->width);
> -        dst += s->frame.linesize[0];
> +        dst += frame->linesize[0];
>          buf += s->avctx->width;
>      }
>  }
> @@ -80,7 +90,9 @@ static void cmv_motcomp(unsigned char *dst, int dst_stride,
>      }
>  }
>  
> -static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const 
> uint8_t *buf_end){
> +static void cmv_decode_inter(CmvContext *s, AVFrame *frame, const uint8_t 
> *buf,
> +                             const uint8_t *buf_end)
> +{
>      const uint8_t *raw = buf + (s->avctx->width*s->avctx->height/16);
>      int x,y,i;
>  
> @@ -88,28 +100,28 @@ static void cmv_decode_inter(CmvContext * s, const 
> uint8_t *buf, const uint8_t *
>      for(y=0; y<s->avctx->height/4; y++)
>      for(x=0; x<s->avctx->width/4 && buf_end - buf > i; x++) {
>          if (buf[i]==0xFF) {
> -            unsigned char *dst = s->frame.data[0] + 
> (y*4)*s->frame.linesize[0] + x*4;
> +            unsigned char *dst = frame->data[0] + (y*4)*frame->linesize[0] + 
> x*4;
>              if (raw+16<buf_end && *raw==0xFF) { /* intra */
>                  raw++;
>                  memcpy(dst, raw, 4);
> -                memcpy(dst+s->frame.linesize[0], raw+4, 4);
> -                memcpy(dst+2*s->frame.linesize[0], raw+8, 4);
> -                memcpy(dst+3*s->frame.linesize[0], raw+12, 4);
> +                memcpy(dst +     frame->linesize[0], raw+4, 4);
> +                memcpy(dst + 2 * frame->linesize[0], raw+8, 4);
> +                memcpy(dst + 3 * frame->linesize[0], raw+12, 4);
>                  raw+=16;
>              }else if(raw<buf_end) {  /* inter using second-last frame as 
> reference */
>                  int xoffset = (*raw & 0xF) - 7;
>                  int yoffset = ((*raw >> 4)) - 7;
> -                if (s->last2_frame.data[0])
> -                    cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
> -                                s->last2_frame.data[0], 
> s->last2_frame.linesize[0],
> +                if (s->last2_frame->data[0])
> +                    cmv_motcomp(frame->data[0], frame->linesize[0],
> +                                s->last2_frame->data[0], 
> s->last2_frame->linesize[0],
>                                  x*4, y*4, xoffset, yoffset, s->avctx->width, 
> s->avctx->height);
>                  raw++;
>              }
>          }else{  /* inter using last frame as reference */
>              int xoffset = (buf[i] & 0xF) - 7;
>              int yoffset = ((buf[i] >> 4)) - 7;
> -            cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
> -                      s->last_frame.data[0], s->last_frame.linesize[0],
> +            cmv_motcomp(frame->data[0], frame->linesize[0],
> +                      s->last_frame->data[0], s->last_frame->linesize[0],
>                        x*4, y*4, xoffset, yoffset, s->avctx->width, 
> s->avctx->height);
>          }
>          i++;
> @@ -154,6 +166,8 @@ static int cmv_decode_frame(AVCodecContext *avctx,
>      int buf_size = avpkt->size;
>      CmvContext *s = avctx->priv_data;
>      const uint8_t *buf_end = buf + buf_size;
> +    AVFrame *frame = data;
> +    int ret;
>  
>      if (buf_end - buf < EA_PREAMBLE_SIZE)
>          return AVERROR_INVALIDDATA;
> @@ -166,46 +180,39 @@ static int cmv_decode_frame(AVCodecContext *avctx,
>      if (av_image_check_size(s->width, s->height, 0, s->avctx))
>          return -1;
>  
> -    /* shuffle */
> -    if (s->last2_frame.data[0])
> -        avctx->release_buffer(avctx, &s->last2_frame);
> -    FFSWAP(AVFrame, s->last_frame, s->last2_frame);
> -    FFSWAP(AVFrame, s->frame, s->last_frame);
> -
> -    s->frame.reference = 1;
> -    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
> -    if (ff_get_buffer(avctx, &s->frame)<0) {
> +    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
>          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
> -        return -1;
> +        return ret;
>      }
>  
> -    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
> +    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
>  
>      buf += EA_PREAMBLE_SIZE;
>      if ((buf[0]&1)) {  // subtype
> -        cmv_decode_inter(s, buf+2, buf_end);
> -        s->frame.key_frame = 0;
> -        s->frame.pict_type = AV_PICTURE_TYPE_P;
> +        cmv_decode_inter(s, frame, buf+2, buf_end);
> +        frame->key_frame = 0;
> +        frame->pict_type = AV_PICTURE_TYPE_P;
>      }else{
> -        s->frame.key_frame = 1;
> -        s->frame.pict_type = AV_PICTURE_TYPE_I;
> -        cmv_decode_intra(s, buf+2, buf_end);
> +        frame->key_frame = 1;
> +        frame->pict_type = AV_PICTURE_TYPE_I;
> +        cmv_decode_intra(s, frame, buf+2, buf_end);
>      }
>  
> +    FFSWAP(AVFrame*, s->last2_frame, s->last_frame);
> +    av_frame_unref(s->last_frame);

  av_frame_unref(s->last2_frame);
  *s->last2_frame = *s->last_frame;

would be less confusing and simpler

> +    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
> +        return ret;
> +
>      *got_frame = 1;
> -    *(AVFrame*)data = s->frame;
>  
>      return buf_size;
>  }
>  
>  static av_cold int cmv_decode_end(AVCodecContext *avctx){
>      CmvContext *s = avctx->priv_data;
> -    if (s->frame.data[0])
> -        s->avctx->release_buffer(avctx, &s->frame);
> -    if (s->last_frame.data[0])
> -        s->avctx->release_buffer(avctx, &s->last_frame);
> -    if (s->last2_frame.data[0])
> -        s->avctx->release_buffer(avctx, &s->last2_frame);
> +
> +    av_frame_free(&s->last_frame);
> +    av_frame_free(&s->last2_frame);
>  
>      return 0;
>  }

otherwise ok

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

Reply via email to