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