Merge commit 'df9b9567518f2840d79a4a96b447ebe1aa326408'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 5 Dec 2012 16:15:57 +0000 (17:15 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 5 Dec 2012 16:20:19 +0000 (17:20 +0100)
* commit 'df9b9567518f2840d79a4a96b447ebe1aa326408':
  lavc: fix decode_frame() third parameter semantics for video decoders

Conflicts:
libavcodec/cscd.c
libavcodec/eamad.c
libavcodec/ffv1dec.c
libavcodec/gifdec.c
libavcodec/h264.c
libavcodec/iff.c
libavcodec/mjpegdec.c
libavcodec/pcx.c
libavcodec/vp56.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
131 files changed:
1  2 
libavcodec/4xm.c
libavcodec/8bps.c
libavcodec/aasc.c
libavcodec/anm.c
libavcodec/ansi.c
libavcodec/asvdec.c
libavcodec/aura.c
libavcodec/avs.c
libavcodec/bethsoftvideo.c
libavcodec/bfi.c
libavcodec/bink.c
libavcodec/bmp.c
libavcodec/bmv.c
libavcodec/c93.c
libavcodec/cavsdec.c
libavcodec/cdgraphics.c
libavcodec/cdxl.c
libavcodec/cinepak.c
libavcodec/cljr.c
libavcodec/cscd.c
libavcodec/cyuv.c
libavcodec/dfa.c
libavcodec/dnxhddec.c
libavcodec/dpx.c
libavcodec/dsicinav.c
libavcodec/dvdec.c
libavcodec/dxa.c
libavcodec/eacmv.c
libavcodec/eamad.c
libavcodec/eatgq.c
libavcodec/eatgv.c
libavcodec/eatqi.c
libavcodec/escape124.c
libavcodec/ffv1dec.c
libavcodec/flashsv.c
libavcodec/flicvideo.c
libavcodec/fraps.c
libavcodec/frwu.c
libavcodec/gifdec.c
libavcodec/h261dec.c
libavcodec/h263.h
libavcodec/h263dec.c
libavcodec/h264.c
libavcodec/huffyuv.c
libavcodec/idcinvideo.c
libavcodec/iff.c
libavcodec/indeo2.c
libavcodec/indeo3.c
libavcodec/interplayvideo.c
libavcodec/ivi_common.c
libavcodec/ivi_common.h
libavcodec/jvdec.c
libavcodec/kgv1dec.c
libavcodec/kmvc.c
libavcodec/lagarith.c
libavcodec/lcldec.c
libavcodec/libopenjpegdec.c
libavcodec/libschroedingerdec.c
libavcodec/libvpxdec.c
libavcodec/loco.c
libavcodec/mdec.c
libavcodec/mimic.c
libavcodec/mjpegbdec.c
libavcodec/mjpegdec.c
libavcodec/mjpegdec.h
libavcodec/mmvideo.c
libavcodec/motionpixels.c
libavcodec/msrle.c
libavcodec/mss1.c
libavcodec/mss2.c
libavcodec/mss3.c
libavcodec/mss4.c
libavcodec/msvideo1.c
libavcodec/mxpegdec.c
libavcodec/nuv.c
libavcodec/pcx.c
libavcodec/pictordec.c
libavcodec/pngdec.c
libavcodec/pnmdec.c
libavcodec/proresdec_lgpl.c
libavcodec/ptx.c
libavcodec/qdrw.c
libavcodec/qpeg.c
libavcodec/qtrle.c
libavcodec/r210dec.c
libavcodec/rawdec.c
libavcodec/rl2.c
libavcodec/roqvideodec.c
libavcodec/rpza.c
libavcodec/rv10.c
libavcodec/rv34.h
libavcodec/sgidec.c
libavcodec/smacker.c
libavcodec/smc.c
libavcodec/snowdec.c
libavcodec/sp5xdec.c
libavcodec/sunrast.c
libavcodec/svq1dec.c
libavcodec/svq3.c
libavcodec/targa.c
libavcodec/tiertexseqv.c
libavcodec/tiff.c
libavcodec/tmv.c
libavcodec/truemotion1.c
libavcodec/truemotion2.c
libavcodec/tscc.c
libavcodec/tscc2.c
libavcodec/txd.c
libavcodec/ulti.c
libavcodec/utvideodec.c
libavcodec/v210dec.c
libavcodec/v210x.c
libavcodec/v410dec.c
libavcodec/vb.c
libavcodec/vble.c
libavcodec/vc1dec.c
libavcodec/vcr1.c
libavcodec/vmdav.c
libavcodec/vmnc.c
libavcodec/vp3.c
libavcodec/vp56.c
libavcodec/vp56.h
libavcodec/vp8.c
libavcodec/vqavideo.c
libavcodec/wnv1.c
libavcodec/xan.c
libavcodec/xl.c
libavcodec/xwddec.c
libavcodec/xxan.c
libavcodec/yop.c
libavcodec/zmbv.c

Simple merge
Simple merge
@@@ -126,16 -84,8 +126,16 @@@ static int aasc_decode_frame(AVCodecCon
          av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
          return -1;
      }
 +        break;
 +    default:
 +        av_log(avctx, AV_LOG_ERROR, "Unknown FourCC: %X\n", avctx->codec_tag);
 +        return -1;
 +    }
 +
 +    if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
 +        memcpy(s->frame.data[1], s->palette, s->palette_size);
  
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data = s->frame;
  
      /* report that the buffer was completely consumed */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1156,11 -1140,9 +1156,11 @@@ static int cavs_decode_frame(AVCodecCon
                  h->got_keyframe = 1;
              }
          case PIC_PB_START_CODE:
-             *data_size = 0;
+             *got_frame = 0;
              if(!h->got_keyframe)
                  break;
 +            if(!h->top_qp)
 +                break;
              init_get_bits(&s->gb, buf_ptr, input_size);
              h->stc = stc;
              if(decode_pic(h))
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -62,7 -62,82 +62,7 @@@ static void add_frame_default(AVFrame *
      }
  }
  
- static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 -#if !HAVE_BIGENDIAN
 -#define copy_frame_16(f, s, l, h) copy_frame_default(f, s, l, l, h)
 -#define copy_frame_32(f, s, l, h) copy_frame_default(f, s, l, l, h)
 -#define add_frame_16(f, s, l, h) add_frame_default(f, s, l, l, h)
 -#define add_frame_32(f, s, l, h) add_frame_default(f, s, l, l, h)
 -#else
 -static void copy_frame_16(AVFrame *f, const uint8_t *src,
 -                          int linelen, int height) {
 -    int i, j;
 -    uint8_t *dst = f->data[0];
 -    dst += (height - 1) * f->linesize[0];
 -    for (i = height; i; i--) {
 -        for (j = linelen / 2; j; j--) {
 -          dst[0] = src[1];
 -          dst[1] = src[0];
 -          src += 2;
 -          dst += 2;
 -        }
 -        dst -= f->linesize[0] + linelen;
 -    }
 -}
 -
 -static void copy_frame_32(AVFrame *f, const uint8_t *src,
 -                          int linelen, int height) {
 -    int i, j;
 -    uint8_t *dst = f->data[0];
 -    dst += (height - 1) * f->linesize[0];
 -    for (i = height; i; i--) {
 -        for (j = linelen / 4; j; j--) {
 -          dst[0] = src[3];
 -          dst[1] = src[2];
 -          dst[2] = src[1];
 -          dst[3] = src[0];
 -          src += 4;
 -          dst += 4;
 -        }
 -        dst -= f->linesize[0] + linelen;
 -    }
 -}
 -
 -static void add_frame_16(AVFrame *f, const uint8_t *src,
 -                         int linelen, int height) {
 -    int i, j;
 -    uint8_t *dst = f->data[0];
 -    dst += (height - 1) * f->linesize[0];
 -    for (i = height; i; i--) {
 -        for (j = linelen / 2; j; j--) {
 -          dst[0] += src[1];
 -          dst[1] += src[0];
 -          src += 2;
 -          dst += 2;
 -        }
 -        dst -= f->linesize[0] + linelen;
 -    }
 -}
 -
 -static void add_frame_32(AVFrame *f, const uint8_t *src,
 -                         int linelen, int height) {
 -    int i, j;
 -    uint8_t *dst = f->data[0];
 -    dst += (height - 1) * f->linesize[0];
 -    for (i = height; i; i--) {
 -        for (j = linelen / 4; j; j--) {
 -          dst[0] += src[3];
 -          dst[1] += src[2];
 -          dst[2] += src[1];
 -          dst[3] += src[0];
 -          src += 4;
 -          dst += 4;
 -        }
 -        dst -= f->linesize[0] + linelen;
 -    }
 -}
 -#endif
 -
+ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt) {
      const uint8_t *buf = avpkt->data;
      int buf_size = avpkt->size;
@@@ -176,9 -162,8 +176,9 @@@ static int cyuv_decode_frame(AVCodecCon
  
          }
      }
 +    }
  
-     *data_size=sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data= s->frame;
  
      return buf_size;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -360,9 -349,17 +360,9 @@@ static int dvvideo_decode_frame(AVCodec
      emms_c();
  
      /* return image */
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data = s->picture;
  
 -    /* Determine the codec's sample_aspect ratio from the packet */
 -    vsc_pack = buf + 80*5 + 48 + 5;
 -    if ( *vsc_pack == dv_video_control ) {
 -        apt = buf[4] & 0x07;
 -        is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07)));
 -        avctx->sample_aspect_ratio = s->sys->sar[is16_9];
 -    }
 -
      return s->sys->frame_size;
  }
  
