On 02/13/2012 10:18 AM, Anton Khirnov wrote:

> ---
>  libavcodec/zmbvenc.c |   33 +++++++++++++++++++++++++++------
>  1 files changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
> index ebb6624..1340a07 100644
> --- a/libavcodec/zmbvenc.c
> +++ b/libavcodec/zmbvenc.c
> @@ -29,6 +29,7 @@
>  
>  #include "libavutil/intreadwrite.h"
>  #include "avcodec.h"
> +#include "internal.h"
>  
>  #include <zlib.h>
>  
> @@ -115,20 +116,27 @@ static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int 
> sstride, uint8_t *prev,
>      return bv;
>  }
>  
> -static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
> void *data)
> +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
> +                        const AVFrame *pict, int *got_packet)
>  {
>      ZmbvEncContext * const c = avctx->priv_data;
> -    AVFrame *pict = data;
>      AVFrame * const p = &c->pic;
> -    uint8_t *src, *prev;
> +    uint8_t *src, *prev, *buf;
>      uint32_t *palptr;
> -    int len = 0;
> +    int len = 0, ret;
>      int keyframe, chpal;
>      int fl;
>      int work_size = 0;
>      int bw, bh;
>      int i, j;
>  
> +    if (!pkt->data &&
> +        (ret = av_new_packet(pkt, c->comp_size + 6)) < 0) {
> +        av_log(avctx, AV_LOG_ERROR, "Could not alloc output packet.\n");
> +        return ret;
> +    }
> +    buf = pkt->data;
> +
>      keyframe = !c->curfrm;
>      c->curfrm++;
>      if(c->curfrm == c->keyint)
> @@ -141,6 +149,11 @@ static int encode_frame(AVCodecContext *avctx, uint8_t 
> *buf, int buf_size, void
>      fl = (keyframe ? ZMBV_KEYFRAME : 0) | (chpal ? ZMBV_DELTAPAL : 0);
>      *buf++ = fl; len++;
>      if(keyframe){
> +        if (pkt->size < 6) {
> +            av_log(avctx, AV_LOG_ERROR, "Output buffer too small.\n");
> +            return AVERROR(EINVAL);
> +        }
> +
>          deflateReset(&c->zstream);
>          *buf++ = 0; len++; // hi ver
>          *buf++ = 1; len++; // lo ver
> @@ -235,8 +248,16 @@ static int encode_frame(AVCodecContext *avctx, uint8_t 
> *buf, int buf_size, void
>          return -1;
>      }
>  
> +    if (pkt->size - (buf - pkt->data) < c->zstream.total_out) {
> +        av_log(avctx, AV_LOG_ERROR, "Output buffer too small.\n");
> +        return AVERROR(EINVAL);
> +    }
>      memcpy(buf, c->comp_buf, c->zstream.total_out);
> -    return len + c->zstream.total_out;
> +
> +    pkt->size   = len + c->zstream.total_out;
> +    pkt->flags |= AV_PKT_FLAG_KEY*p->key_frame;
> +    *got_packet = 1;
> +    return 0;
>  }
>  
>  
> @@ -329,7 +350,7 @@ AVCodec ff_zmbv_encoder = {
>      .id             = CODEC_ID_ZMBV,
>      .priv_data_size = sizeof(ZmbvEncContext),
>      .init           = encode_init,
> -    .encode         = encode_frame,
> +    .encode2        = encode_frame,
>      .close          = encode_end,
>      .pix_fmts = (const enum PixelFormat[]){PIX_FMT_PAL8, PIX_FMT_NONE},
>      .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),


It looks like a max of only 7 bytes are written before you know the
actual output size. So why not have a local 7-byte buffer for that, then
use ff_alloc_packet() with the real size before the memcpy()?

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

Reply via email to