X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fzmbvenc.c;h=a04c0597ee5e7d99ad2d2a15c4a1ebfe1fb431f2;hb=4fab6627697100ccc3135a13f4d0eb483cbe3227;hp=a6b51ba306bb51d89a05114df57cd907f99e26b9;hpb=fe4bf37455e81ecf2c0b769c979bdf6eec785602;p=ffmpeg diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index a6b51ba306b..a04c0597ee5 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -20,13 +20,14 @@ */ /** - * @file zmbvenc.c + * @file libavcodec/zmbvenc.c * Zip Motion Blocks Video encoder */ #include #include +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include @@ -60,21 +61,26 @@ static int score_tab[256]; * XXX should be optimized and moved to DSPContext * TODO handle out of edge ME */ -static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh) +static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, + int bw, int bh, int *xored) { int sum = 0; int i, j; - uint8_t histogram[256]={0}; + uint8_t histogram[256] = {0}; + *xored = 0; for(j = 0; j < bh; j++){ - for(i = 0; i < bw; i++) - histogram[src[i] ^ src2[i]]++; + for(i = 0; i < bw; i++){ + int t = src[i] ^ src2[i]; + histogram[t]++; + *xored |= t; + } src += stride; src2 += stride2; } - for(i=1; i<256; i++) - sum+= score_tab[histogram[i]]; + for(i = 1; i < 256; i++) + sum += score_tab[histogram[i]]; return sum; } @@ -82,22 +88,22 @@ static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2 /** Motion estimation function * TODO make better ME decisions */ -static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, int pstride, - int x, int y, int *mx, int *my) +static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, + int pstride, int x, int y, int *mx, int *my, int *xored) { int dx, dy, tx, ty, tv, bv, bw, bh; *mx = *my = 0; bw = FFMIN(ZMBV_BLOCK, c->avctx->width - x); bh = FFMIN(ZMBV_BLOCK, c->avctx->height - y); - bv = block_cmp(src, sstride, prev, pstride, bw, bh); + bv = block_cmp(src, sstride, prev, pstride, bw, bh, xored); if(!bv) return 0; for(ty = FFMAX(y - c->range, 0); ty < FFMIN(y + c->range, c->avctx->height - bh); ty++){ for(tx = FFMAX(x - c->range, 0); tx < FFMIN(x + c->range, c->avctx->width - bw); tx++){ if(tx == x && ty == y) continue; // we already tested this block dx = tx - x; dy = ty - y; - tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh); + tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh, xored); if(tv < bv){ bv = tv; *mx = dx; @@ -116,7 +122,6 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void AVFrame * const p = &c->pic; uint8_t *src, *prev; uint32_t *palptr; - int zret = Z_OK; int len = 0; int keyframe, chpal; int fl; @@ -173,7 +178,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void work_size += avctx->width; } }else{ - int x, y, bh2, bw2; + int x, y, bh2, bw2, xored; uint8_t *tsrc, *tprev; uint8_t *mv; int mx, my, bv; @@ -192,11 +197,11 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void tsrc = src + x; tprev = prev + x; - bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my); - mv[0] = (mx << 1) | !!bv; + bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my, &xored); + mv[0] = (mx << 1) | !!xored; mv[1] = my << 1; tprev += mx + my * c->pstride; - if(bv){ + if(xored){ for(j = 0; j < bh2; j++){ for(i = 0; i < bw2; i++) c->work_buf[work_size++] = tsrc[i] ^ tprev[i]; @@ -225,7 +230,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void c->zstream.next_out = c->comp_buf; c->zstream.avail_out = c->comp_size; c->zstream.total_out = 0; - if((zret = deflate(&c->zstream, Z_SYNC_FLUSH)) != Z_OK){ + if(deflate(&c->zstream, Z_SYNC_FLUSH) != Z_OK){ av_log(avctx, AV_LOG_ERROR, "Error compressing data\n"); return -1; } @@ -250,7 +255,6 @@ static av_cold int encode_init(AVCodecContext *avctx) c->avctx = avctx; - c->pic.data[0] = NULL; c->curfrm = 0; c->keyint = avctx->keyint_min; c->range = 8; @@ -264,10 +268,6 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } - if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - return -1; - } - // Needed if zlib unused or init aborted before deflateInit memset(&(c->zstream), 0, sizeof(z_stream)); c->comp_size = avctx->width * avctx->height + 1024 + @@ -285,7 +285,7 @@ static av_cold int encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); return -1; } - c->pstride = (avctx->width + 15) & ~15; + c->pstride = FFALIGN(avctx->width, 16); if ((c->prev = av_malloc(c->pstride * avctx->height)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate picture.\n"); return -1; @@ -300,6 +300,8 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } + avctx->coded_frame = (AVFrame*)&c->pic; + return 0; } @@ -329,6 +331,6 @@ AVCodec zmbv_encoder = { encode_init, encode_frame, encode_end, - .pix_fmts = (enum PixelFormat[]){PIX_FMT_PAL8, PIX_FMT_NONE}, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_PAL8, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), };