Simple merge
Simple merge
@@@ -238,10 -230,10 +238,10 @@@ static int decode_frame(AVCodecContext 
      int chunk_type;
      int inter;
  
 -    if (buf_size < 17) {
 +    if (buf_size < 26) {
          av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
-         *data_size = 0;
+         *got_frame = 0;
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
  
      chunk_type = AV_RL32(&buf[0]);
  
      for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
          for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
 -            decode_mb(s, inter);
 +            if(decode_mb(s, inter) < 0)
 +                return AVERROR_INVALIDDATA;
  
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data = s->frame;
  
      if (chunk_type != MADe_TAG)
@@@ -231,10 -225,9 +231,10 @@@ static int tgq_decode_frame(AVCodecCont
  
      for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
          for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
 -            tgq_decode_mb(s, y, x);
 +            if (tgq_decode_mb(s, y, x) < 0)
 +                return AVERROR_INVALIDDATA;
  
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data = s->frame;
  
      return avpkt->size;
Simple merge
@@@ -134,12 -134,11 +134,12 @@@ static int tqi_decode_frame(AVCodecCont
      for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++)
      {
          if (tqi_decode_mb(s, t->block) < 0)
 -            break;
 +            goto end;
          tqi_idct_put(t, t->block);
      }
 +    end:
  
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data = t->frame;
      return buf_size;
  }
Simple merge
@@@ -727,7 -793,8 +727,7 @@@ static av_cold int decode_init(AVCodecC
      return 0;
  }
  
- static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
 -static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
 -                             int *got_frame, AVPacket *avpkt)
++static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
  {
      const uint8_t *buf  = avpkt->data;
      int buf_size        = avpkt->size;
Simple merge
Simple merge
@@@ -153,57 -149,12 +153,57 @@@ static int decode_frame(AVCodecContext 
          av_log(avctx, AV_LOG_ERROR,
                 "This file is encoded with Fraps version %d. " \
                 "This codec can only decode versions <= 5.\n", version);
 -        return -1;
 +        return AVERROR_PATCHWELCOME;
 +    }
 +
 +    buf += header_size;
 +
 +    if (version < 2) {
 +        unsigned needed_size = avctx->width*avctx->height*3;
 +        if (version == 0) needed_size /= 2;
 +        needed_size += header_size;
 +        /* bit 31 means same as previous pic */
 +        if (header & (1U<<31)) {
-             *data_size = 0;
++            *got_frame = 0;
 +            return buf_size;
 +        }
 +        if (buf_size != needed_size) {
 +            av_log(avctx, AV_LOG_ERROR,
 +                   "Invalid frame length %d (should be %d)\n",
 +                   buf_size, needed_size);
 +            return AVERROR_INVALIDDATA;
 +        }
 +    } else {
 +        /* skip frame */
 +        if (buf_size == 8) {
-             *data_size = 0;
++            *got_frame = 0;
 +            return buf_size;
 +        }
 +        if (AV_RL32(buf) != FPS_TAG || buf_size < planes*1024 + 24) {
 +            av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        for(i = 0; i < planes; i++) {
 +            offs[i] = AV_RL32(buf + 4 + i * 4);
 +            if(offs[i] >= buf_size - header_size || (i && offs[i] <= offs[i - 1] + 1024)) {
 +                av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i);
 +                return AVERROR_INVALIDDATA;
 +            }
 +        }
 +        offs[planes] = buf_size - header_size;
 +        for(i = 0; i < planes; i++) {
 +            av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, offs[i + 1] - offs[i] - 1024);
 +            if (!s->tmpbuf)
 +                return AVERROR(ENOMEM);
 +        }
      }
  
 -    buf+=4;
 -    if (header_size == 8)
 -        buf+=4;
 +    if (f->data[0])
 +        ff_thread_release_buffer(avctx, f);
 +    f->pict_type = AV_PICTURE_TYPE_I;
 +    f->key_frame = 1;
 +    f->reference = 0;
 +    f->buffer_hints = FF_BUFFER_HINTS_VALID;
  
      pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
      if (avctx->pix_fmt != pix_fmt && f->data[0]) {
@@@ -45,10 -39,9 +45,10 @@@ static av_cold int decode_init(AVCodecC
      return 0;
  }
  
- static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt)
  {
 +    FRWUContext *s = avctx->priv_data;
      int field, ret;
      AVFrame *pic = avctx->coded_frame;
      const uint8_t *buf = avpkt->data;
@@@ -412,10 -245,8 +412,10 @@@ static int gif_read_header1(GifState *s
      return 0;
  }
  
 -static int gif_parse_next_image(GifState *s)
 +static int gif_parse_next_image(GifState *s, int *got_picture)
  {
-     *got_picture = sizeof(AVPicture);
 +    int ret;
++    *got_picture = 1;
      while (s->bytestream < s->bytestream_end) {
          int code = bytestream_get_byte(&s->bytestream);
  
@@@ -454,7 -282,8 +454,7 @@@ static av_cold int gif_decode_init(AVCo
      return 0;
  }
  
- static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_picture, AVPacket *avpkt)
 -static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 -                            AVPacket *avpkt)
++static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
  {
      const uint8_t *buf = avpkt->data;
      int buf_size = avpkt->size;
      AVFrame *picture = data;
      int ret;
  
 +    s->picture.pts          = avpkt->pts;
 +    s->picture.pkt_pts      = avpkt->pts;
 +    s->picture.pkt_dts      = avpkt->dts;
 +    s->picture.pkt_duration = avpkt->duration;
 +
      s->bytestream = buf;
      s->bytestream_end = buf + buf_size;
 -    if (gif_read_header1(s) < 0)
 -        return -1;
  
 -    avctx->pix_fmt = AV_PIX_FMT_PAL8;
 -    if (av_image_check_size(s->screen_width, s->screen_height, 0, avctx))
 -        return -1;
 -    avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
 +    if (buf_size >= 6) {
 +        s->keyframe = memcmp(s->bytestream, gif87a_sig, 6) == 0 ||
 +                      memcmp(s->bytestream, gif89a_sig, 6) == 0;
 +    } else {
 +        s->keyframe = 0;
 +    }
  
 -    if (s->picture.data[0])
 -        avctx->release_buffer(avctx, &s->picture);
 -    if (ff_get_buffer(avctx, &s->picture) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 -        return -1;
 +    if (s->keyframe) {
 +        if ((ret = gif_read_header1(s)) < 0)
 +            return ret;
 +
 +        if ((ret = av_image_check_size(s->screen_width, s->screen_height, 0, avctx)) < 0)
 +            return ret;
 +        avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
 +
 +        if (s->picture.data[0])
 +            avctx->release_buffer(avctx, &s->picture);
 +
 +        if ((ret = ff_get_buffer(avctx, &s->picture)) < 0) {
 +            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +            return ret;
 +        }
 +
 +        s->picture.pict_type = AV_PICTURE_TYPE_I;
 +        s->picture.key_frame = 1;
 +    } else {
 +        if ((ret = avctx->reget_buffer(avctx, &s->picture)) < 0) {
 +            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
 +            return ret;
 +        }
 +
 +        s->picture.pict_type = AV_PICTURE_TYPE_P;
 +        s->picture.key_frame = 0;
      }
 -    s->image_palette = (uint32_t *)s->picture.data[1];
 -    ret = gif_parse_next_image(s);
 +
-     ret = gif_parse_next_image(s, got_picture);
++    ret = gif_parse_next_image(s, got_frame);
      if (ret < 0)
          return ret;
-     else if (*got_picture)
++    else if (*got_frame)
 +        *picture = s->picture;
  
 -    *picture = s->picture;
 -    *got_frame = 1;
      return s->bytestream - buf;
  }
  
Simple merge
Simple merge
Simple merge
@@@ -4189,10 -4055,11 +4189,10 @@@ not_extra
  
          field_end(h, 0);
  
 -        if (!h->next_output_pic) {
 -            /* Wait for second field. */
 -            *got_frame = 0;
 -        } else {
 +        /* Wait for second field. */
-         *data_size = 0;
++        *got_frame = 0;
 +        if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
-             *data_size = sizeof(AVFrame);
+             *got_frame = 1;
              *pict      = h->next_output_pic->f;
          }
      }
Simple merge
Simple merge
@@@ -484,114 -246,65 +484,114 @@@ static int decode_byterun(uint8_t *dst
      return buf - buf_start;
  }
  
 -static int decode_frame_ilbm(AVCodecContext *avctx,
 -                            void *data, int *got_frame,
 -                            AVPacket *avpkt)
 +/**
 + * Decode DEEP RLE 32-bit buffer
 + * @param[out] dst Destination buffer
 + * @param[in] src Source buffer
 + * @param src_size Source buffer size (bytes)
 + * @param width Width of destination buffer (pixels)
 + * @param height Height of destination buffer (pixels)
 + * @param linesize Line size of destination buffer (bytes)
 + */
 +static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
  {
 -    IffContext *s = avctx->priv_data;
 -    const uint8_t *buf = avpkt->data;
 -    int buf_size = avpkt->size;
 -    const uint8_t *buf_end = buf+buf_size;
 -    int y, plane, res;
 -
 -    if (s->init) {
 -        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
 -            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
 -            return res;
 -        }
 -    } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 -        return res;
 -    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
 -        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
 -            return res;
 -    }
 -    s->init = 1;
 -
 -    if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
 -        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 -            for(y = 0; y < avctx->height; y++ ) {
 -                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 -                memset(row, 0, avctx->width);
 -                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
 -                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
 -                    buf += s->planesize;
 +    const uint8_t *src_end = src + src_size;
 +    int x = 0, y = 0, i;
 +    while (src + 5 <= src_end) {
 +        int opcode;
 +        opcode = *(int8_t *)src++;
 +        if (opcode >= 0) {
 +            int size = opcode + 1;
 +            for (i = 0; i < size; i++) {
 +                int length = FFMIN(size - i, width);
 +                memcpy(dst + y*linesize + x * 4, src, length * 4);
 +                src += length * 4;
 +                x += length;
 +                i += length;
 +                if (x >= width) {
 +                    x = 0;
 +                    y += 1;
 +                    if (y >= height)
 +                        return;
                  }
              }
 -        } else { // AV_PIX_FMT_BGR32
 -            for(y = 0; y < avctx->height; y++ ) {
 -                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 -                memset(row, 0, avctx->width << 2);
 -                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
 -                    decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
 -                    buf += s->planesize;
 +        } else {
 +            int size = -opcode + 1;
 +            uint32_t pixel = AV_RL32(src);
 +            for (i = 0; i < size; i++) {
 +                *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
 +                x += 1;
 +                if (x >= width) {
 +                    x = 0;
 +                    y += 1;
 +                    if (y >= height)
 +                        return;
                  }
              }
 +            src += 4;
 +        }
 +    }
 +}
 +
 +/**
 + * Decode DEEP TVDC 32-bit buffer
 + * @param[out] dst Destination buffer
 + * @param[in] src Source buffer
 + * @param src_size Source buffer size (bytes)
 + * @param width Width of destination buffer (pixels)
 + * @param height Height of destination buffer (pixels)
 + * @param linesize Line size of destination buffer (bytes)
 + * @param[int] tvdc TVDC lookup table
 + */
 +static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
 +{
 +    int x = 0, y = 0, plane = 0;
 +    int8_t pixel = 0;
 +    int i, j;
 +
 +    for (i = 0; i < src_size * 2;) {
 +#define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
 +        int d = tvdc[GETNIBBLE];
 +        i++;
 +        if (d) {
 +            pixel += d;
 +            dst[y * linesize + x*4 + plane] = pixel;
 +            x++;
 +        } else {
 +            if (i >= src_size * 2)
 +                return;
 +            d = GETNIBBLE + 1;
 +            i++;
 +            d = FFMIN(d, width - x);
 +            for (j = 0; j < d; j++) {
 +                dst[y * linesize + x*4 + plane] = pixel;
 +                x++;
 +            }
          }
 -    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { // IFF-PBM
 -        for(y = 0; y < avctx->height; y++ ) {
 -            uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
 -            memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
 -            buf += avctx->width + (avctx->width % 2); // padding if odd
 +        if (x >= width) {
 +            plane++;
 +            if (plane >= 4) {
 +                y++;
 +                if (y >= height)
 +                    return;
 +                plane = 0;
 +            }
 +            x = 0;
 +            pixel = 0;
 +            i = (i + 1) & ~1;
          }
      }
 +}
  
 -    *got_frame = 1;
 -    *(AVFrame*)data = s->frame;
 -    return buf_size;
 +static int unsupported(AVCodecContext *avctx)
 +{
 +    IffContext *s = avctx->priv_data;
 +    av_log_ask_for_sample(avctx, "unsupported bitmap (compression %i, bpp %i, ham %i)\n", s->compression, s->bpp, s->ham);
 +    return AVERROR_INVALIDDATA;
  }
  
 -static int decode_frame_byterun1(AVCodecContext *avctx,
 +static int decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size,
+                             void *data, int *got_frame,
                              AVPacket *avpkt)
  {
      IffContext *s = avctx->priv_data;
      }
      s->init = 1;
  
 -    if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
 -        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 -            for(y = 0; y < avctx->height ; y++ ) {
 -                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 -                memset(row, 0, avctx->width);
 -                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
 -                    buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
 -                    decodeplane8(row, s->planebuf, s->planesize, plane);
 +    switch (s->compression) {
 +    case 0:
 +        if (avctx->codec_tag == MKTAG('A','C','B','M')) {
 +            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 +                memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
 +                for (plane = 0; plane < s->bpp; plane++) {
 +                    for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
 +                        uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 +                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
 +                        buf += s->planesize;
 +                    }
 +                }
 +            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
 +                memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
 +                for(y = 0; y < avctx->height; y++) {
 +                    uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
 +                    memset(s->ham_buf, 0, s->planesize * 8);
 +                    for (plane = 0; plane < s->bpp; plane++) {
 +                        const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
 +                        if (start >= buf_end)
 +                            break;
 +                        decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
 +                    }
 +                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
 +                }
 +            } else
 +                return unsupported(avctx);
 +        } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
 +            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 +            int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
 +            int x;
 +            for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
 +                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
 +                memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
 +                buf += raw_width;
 +                if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
 +                    for(x = 0; x < avctx->width; x++)
 +                        row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
                  }
              }
 -        } else { //AV_PIX_FMT_BGR32
 -            for(y = 0; y < avctx->height ; y++ ) {
 -                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 -                memset(row, 0, avctx->width << 2);
 -                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
 -                    buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
 -                    decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
 +        } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
 +            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 +                for(y = 0; y < avctx->height; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 +                    memset(row, 0, avctx->width);
 +                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
 +                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
 +                        buf += s->planesize;
 +                    }
 +                }
 +            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
 +                for (y = 0; y < avctx->height; y++) {
 +                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 +                    memset(s->ham_buf, 0, s->planesize * 8);
 +                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
 +                        decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
 +                        buf += s->planesize;
 +                    }
 +                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
 +                }
 +            } else { // AV_PIX_FMT_BGR32
 +                for(y = 0; y < avctx->height; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 +                    memset(row, 0, avctx->width << 2);
 +                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
 +                        decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
 +                        buf += s->planesize;
 +                    }
                  }
              }
 +        } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
 +            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 +                for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
 +                    memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
 +                    buf += avctx->width + (avctx->width % 2); // padding if odd
 +                }
 +            } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
 +                for (y = 0; y < avctx->height && buf_end > buf; y++) {
 +                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 +                    memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
 +                    buf += avctx->width + (avctx->width & 1); // padding if odd
 +                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
 +                }
 +            } else
 +                return unsupported(avctx);
          }
 -    } else {
 -        for(y = 0; y < avctx->height ; y++ ) {
 -            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 -            buf += decode_byterun(row, avctx->width, buf, buf_end);
 +        break;
 +    case 1:
 +        if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
 +            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 +                for(y = 0; y < avctx->height ; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
 +                    memset(row, 0, avctx->width);
 +                    for (plane = 0; plane < s->bpp; plane++) {
 +                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
 +                        decodeplane8(row, s->planebuf, s->planesize, plane);
 +                    }
 +                }
 +            } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
 +                for (y = 0; y < avctx->height ; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 +                    memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
 +                    for (plane = 0; plane < s->bpp; plane++) {
 +                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
 +                        decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
 +                    }
 +                    lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
 +                }
 +            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
 +                for (y = 0; y < avctx->height ; y++) {
 +                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 +                    memset(s->ham_buf, 0, s->planesize * 8);
 +                    for (plane = 0; plane < s->bpp; plane++) {
 +                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
 +                        decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
 +                    }
 +                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
 +                }
 +            } else { //AV_PIX_FMT_BGR32
 +                for(y = 0; y < avctx->height ; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 +                    memset(row, 0, avctx->width << 2);
 +                    for (plane = 0; plane < s->bpp; plane++) {
 +                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
 +                        decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
 +                    }
 +                }
 +            }
 +        } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
 +            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
 +                for(y = 0; y < avctx->height ; y++ ) {
 +                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 +                    buf += decode_byterun(row, avctx->width, buf, buf_end);
 +                }
 +            } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
 +                for (y = 0; y < avctx->height ; y++) {
 +                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
 +                    buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
 +                    decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
 +                }
 +            } else
 +                return unsupported(avctx);
 +        } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
 +            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 +            if (av_get_bits_per_pixel(desc) == 32)
 +                decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
 +            else
 +                return unsupported(avctx);
          }
 +        break;
 +    case 5:
 +        if (avctx->codec_tag == MKTAG('D','E','E','P')) {
 +            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 +            if (av_get_bits_per_pixel(desc) == 32)
 +                decode_deep_tvdc32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0], s->tvdc);
 +            else
 +                return unsupported(avctx);
 +        } else
 +            return unsupported(avctx);
 +        break;
 +    default:
 +        return unsupported(avctx);
      }
  
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
      *(AVFrame*)data = s->frame;
      return buf_size;
  }
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -507,10 -497,10 +507,10 @@@ static int lag_decode_arith_plane(Lagar
   * @return number of consumed bytes on success or negative if decode fails
   */
  static int lag_decode_frame(AVCodecContext *avctx,
-                             void *data, int *data_size, AVPacket *avpkt)
+                             void *data, int *got_frame, AVPacket *avpkt)
  {
      const uint8_t *buf = avpkt->data;
 -    int buf_size = avpkt->size;
 +    unsigned int buf_size = avpkt->size;
      LagarithContext *l = avctx->priv_data;
      AVFrame *const p = &l->picture;
      uint8_t frametype = 0;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -229,12 -222,11 +229,12 @@@ static int decode_frame(AVCodecContext 
                                      p->linesize[0], buf, buf_size, 4);
          break;
      }
 +stop:
  
