[Ffmpeg-devel] [RFC] ZMBV encoder
Michael Niedermayer
michaelni
Mon Dec 4 16:59:35 CET 2006
Hi
On Mon, Dec 04, 2006 at 08:13:57AM +0200, Kostya wrote:
> Here is my ZMBV encoder for encoding palettized videos.
> Index: libavcodec/zmbvenc.c
> ===================================================================
> --- libavcodec/zmbvenc.c (revision 0)
> +++ libavcodec/zmbvenc.c (revision 0)
[...]
> +
> +#define ZMBV_KEYFRAME 1
> +#define ZMBV_DELTAPAL 2
duplicate from zmbv.c
[...]
> +/** Block comparing function
> + * XXX should be optimized and moved to DSPContext
> + * TODO handle out of edge ME
> + */
> +int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh)
> +{
> + int sum = 0;
> + int i, j;
> + for(j = 0; j < bh; j++){
> + for(i = 0; i < bw; i++)
> + sum += src[i] ^ src2[i];
> + src += stride;
> + src2 += stride2;
> + }
> + return sum;
> +}
i dont think sum += src[i] ^ src2[i]; is optimal compression wise ...
_maybe_
sum += score[src[i] ^ src2[i]];
and
for(i,j=0; i,j<256; i,j++){
score[i^j] += ABS(i-j);
}
or even simply
sum += ABS(src[i] - src2[i])
might be better, and of course a
for()
dst[i]= src[i] ^ src2[i];
sum= lzw_size(dst, len);
might be interresting ...
[...]
> + uint8_t tpal[3];
> + for(i = 0; i < 256; i++){
> + tpal[0] = (palptr[i] >> 16) & 0xFF;
> + tpal[1] = (palptr[i] >> 8) & 0xFF;
> + tpal[2] = palptr[i] & 0xFF;
the &0xFF is unneeded
[...]
> + }else{
> + int x, y, bh2, bw2;
> + uint8_t *tsrc, *tprev;
> + uint8_t *mv;
> + int bmvx, bmvy, bv, tx, ty, tv, dx, dy;
> +
> + bw = (avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK;
> + bh = (avctx->height + ZMBV_BLOCK - 1) / ZMBV_BLOCK;
> + mv = c->work_buf + work_size;
> + memset(c->work_buf + work_size, 0, (bw * bh * 2 + 3) & ~3);
> + work_size += (bw * bh * 2 + 3) & ~3;
> + /* for now just XOR'ing */
> + for(y = 0; y < avctx->height; y += ZMBV_BLOCK) {
> + bh2 = FFMIN(avctx->height - y, ZMBV_BLOCK);
> + for(x = 0; x < avctx->width; x += ZMBV_BLOCK, mv += 2) {
> + bw2 = FFMIN(avctx->width - x, ZMBV_BLOCK);
> +
> + tsrc = src + x;
> + tprev = prev + x;
> +
> + bmvx = bmvy = 0;
> + bv = block_cmp(tsrc, p->linesize[0], tprev, c->pstride, ZMBV_BLOCK, ZMBV_BLOCK);
> + if(bv) for(ty = FFMAX(y - 16, 0); ty < FFMIN(y + 16, avctx->height - ZMBV_BLOCK); ty++){
> + for(tx = FFMAX(x - 16, 0); tx < FFMIN(x + 16, avctx->width - ZMBV_BLOCK); tx++){
use avctx->me_range
> + if(tx == x && ty == y) continue; // we already tested this block
> + dx = tx - x;
> + dy = ty - y;
> + tv = block_cmp(tsrc, p->linesize[0], tprev + dx + dy*c->pstride, c->pstride, ZMBV_BLOCK, ZMBV_BLOCK);
> + if(tv < bv){
> + bv = tv;
> + bmvx = dx;
> + bmvy = dy;
> + if(!bv) break;
> + }
> + }
> + if(!bv) break;
> + }
hmmmmm
maybe try using the motion estimation code from lavc or at least implement
a optional more practical variant ...
practical:
take motion vector from left, top, top right, last frame and (0,0)
try cmp on all, take best
try (x,y+1), (x,y-1), (x+1,y) (x-1,y) where (x,y) is the best so far
continue this until the best is in the middle of this small set in
which case you are done
improvments:
try median(top,left,top right)
try right one from last frame and try bottom one from last frame
[...]
> + c->width = avctx->width;
> + c->height = avctx->height;
> + c->curfrm = 0;
> + c->keyint = avctx->keyint_min;
why is this copied from avctx? the copied variants dont seem to be used
much ...
[...]
> +/*
> + *
> + * Uninit zmbv decoder
> + *
> + */
not doxygen compatible
[...]
> +
> +AVCodec zmbv_encoder = {
> + "zmbv",
> + CODEC_TYPE_VIDEO,
> + CODEC_ID_ZMBV,
> + sizeof(ZmbvEncContext),
> + encode_init,
> + encode_frame,
> + encode_end
> +};
supported pix_fmt entry is missing
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
In the past you could go to a library and read, borrow or copy any book
Today you'd get arrested for mere telling someone where the library is
More information about the ffmpeg-devel
mailing list