-     *data_size = sizeof(AVFrame);
+     *got_frame      = 1;
      *(AVFrame*)data = l->pic;
  
 -    return buf_size;
 +    return buf_size < 0 ? -1 : avpkt->size - buf_size;
  }
  
  static av_cold int decode_init(AVCodecContext *avctx){
Simple merge
Simple merge
@@@ -136,13 -136,8 +136,13 @@@ read_header
  
      //XXX FIXME factorize, this looks very similar to the EOI code
  
 +    if(!s->got_picture) {
 +        av_log(avctx, AV_LOG_WARNING, "no picture\n");
 +        return buf_size;
 +    }
 +
      *picture= *s->picture_ptr;
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
  
      if(!s->lossless){
          picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);
@@@ -1709,11 -1548,10 +1709,11 @@@ eoi_parser
                      s->bottom_field ^= 1;
                      /* if not bottom field, do not output image yet */
                      if (s->bottom_field == !s->interlace_polarity)
 -                        goto not_the_end;
 -                    }
 +                        break;
 +                }
                      *picture   = *s->picture_ptr;
-                     *data_size = sizeof(AVFrame);
+                     *got_frame = 1;
 +                    s->got_picture = 0;
  
                      if (!s->lossless) {
                          picture->quality      = FFMAX3(s->qscale[0],
Simple merge
@@@ -210,10 -209,10 +210,10 @@@ static int mm_decode_frame(AVCodecConte
  
      memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
  
-     *data_size = sizeof(AVFrame);
+     *got_frame      = 1;
      *(AVFrame*)data = s->frame;
  
 -    return buf_size;
 +    return avpkt->size;
  }
  
  static av_cold int mm_decode_end(AVCodecContext *avctx)
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -140,10 -135,10 +140,10 @@@ static int codec_reinit(AVCodecContext 
          ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
                                c->lq, c->cq);
  
 -    return 1;
 +    return 0;
  }
  
- static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt)
  {
      const uint8_t *buf = avpkt->data;
@@@ -75,9 -77,10 +75,9 @@@ static void pcx_palette(GetByteContext 
          memset(dst, 0, (256 - pallen) * sizeof(*dst));
  }
  
- static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 -                            AVPacket *avpkt) {
 -    const uint8_t *buf = avpkt->data;
 -    int buf_size = avpkt->size;
 +                            AVPacket *avpkt)
 +{
      PCXContext * const s = avctx->priv_data;
      AVFrame *picture = data;
      AVFrame * const p = &s->picture;
      }
  
      *picture = s->picture;
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
  
 -    ret = buf - bufstart;
  end:
      av_free(scanline);
      return ret;
@@@ -97,16 -97,8 +97,16 @@@ static const uint8_t cga_mode45_index[6
      [5] = { 0, 11, 12, 15 }, // mode5, high intensity
  };
  
 +static av_cold int decode_init(AVCodecContext *avctx)
 +{
 +    PicContext *s = avctx->priv_data;
 +
 +    avcodec_get_frame_defaults(&s->frame);
 +    return 0;
 +}
 +
  static int decode_frame(AVCodecContext *avctx,
-                         void *data, int *data_size,
+                         void *data, int *got_frame,
                          AVPacket *avpkt)
  {
      PicContext *s = avctx->priv_data;
                  }
              }
          }
 +
 +        if (x < avctx->width && y >= 0) {
 +            int run = (y + 1) * avctx->width - x;
 +            if (bits_per_plane == 8)
 +                picmemset_8bpp(s, val, run, &x, &y);
 +            else
 +                picmemset(s, val, run / (8 / bits_per_plane), &x, &y, &plane, bits_per_plane);
 +        }
      } else {
 -        av_log_ask_for_sample(s, "uncompressed image\n");
 -        return avpkt->size;
 +        while (y >= 0 && bytestream2_get_bytes_left(&s->g) > 0) {
 +            memcpy(s->frame.data[0] + y * s->frame.linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g)));
 +            bytestream2_skip(&s->g, avctx->width);
 +            y--;
 +        }
      }
  
-     *data_size = sizeof(AVFrame);
+     *got_frame      = 1;
      *(AVFrame*)data = s->frame;
      return avpkt->size;
  }
@@@ -388,124 -382,8 +388,124 @@@ static int png_decode_idat(PNGDecContex
      return 0;
  }
  
 +static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
 +                       const uint8_t *data_end)
 +{
 +    z_stream zstream;
 +    unsigned char *buf;
 +    unsigned buf_size;
 +    int ret;
 +
 +    zstream.zalloc = ff_png_zalloc;
 +    zstream.zfree  = ff_png_zfree;
 +    zstream.opaque = NULL;
 +    if (inflateInit(&zstream) != Z_OK)
 +        return AVERROR_EXTERNAL;
 +    zstream.next_in  = (unsigned char *)data;
 +    zstream.avail_in = data_end - data;
 +    av_bprint_init(bp, 0, -1);
 +
 +    while (zstream.avail_in > 0) {
 +        av_bprint_get_buffer(bp, 1, &buf, &buf_size);
 +        if (!buf_size) {
 +            ret = AVERROR(ENOMEM);
 +            goto fail;
 +        }
 +        zstream.next_out  = buf;
 +        zstream.avail_out = buf_size;
 +        ret = inflate(&zstream, Z_PARTIAL_FLUSH);
 +        if (ret != Z_OK && ret != Z_STREAM_END) {
 +            ret = AVERROR_EXTERNAL;
 +            goto fail;
 +        }
 +        bp->len += zstream.next_out - buf;
 +        if (ret == Z_STREAM_END)
 +            break;
 +    }
 +    inflateEnd(&zstream);
 +    bp->str[bp->len] = 0;
 +    return 0;
 +
 +fail:
 +    inflateEnd(&zstream);
 +    av_bprint_finalize(bp, NULL);
 +    return ret;
 +}
 +
 +static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in)
 +{
 +    size_t extra = 0, i;
 +    uint8_t *out, *q;
 +
 +    for (i = 0; i < size_in; i++)
 +        extra += in[i] >= 0x80;
 +    if (size_in == SIZE_MAX || extra > SIZE_MAX - size_in - 1)
 +        return NULL;
 +    q = out = av_malloc(size_in + extra + 1);
 +    if (!out)
 +        return NULL;
 +    for (i = 0; i < size_in; i++) {
 +        if (in[i] >= 0x80) {
 +            *(q++) = 0xC0 | (in[i] >> 6);
 +            *(q++) = 0x80 | (in[i] & 0x3F);
 +        } else {
 +            *(q++) = in[i];
 +        }
 +    }
 +    *(q++) = 0;
 +    return out;
 +}
 +
 +static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
 +                             AVDictionary **dict)
 +{
 +    int ret, method;
 +    const uint8_t *data        = s->gb.buffer;
 +    const uint8_t *data_end    = data + length;
 +    const uint8_t *keyword     = data;
 +    const uint8_t *keyword_end = memchr(keyword, 0, data_end - keyword);
 +    uint8_t *kw_utf8 = NULL, *text, *txt_utf8 = NULL;
 +    unsigned text_len;
 +    AVBPrint bp;
 +
 +    if (!keyword_end)
 +        return AVERROR_INVALIDDATA;
 +    data = keyword_end + 1;
 +
 +    if (compressed) {
 +        if (data == data_end)
 +            return AVERROR_INVALIDDATA;
 +        method = *(data++);
 +        if (method)
 +            return AVERROR_INVALIDDATA;
 +        if ((ret = decode_zbuf(&bp, data, data_end)) < 0)
 +            return ret;
 +        text_len = bp.len;
 +        av_bprint_finalize(&bp, (char **)&text);
 +        if (!text)
 +            return AVERROR(ENOMEM);
 +    } else {
 +        text = (uint8_t *)data;
 +        text_len = data_end - text;
 +    }
 +
 +    kw_utf8  = iso88591_to_utf8(keyword, keyword_end - keyword);
 +    txt_utf8 = iso88591_to_utf8(text, text_len);
 +    if (text != data)
 +        av_free(text);
 +    if (!(kw_utf8 && txt_utf8)) {
 +        av_free(kw_utf8);
 +        av_free(txt_utf8);
 +        return AVERROR(ENOMEM);
 +    }
 +
 +    av_dict_set(dict, kw_utf8, txt_utf8,
 +                AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
 +    return 0;
 +}
 +
  static int decode_frame(AVCodecContext *avctx,
-                         void *data, int *data_size,
+                         void *data, int *got_frame,
                          AVPacket *avpkt)
  {
      const uint8_t *buf = avpkt->data;
          }
      }
  
 +    s->current_picture->metadata = metadata;
 +    metadata = NULL;
      *picture= *s->current_picture;
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
  
      ret = bytestream2_tell(&s->gb);
   the_end:
@@@ -184,9 -162,27 +184,9 @@@ static int pnm_decode_frame(AVCodecCont
              }
          }
          break;
 -    case AV_PIX_FMT_RGB32:
 -        ptr      = p->data[0];
 -        linesize = p->linesize[0];
 -        if (s->bytestream + avctx->width * avctx->height * 4 > s->bytestream_end)
 -            return -1;
 -        for (i = 0; i < avctx->height; i++) {
 -            int j, r, g, b, a;
 -
 -            for (j = 0; j < avctx->width; j++) {
 -                r = *s->bytestream++;
 -                g = *s->bytestream++;
 -                b = *s->bytestream++;
 -                a = *s->bytestream++;
 -                ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b;
 -            }
 -            ptr += linesize;
 -        }
 -        break;
      }
      *picture   = s->picture;
-     *data_size = sizeof(AVPicture);
+     *got_frame = 1;
  
      return s->bytestream - s->bytestream_start;
  }
index ce23969,0000000..4fa2817
mode 100644,000000..100644
--- /dev/null
@@@ -1,674 -1,0 +1,674 @@@
- static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 +/*
 + * Apple ProRes compatible decoder
 + *
 + * Copyright (c) 2010-2011 Maxim Poliakovski
 + *
 + * This file is part of Libav.
 + *
 + * Libav is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * Libav is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with Libav; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +/**
 + * @file
 + * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444.
 + * It is used for storing and editing high definition video data in Apple's Final Cut Pro.
 + *
 + * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
 + */
 +
 +#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
 +
 +#include <stdint.h>
 +
 +#include "libavutil/intmath.h"
 +#include "avcodec.h"
 +#include "internal.h"
 +#include "proresdata.h"
 +#include "proresdsp.h"
 +#include "get_bits.h"
 +
 +typedef struct {
 +    const uint8_t *index;            ///< pointers to the data of this slice
 +    int slice_num;
 +    int x_pos, y_pos;
 +    int slice_width;
 +    int prev_slice_sf;               ///< scalefactor of the previous decoded slice
 +    DECLARE_ALIGNED(16, DCTELEM, blocks)[8 * 4 * 64];
 +    DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
 +    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
 +} ProresThreadData;
 +
 +typedef struct {
 +    ProresDSPContext dsp;
 +    AVFrame    picture;
 +    ScanTable  scantable;
 +    int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
 +
 +    int        frame_type;               ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first
 +    int        pic_format;               ///< 2 = 422, 3 = 444
 +    uint8_t    qmat_luma[64];            ///< dequantization matrix for luma
 +    uint8_t    qmat_chroma[64];          ///< dequantization matrix for chroma
 +    int        qmat_changed;             ///< 1 - global quantization matrices changed
 +    int        total_slices;            ///< total number of slices in a picture
 +    ProresThreadData *slice_data;
 +    int        pic_num;
 +    int        chroma_factor;
 +    int        mb_chroma_factor;
 +    int        num_chroma_blocks;       ///< number of chrominance blocks in a macroblock
 +    int        num_x_slices;
 +    int        num_y_slices;
 +    int        slice_width_factor;
 +    int        slice_height_factor;
 +    int        num_x_mbs;
 +    int        num_y_mbs;
 +    int        alpha_info;
 +} ProresContext;
 +
 +
 +static av_cold int decode_init(AVCodecContext *avctx)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +
 +    ctx->total_slices     = 0;
 +    ctx->slice_data       = NULL;
 +
 +    avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
 +    ff_proresdsp_init(&ctx->dsp, avctx);
 +
 +    avctx->coded_frame = &ctx->picture;
 +    avcodec_get_frame_defaults(&ctx->picture);
 +    ctx->picture.type      = AV_PICTURE_TYPE_I;
 +    ctx->picture.key_frame = 1;
 +
 +    ctx->scantable_type = -1;   // set scantable type to uninitialized
 +    memset(ctx->qmat_luma, 4, 64);
 +    memset(ctx->qmat_chroma, 4, 64);
 +
 +    return 0;
 +}
 +
 +
 +static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
 +                               const int data_size, AVCodecContext *avctx)
 +{
 +    int hdr_size, version, width, height, flags;
 +    const uint8_t *ptr;
 +
 +    hdr_size = AV_RB16(buf);
 +    if (hdr_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    version = AV_RB16(buf + 2);
 +    if (version >= 2) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported header version: %d\n", version);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    width  = AV_RB16(buf + 8);
 +    height = AV_RB16(buf + 10);
 +    if (width != avctx->width || height != avctx->height) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "picture dimension changed: old: %d x %d, new: %d x %d\n",
 +               avctx->width, avctx->height, width, height);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->frame_type = (buf[12] >> 2) & 3;
 +    if (ctx->frame_type > 2) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported frame type: %d\n", ctx->frame_type);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->chroma_factor     = (buf[12] >> 6) & 3;
 +    ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
 +    ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
 +    switch (ctx->chroma_factor) {
 +    case 2:
 +        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
 +        break;
 +    case 3:
 +        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
 +        break;
 +    default:
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported picture format: %d\n", ctx->pic_format);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    if (ctx->scantable_type != ctx->frame_type) {
 +        if (!ctx->frame_type)
 +            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
 +                              ff_prores_progressive_scan);
 +        else
 +            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
 +                              ff_prores_interlaced_scan);
 +        ctx->scantable_type = ctx->frame_type;
 +    }
 +
 +    if (ctx->frame_type) {      /* if interlaced */
 +        ctx->picture.interlaced_frame = 1;
 +        ctx->picture.top_field_first  = ctx->frame_type & 1;
 +    }
 +
 +    avctx->color_primaries = buf[14];
 +    avctx->color_trc       = buf[15];
 +    avctx->colorspace      = buf[16];
 +
 +    ctx->alpha_info = buf[17] & 0xf;
 +    if (ctx->alpha_info)
 +        av_log_missing_feature(avctx, "Alpha channel", 0);
 +
 +    ctx->qmat_changed = 0;
 +    ptr   = buf + 20;
 +    flags = buf[19];
 +    if (flags & 2) {
 +        if (ptr - buf > hdr_size - 64) {
 +            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        if (memcmp(ctx->qmat_luma, ptr, 64)) {
 +            memcpy(ctx->qmat_luma, ptr, 64);
 +            ctx->qmat_changed = 1;
 +        }
 +        ptr += 64;
 +    } else {
 +        memset(ctx->qmat_luma, 4, 64);
 +        ctx->qmat_changed = 1;
 +    }
 +
 +    if (flags & 1) {
 +        if (ptr - buf > hdr_size - 64) {
 +            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
 +            return -1;
 +        }
 +        if (memcmp(ctx->qmat_chroma, ptr, 64)) {
 +            memcpy(ctx->qmat_chroma, ptr, 64);
 +            ctx->qmat_changed = 1;
 +        }
 +    } else {
 +        memset(ctx->qmat_chroma, 4, 64);
 +        ctx->qmat_changed = 1;
 +    }
 +
 +    return hdr_size;
 +}
 +
 +
 +static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
 +                                 const int data_size, AVCodecContext *avctx)
 +{
 +    int   i, hdr_size, pic_data_size, num_slices;
 +    int   slice_width_factor, slice_height_factor;
 +    int   remainder, num_x_slices;
 +    const uint8_t *data_ptr, *index_ptr;
 +
 +    hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
 +    if (hdr_size < 8 || hdr_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    pic_data_size = AV_RB32(buf + 1);
 +    if (pic_data_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    slice_width_factor  = buf[7] >> 4;
 +    slice_height_factor = buf[7] & 0xF;
 +    if (slice_width_factor > 3 || slice_height_factor) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported slice dimension: %d x %d\n",
 +               1 << slice_width_factor, 1 << slice_height_factor);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->slice_width_factor  = slice_width_factor;
 +    ctx->slice_height_factor = slice_height_factor;
 +
 +    ctx->num_x_mbs = (avctx->width + 15) >> 4;
 +    ctx->num_y_mbs = (avctx->height +
 +                      (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
 +                     (4 + ctx->picture.interlaced_frame);
 +
 +    remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
 +    num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
 +                   ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
 +
 +    num_slices = num_x_slices * ctx->num_y_mbs;
 +    if (num_slices != AV_RB16(buf + 5)) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    if (ctx->total_slices != num_slices) {
 +        av_freep(&ctx->slice_data);
 +        ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
 +        if (!ctx->slice_data)
 +            return AVERROR(ENOMEM);
 +        ctx->total_slices = num_slices;
 +    }
 +
 +    if (hdr_size + num_slices * 2 > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    /* parse slice table allowing quick access to the slice data */
 +    index_ptr = buf + hdr_size;
 +    data_ptr = index_ptr + num_slices * 2;
 +
 +    for (i = 0; i < num_slices; i++) {
 +        ctx->slice_data[i].index = data_ptr;
 +        ctx->slice_data[i].prev_slice_sf = 0;
 +        data_ptr += AV_RB16(index_ptr + i * 2);
 +    }
 +    ctx->slice_data[i].index = data_ptr;
 +    ctx->slice_data[i].prev_slice_sf = 0;
 +
 +    if (data_ptr > buf + data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
 +        return -1;
 +    }
 +
 +    return pic_data_size;
 +}
 +
 +
 +/**
 + * Read an unsigned rice/exp golomb codeword.
 + */
 +static inline int decode_vlc_codeword(GetBitContext *gb, unsigned codebook)
 +{
 +    unsigned int rice_order, exp_order, switch_bits;
 +    unsigned int buf, code;
 +    int log, prefix_len, len;
 +
 +    OPEN_READER(re, gb);
 +    UPDATE_CACHE(re, gb);
 +    buf = GET_CACHE(re, gb);
 +
 +    /* number of prefix bits to switch between Rice and expGolomb */
 +    switch_bits = (codebook & 3) + 1;
 +    rice_order  = codebook >> 5;        /* rice code order */
 +    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
 +
 +    log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
 +
 +    if (log < switch_bits) { /* ok, we got a rice code */
 +        if (!rice_order) {
 +            /* shortcut for faster decoding of rice codes without remainder */
 +            code = log;
 +            LAST_SKIP_BITS(re, gb, log + 1);
 +        } else {
 +            prefix_len = log + 1;
 +            code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
 +            LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
 +        }
 +    } else { /* otherwise we got a exp golomb code */
 +        len  = (log << 1) - switch_bits + exp_order + 1;
 +        code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
 +        LAST_SKIP_BITS(re, gb, len);
 +    }
 +
 +    CLOSE_READER(re, gb);
 +
 +    return code;
 +}
 +
 +#define LSB2SIGN(x) (-((x) & 1))
 +#define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
 +
 +/**
 + * Decode DC coefficients for all blocks in a slice.
 + */
 +static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
 +                                    int nblocks)
 +{
 +    DCTELEM prev_dc;
 +    int     i, sign;
 +    int16_t delta;
 +    unsigned int code;
 +
 +    code   = decode_vlc_codeword(gb, FIRST_DC_CB);
 +    out[0] = prev_dc = TOSIGNED(code);
 +
 +    out   += 64; /* move to the DC coeff of the next block */
 +    delta  = 3;
 +
 +    for (i = 1; i < nblocks; i++, out += 64) {
 +        code = decode_vlc_codeword(gb, ff_prores_dc_codebook[FFMIN(FFABS(delta), 3)]);
 +
 +        sign     = -(((delta >> 15) & 1) ^ (code & 1));
 +        delta    = (((code + 1) >> 1) ^ sign) - sign;
 +        prev_dc += delta;
 +        out[0]   = prev_dc;
 +    }
 +}
 +
 +
 +/**
 + * Decode AC coefficients for all blocks in a slice.
 + */
 +static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
 +                                    int blocks_per_slice,
 +                                    int plane_size_factor,
 +                                    const uint8_t *scan)
 +{
 +    int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
 +    int max_coeffs, bits_left;
 +
 +    /* set initial prediction values */
 +    run   = 4;
 +    level = 2;
 +
 +    max_coeffs = blocks_per_slice << 6;
 +    block_mask = blocks_per_slice - 1;
 +
 +    for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
 +        run_cb_index = ff_prores_run_to_cb_index[FFMIN(run, 15)];
 +        lev_cb_index = ff_prores_lev_to_cb_index[FFMIN(level, 9)];
 +
 +        bits_left = get_bits_left(gb);
 +        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
 +            return;
 +
 +        run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]);
 +
 +        bits_left = get_bits_left(gb);
 +        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
 +            return;
 +
 +        level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1;
 +
 +        pos += run + 1;
 +        if (pos >= max_coeffs)
 +            break;
 +
 +        sign = get_sbits(gb, 1);
 +        out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
 +            (level ^ sign) - sign;
 +    }
 +}
 +
 +
 +/**
 + * Decode a slice plane (luma or chroma).
 + */
 +static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
 +                               const uint8_t *buf,
 +                               int data_size, uint16_t *out_ptr,
 +                               int linesize, int mbs_per_slice,
 +                               int blocks_per_mb, int plane_size_factor,
 +                               const int16_t *qmat, int is_chroma)
 +{
 +    GetBitContext gb;
 +    DCTELEM *block_ptr;
 +    int mb_num, blocks_per_slice;
 +
 +    blocks_per_slice = mbs_per_slice * blocks_per_mb;
 +
 +    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
 +
 +    init_get_bits(&gb, buf, data_size << 3);
 +
 +    decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
 +
 +    decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
 +                     plane_size_factor, ctx->scantable.permutated);
 +
 +    /* inverse quantization, inverse transform and output */
 +    block_ptr = td->blocks;
 +
 +    if (!is_chroma) {
 +        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
 +            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
 +            block_ptr += 64;
 +            if (blocks_per_mb > 2) {
 +                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
 +                block_ptr += 64;
 +            }
 +            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
 +            block_ptr += 64;
 +            if (blocks_per_mb > 2) {
 +                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
 +                block_ptr += 64;
 +            }
 +        }
 +    } else {
 +        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
 +            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
 +            block_ptr += 64;
 +            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
 +            block_ptr += 64;
 +            if (blocks_per_mb > 2) {
 +                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
 +                block_ptr += 64;
 +                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
 +                block_ptr += 64;
 +            }
 +        }
 +    }
 +}
 +
 +
 +static int decode_slice(AVCodecContext *avctx, void *tdata)
 +{
 +    ProresThreadData *td = tdata;
 +    ProresContext *ctx = avctx->priv_data;
 +    int mb_x_pos  = td->x_pos;
 +    int mb_y_pos  = td->y_pos;
 +    int pic_num   = ctx->pic_num;
 +    int slice_num = td->slice_num;
 +    int mbs_per_slice = td->slice_width;
 +    const uint8_t *buf;
 +    uint8_t *y_data, *u_data, *v_data;
 +    AVFrame *pic = avctx->coded_frame;
 +    int i, sf, slice_width_factor;
 +    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
 +    int y_linesize, u_linesize, v_linesize;
 +
 +    buf             = ctx->slice_data[slice_num].index;
 +    slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
 +
 +    slice_width_factor = av_log2(mbs_per_slice);
 +
 +    y_data     = pic->data[0];
 +    u_data     = pic->data[1];
 +    v_data     = pic->data[2];
 +    y_linesize = pic->linesize[0];
 +    u_linesize = pic->linesize[1];
 +    v_linesize = pic->linesize[2];
 +
 +    if (pic->interlaced_frame) {
 +        if (!(pic_num ^ pic->top_field_first)) {
 +            y_data += y_linesize;
 +            u_data += u_linesize;
 +            v_data += v_linesize;
 +        }
 +        y_linesize <<= 1;
 +        u_linesize <<= 1;
 +        v_linesize <<= 1;
 +    }
 +
 +    if (slice_data_size < 6) {
 +        av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    /* parse slice header */
 +    hdr_size    = buf[0] >> 3;
 +    y_data_size = AV_RB16(buf + 2);
 +    u_data_size = AV_RB16(buf + 4);
 +    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
 +        slice_data_size - y_data_size - u_data_size - hdr_size;
 +
 +    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
 +        v_data_size < 0 || hdr_size < 6) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    sf = av_clip(buf[1], 1, 224);
 +    sf = sf > 128 ? (sf - 96) << 2 : sf;
 +
 +    /* scale quantization matrixes according with slice's scale factor */
 +    /* TODO: this can be SIMD-optimized a lot */
 +    if (ctx->qmat_changed || sf != td->prev_slice_sf) {
 +        td->prev_slice_sf = sf;
 +        for (i = 0; i < 64; i++) {
 +            td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
 +            td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
 +        }
 +    }
 +
 +    /* decode luma plane */
 +    decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
 +                       (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
 +                                    (mb_x_pos << 5)), y_linesize,
 +                       mbs_per_slice, 4, slice_width_factor + 2,
 +                       td->qmat_luma_scaled, 0);
 +
 +    /* decode U chroma plane */
 +    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
 +                       (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
 +                                    (mb_x_pos << ctx->mb_chroma_factor)),
 +                       u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
 +                       slice_width_factor + ctx->chroma_factor - 1,
 +                       td->qmat_chroma_scaled, 1);
 +
 +    /* decode V chroma plane */
 +    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
 +                       v_data_size,
 +                       (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
 +                                    (mb_x_pos << ctx->mb_chroma_factor)),
 +                       v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
 +                       slice_width_factor + ctx->chroma_factor - 1,
 +                       td->qmat_chroma_scaled, 1);
 +
 +    return 0;
 +}
 +
 +
 +static int decode_picture(ProresContext *ctx, int pic_num,
 +                          AVCodecContext *avctx)
 +{
 +    int slice_num, slice_width, x_pos, y_pos;
 +
 +    slice_num = 0;
 +
 +    ctx->pic_num = pic_num;
 +    for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
 +        slice_width = 1 << ctx->slice_width_factor;
 +
 +        for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
 +             x_pos += slice_width) {
 +            while (ctx->num_x_mbs - x_pos < slice_width)
 +                slice_width >>= 1;
 +
 +            ctx->slice_data[slice_num].slice_num   = slice_num;
 +            ctx->slice_data[slice_num].x_pos       = x_pos;
 +            ctx->slice_data[slice_num].y_pos       = y_pos;
 +            ctx->slice_data[slice_num].slice_width = slice_width;
 +
 +            slice_num++;
 +        }
 +    }
 +
 +    return avctx->execute(avctx, decode_slice,
 +                          ctx->slice_data, NULL, slice_num,
 +                          sizeof(ctx->slice_data[0]));
 +}
 +
 +
 +#define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
 +
-     *data_size       = sizeof(AVPicture);
++static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 +                        AVPacket *avpkt)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    AVFrame *picture   = avctx->coded_frame;
 +    const uint8_t *buf = avpkt->data;
 +    int buf_size       = avpkt->size;
 +    int frame_hdr_size, pic_num, pic_data_size;
 +
 +    /* check frame atom container */
 +    if (buf_size < 28 || buf_size < AV_RB32(buf) ||
 +        AV_RB32(buf + 4) != FRAME_ID) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    MOVE_DATA_PTR(8);
 +
 +    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
 +    if (frame_hdr_size < 0)
 +        return AVERROR_INVALIDDATA;
 +
 +    MOVE_DATA_PTR(frame_hdr_size);
 +
 +    if (picture->data[0])
 +        avctx->release_buffer(avctx, picture);
 +
 +    picture->reference = 0;
 +    if (ff_get_buffer(avctx, picture) < 0)
 +        return -1;
 +
 +    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
 +        pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
 +        if (pic_data_size < 0)
 +            return AVERROR_INVALIDDATA;
 +
 +        if (decode_picture(ctx, pic_num, avctx))
 +            return -1;
 +
 +        MOVE_DATA_PTR(pic_data_size);
 +    }
 +
++    *got_frame       = 1;
 +    *(AVFrame*) data = *avctx->coded_frame;
 +
 +    return avpkt->size;
 +}
 +
 +
 +static av_cold int decode_close(AVCodecContext *avctx)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +
 +    if (ctx->picture.data[0])
 +        avctx->release_buffer(avctx, &ctx->picture);
 +
 +    av_freep(&ctx->slice_data);
 +
 +    return 0;
 +}
 +
 +
 +AVCodec ff_prores_lgpl_decoder = {
 +    .name           = "prores_lgpl",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_PRORES,
 +    .priv_data_size = sizeof(ProresContext),
 +    .init           = decode_init,
 +    .close          = decode_close,
 +    .decode         = decode_frame,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
 +    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
 +};
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -256,18 -195,8 +256,18 @@@ static int raw_decode(AVCodecContext *a
              line += picture->linesize[0];
          }
      }
 +    if(avctx->codec_tag == AV_RL32("YVYU") &&
 +       avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
 +        int x, y;
 +        uint8_t *line = picture->data[0];
 +        for(y = 0; y < avctx->height; y++) {
 +            for(x = 0; x < avctx->width - 1; x += 2)
 +                FFSWAP(uint8_t, line[2*x + 1], line[2*x + 3]);
 +            line += picture->linesize[0];
 +        }
 +    }
  
-     *data_size = sizeof(AVPicture);
+     *got_frame = 1;
      return buf_size;
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -196,33 -180,9 +197,33 @@@ static int sunrast_decode_frame(AVCodec
              buf += alen;
          }
      }
 +    if (avctx->pix_fmt == AV_PIX_FMT_PAL8 && depth < 8) {
 +        uint8_t *ptr_free = ptr2;
 +        ptr = p->data[0];
 +        for (y=0; y<h; y++) {
 +            for (x = 0; x < (w + 7 >> 3) * depth; x++) {
 +                if (depth == 1) {
 +                    ptr[8*x]   = ptr2[x] >> 7;
 +                    ptr[8*x+1] = ptr2[x] >> 6 & 1;
 +                    ptr[8*x+2] = ptr2[x] >> 5 & 1;
 +                    ptr[8*x+3] = ptr2[x] >> 4 & 1;
 +                    ptr[8*x+4] = ptr2[x] >> 3 & 1;
 +                    ptr[8*x+5] = ptr2[x] >> 2 & 1;
 +                    ptr[8*x+6] = ptr2[x] >> 1 & 1;
 +                    ptr[8*x+7] = ptr2[x]      & 1;
 +                } else {
 +                    ptr[2*x]   = ptr2[x] >> 4;
 +                    ptr[2*x+1] = ptr2[x] & 0xF;
 +                }
 +            }
 +            ptr  += p->linesize[0];
 +            ptr2 += (w + 15 >> 3) * depth;
 +        }
 +        av_freep(&ptr_free);
 +    }
  
      *picture   = s->picture;
-     *data_size = sizeof(AVFrame);
+     *got_frame = 1;
  
      return buf - bufstart;
  }
Simple merge
@@@ -1008,8 -1003,9 +1008,8 @@@ static av_cold int svq3_decode_init(AVC
  }
  
  static int svq3_decode_frame(AVCodecContext *avctx, void *data,
-                              int *data_size, AVPacket *avpkt)
+                              int *got_frame, AVPacket *avpkt)
  {
 -    const uint8_t *buf = avpkt->data;
      SVQ3Context *svq3  = avctx->priv_data;
      H264Context *h     = &svq3->h;
      MpegEncContext *s  = &h->s;
Simple merge
Simple merge
@@@ -984,8 -540,10 +984,8 @@@ static int tiff_decode_tag(TiffContext 
  }
  
  static int decode_frame(AVCodecContext *avctx,
-                         void *data, int *data_size, AVPacket *avpkt)
+                         void *data, int *got_frame, AVPacket *avpkt)
  {
 -    const uint8_t *buf = avpkt->data;
 -    int buf_size = avpkt->size;
      TiffContext *const s = avctx->priv_data;
      AVFrame *picture = data;
      AVFrame *const p = &s->picture;
          }
      }
      *picture   = s->picture;
-     *data_size = sizeof(AVPicture);
+     *got_frame = 1;
  
 -    return buf_size;
 +    return avpkt->size;
  }
  
  static av_cold int tiff_init(AVCodecContext *avctx)
Simple merge
Simple merge
@@@ -873,8 -861,9 +873,8 @@@ static int decode_frame(AVCodecContext 
          p->pict_type = AV_PICTURE_TYPE_P;
  
      l->cur = !l->cur;
-     *data_size = sizeof(AVFrame);
+     *got_frame      = 1;
      *(AVFrame*)data = l->pic;
 -    av_free(swbuf);
  
      return buf_size;
  }
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -72,12 -43,10 +72,12 @@@ static av_cold int decode_init(AVCodecC
      return 0;
  }
  
- static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt)
  {
 -    int h, w;
 +    V210DecContext *s = avctx->priv_data;
 +
 +    int h, w, stride, aligned_input;
      AVFrame *pic = avctx->coded_frame;
      const uint8_t *psrc = avpkt->data;
      uint16_t *y, *u, *v;
Simple merge
Simple merge
diff --cc libavcodec/vb.c
Simple merge
@@@ -163,13 -159,13 +163,13 @@@ static int vble_decode_frame(AVCodecCon
      /* Chroma */
      if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
          offset += avctx->width * avctx->height;
 -        vble_restore_plane(ctx, 1, offset, width_uv, height_uv);
 +        vble_restore_plane(ctx, &gb, 1, offset, width_uv, height_uv);
  
          offset += width_uv * height_uv;
 -        vble_restore_plane(ctx, 2, offset, width_uv, height_uv);
 +        vble_restore_plane(ctx, &gb, 2, offset, width_uv, height_uv);
      }
  
-     *data_size = sizeof(AVFrame);
+     *got_frame       = 1;
      *(AVFrame *)data = *pic;
  
      return avpkt->size;
@@@ -5363,10 -5331,10 +5363,10 @@@ static int vc1_decode_frame(AVCodecCont
              *pict = s->next_picture_ptr->f;
              s->next_picture_ptr = NULL;
  
-             *data_size = sizeof(AVFrame);
+             *got_frame = 1;
          }
  
 -        return 0;
 +        return buf_size;
      }
  
      if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -490,9 -487,7 +490,9 @@@ static int vp56_size_changed(VP56Contex
      return 0;
  }
  
- int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 +static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int);
 +
+ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                           AVPacket *avpkt)
  {
      const uint8_t *buf = avpkt->data;
              return -1;
      }
  
 -    for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) {
 -        int mb_row, mb_col, mb_row_flip, mb_offset = 0;
 -        int block, y, uv, stride_y, stride_uv;
 -        int golden_frame = 0;
 -        int res;
 +    res = s->parse_header(s, buf, remaining_buf_size);
 +    if (!res)
 +        return -1;
  
 -        s->modelp = &s->models[is_alpha];
 +    if (res == 2) {
 +        for (i = 0; i < 4; i++) {
 +            if (s->frames[i].data[0])
 +                avctx->release_buffer(avctx, &s->frames[i]);
 +        }
 +    }
  
 -        res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);
 -        if (!res)
 +    p->reference = 3;
 +    if (ff_get_buffer(avctx, p) < 0) {
 +        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +        return -1;
 +    }
 +
 +    if (res == 2) {
 +        if (vp56_size_changed(s)) {
 +            avctx->release_buffer(avctx, p);
              return -1;
 +        }
 +    }
  
 -        if (res == 2) {
 -            int i;
 -            for (i = 0; i < 4; i++) {
 -                if (s->frames[i].data[0])
 -                    avctx->release_buffer(avctx, &s->frames[i]);
 -            }
 -            if (is_alpha) {
 -                avcodec_set_dimensions(avctx, 0, 0);
 -                return -1;
 +    if (s->has_alpha) {
 +        int bak_w = avctx->width;
 +        int bak_h = avctx->height;
 +        int bak_cw = avctx->coded_width;
 +        int bak_ch = avctx->coded_height;
 +        buf += alpha_offset;
 +        remaining_buf_size -= alpha_offset;
 +
 +        res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size);
 +        if (res != 1) {
 +            if(res==2) {
 +                av_log(avctx, AV_LOG_ERROR, "Alpha reconfiguration\n");
 +                avctx->width  = bak_w;
 +                avctx->height = bak_h;
 +                avctx->coded_width  = bak_cw;
 +                avctx->coded_height = bak_ch;
              }
 +            avctx->release_buffer(avctx, p);
 +            return -1;
          }
 +    }
  
 -        if (!is_alpha) {
 -            p->reference = 1;
 -            if (ff_get_buffer(avctx, p) < 0) {
 -                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 -                return -1;
 -            }
 +    avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, s->has_alpha + 1);
  
 -            if (res == 2)
 -                if (vp56_size_changed(avctx)) {
 -                    avctx->release_buffer(avctx, p);
 -                    return -1;
 -                }
 -        }
 +    /* release frames that aren't in use */
 +    for (i = 0; i < 4; ++i) {
 +        AVFrame *victim = &s->frames[i];
 +        if (!victim->data[0])
 +            continue;
 +        if (victim != s->framep[VP56_FRAME_PREVIOUS] &&
 +            victim != s->framep[VP56_FRAME_GOLDEN] &&
 +            (!s->has_alpha || victim != s->alpha_context->framep[VP56_FRAME_GOLDEN]))
 +            avctx->release_buffer(avctx, victim);
 +    }
  
 -        if (p->key_frame) {
 -            p->pict_type = AV_PICTURE_TYPE_I;
 -            s->default_models_init(s);
 -            for (block=0; block<s->mb_height*s->mb_width; block++)
 -                s->macroblocks[block].type = VP56_MB_INTRA;
 -        } else {
 -            p->pict_type = AV_PICTURE_TYPE_P;
 -            vp56_parse_mb_type_models(s);
 -            s->parse_vector_models(s);
 -            s->mb_type = VP56_MB_INTER_NOVEC_PF;
 -        }
 +    p->qstride = 0;
 +    p->qscale_table = s->qscale_table;
 +    p->qscale_type = FF_QSCALE_TYPE_VP56;
 +    *(AVFrame*)data = *p;
-     *data_size = sizeof(AVFrame);
++    *got_frame = 1;
 +
 +    return avpkt->size;
 +}
 +
 +static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
 +                              int jobnr, int threadnr)
 +{
 +    VP56Context *s0 = avctx->priv_data;
 +    int is_alpha = (jobnr == 1);
 +    VP56Context *s = is_alpha ? s0->alpha_context : s0;
 +    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
 +    int mb_row, mb_col, mb_row_flip, mb_offset = 0;
 +    int block, y, uv, stride_y, stride_uv;
 +
 +    if (p->key_frame) {
 +        p->pict_type = AV_PICTURE_TYPE_I;
 +        s->default_models_init(s);
 +        for (block=0; block<s->mb_height*s->mb_width; block++)
 +            s->macroblocks[block].type = VP56_MB_INTRA;
 +    } else {
 +        p->pict_type = AV_PICTURE_TYPE_P;
 +        vp56_parse_mb_type_models(s);
 +        s->parse_vector_models(s);
 +        s->mb_type = VP56_MB_INTER_NOVEC_PF;
 +    }
  
 -        if (s->parse_coeff_models(s))
 -            goto next;
 +    if (s->parse_coeff_models(s))
 +        goto next;
  
 -        memset(s->prev_dc, 0, sizeof(s->prev_dc));
 -        s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
 -        s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
 +    memset(s->prev_dc, 0, sizeof(s->prev_dc));
 +    s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
 +    s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
  
 -        for (block=0; block < 4*s->mb_width+6; block++) {
 -            s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
 -            s->above_blocks[block].dc_coeff = 0;
 -            s->above_blocks[block].not_null_dc = 0;
 -        }
 -        s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
 -        s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
 +    for (block=0; block < 4*s->mb_width+6; block++) {
 +        s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
 +        s->above_blocks[block].dc_coeff = 0;
 +        s->above_blocks[block].not_null_dc = 0;
 +    }
 +    s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
 +    s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
 +
 +    stride_y  = p->linesize[0];
 +    stride_uv = p->linesize[1];
  
 -        stride_y  = p->linesize[0];
 -        stride_uv = p->linesize[1];
 +    if (s->flip < 0)
 +        mb_offset = 7;
  
 +    /* main macroblocks loop */
 +    for (mb_row=0; mb_row<s->mb_height; mb_row++) {
          if (s->flip < 0)
 -            mb_offset = 7;
 -
 -        /* main macroblocks loop */
 -        for (mb_row=0; mb_row<s->mb_height; mb_row++) {
 -            if (s->flip < 0)
 -                mb_row_flip = s->mb_height - mb_row - 1;
 -            else
 -                mb_row_flip = mb_row;
 -
 -            for (block=0; block<4; block++) {
 -                s->left_block[block].ref_frame = VP56_FRAME_NONE;
 -                s->left_block[block].dc_coeff = 0;
 -                s->left_block[block].not_null_dc = 0;
 -            }
 -            memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
 -            memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
 -
 -            s->above_block_idx[0] = 1;
 -            s->above_block_idx[1] = 2;
 -            s->above_block_idx[2] = 1;
 -            s->above_block_idx[3] = 2;
 -            s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
 -            s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
 -
 -            s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
 -            s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
 -            s->block_offset[1] = s->block_offset[0] + 8;
 -            s->block_offset[3] = s->block_offset[2] + 8;
 -            s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
 -            s->block_offset[5] = s->block_offset[4];
 -
 -            for (mb_col=0; mb_col<s->mb_width; mb_col++) {
 -                vp56_decode_mb(s, mb_row, mb_col, is_alpha);
 -
 -                for (y=0; y<4; y++) {
 -                    s->above_block_idx[y] += 2;
 -                    s->block_offset[y] += 16;
 -                }
 +            mb_row_flip = s->mb_height - mb_row - 1;
 +        else
 +            mb_row_flip = mb_row;
  
 -                for (uv=4; uv<6; uv++) {
 -                    s->above_block_idx[uv] += 1;
 -                    s->block_offset[uv] += 8;
 -                }
 -            }
 +        for (block=0; block<4; block++) {
 +            s->left_block[block].ref_frame = VP56_FRAME_NONE;
 +            s->left_block[block].dc_coeff = 0;
 +            s->left_block[block].not_null_dc = 0;
          }
 +        memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
 +        memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
 +
 +        s->above_block_idx[0] = 1;
 +        s->above_block_idx[1] = 2;
 +        s->above_block_idx[2] = 1;
 +        s->above_block_idx[3] = 2;
 +        s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
 +        s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
 +
 +        s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
 +        s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
 +        s->block_offset[1] = s->block_offset[0] + 8;
 +        s->block_offset[3] = s->block_offset[2] + 8;
 +        s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
 +        s->block_offset[5] = s->block_offset[4];
 +
 +        for (mb_col=0; mb_col<s->mb_width; mb_col++) {
 +            vp56_decode_mb(s, mb_row, mb_col, is_alpha);
 +
 +            for (y=0; y<4; y++) {
 +                s->above_block_idx[y] += 2;
 +                s->block_offset[y] += 16;
 +            }
  
 -    next:
 -        if (p->key_frame || golden_frame) {
 -            if (s->framep[VP56_FRAME_GOLDEN]->data[0] &&
 -                s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])
 -                avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
 -            s->framep[VP56_FRAME_GOLDEN] = p;
 +            for (uv=4; uv<6; uv++) {
 +                s->above_block_idx[uv] += 1;
 +                s->block_offset[uv] += 8;
 +            }
          }
 +    }
  
 -        if (s->has_alpha) {
 -            FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN],
 -                              s->framep[VP56_FRAME_GOLDEN2]);
 -            buf += alpha_offset;
 -            remaining_buf_size -= alpha_offset;
 -        }
 +next:
 +    if (p->key_frame || s->golden_frame) {
 +        s->framep[VP56_FRAME_GOLDEN] = p;
      }
  
 -    if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] ||
 -        s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) {
 -        if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] &&
 -            s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2])
 -            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
 -                              s->framep[VP56_FRAME_UNUSED]);
 -        else
 -            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
 -                              s->framep[VP56_FRAME_UNUSED2]);
 -    } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
 -        avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
      FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
                        s->framep[VP56_FRAME_PREVIOUS]);
 -
 -    p->qstride = 0;
 -    p->qscale_table = s->qscale_table;
 -    p->qscale_type = FF_QSCALE_TYPE_VP56;
 -    *(AVFrame*)data = *p;
 -    *got_frame = 1;
 -
 -    return avpkt->size;
 +    return 0;
  }
  
  av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
@@@ -178,12 -174,9 +178,12 @@@ struct vp56_context 
  
  
  void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
 +void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
 +                          int flip, int has_alpha);
  int ff_vp56_free(AVCodecContext *avctx);
 +int ff_vp56_free_context(VP56Context *s);
  void ff_vp56_init_dequant(VP56Context *s, int quantizer);
- int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                           AVPacket *avpkt);
  
  
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc libavcodec/xl.c
@@@ -38,11 -38,10 +38,11 @@@ static const int xl_table[32] = 
     0,   1,   2,   3,   4,   5,   6,   7,
     8,   9,  12,  15,  20,  25,  34,  46,
    64,  82,  94, 103, 108, 113, 116, 119,
 - 120, 121, 122, 123, 124, 125, 126, 127};
 + 120, 121, 122, 123, 124, 125, 126, 127
 +};
  
  static int decode_frame(AVCodecContext *avctx,
-                         void *data, int *data_size,
+                         void *data, int *got_frame,
                          AVPacket *avpkt)
  {
      const uint8_t *buf = avpkt->data;
Simple merge
Simple merge
Simple merge
Simple merge