[FFmpeg-devel] a64 encoder 5th round

Vitor Sessak vitor1001
Fri Jan 23 21:19:22 CET 2009


Michael Niedermayer wrote:
> On Fri, Jan 23, 2009 at 10:28:31AM +0100, Bitbreaker/METALVOTZE wrote:
>> Cleaned up a few more things in the code, also added issues found by Aurel. 
>> Anything else to fix?
> [...]
>> +/* own methods */
>> +static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest)
>> +{
>> +    int blockx, blocky, x, y;
>> +    int luma = 0;
> 
>> +    int height = avctx->height;
>> +    int width = avctx->width;
> 
> these could be set to FFMIN(width, C64XRES) ... i think
> 
> 
>> +    uint8_t *src = p->data[0];
>> +
>> +    for (blocky = 0; blocky<height && blocky < C64YRES; blocky += 8) {
>> +        for (blockx = 0; blockx<width && blockx < C64XRES; blockx += 8) {
>> +            for (y = blocky; y < blocky+8 && y<C64YRES && y<height; y++) {
>> +                for (x = blockx; x < blockx+8 && x<C64XRES && x<width; x += 2) {
>> +                    /* build average over 2 pixels */
>> +                    luma = (src[(x + 0 + y * p->linesize[0])] +
>> +                            src[(x + 1 + y * p->linesize[0])]) / 2;
>> +                    /* write blocks as linear data now so they are suitable for elbg */
> 
>> +                    dest[0] = luma; dest++;
> 
> *dest++ = ...
> 
> 
> [...]
>> +    const uint8_t vals[] = { 3, 2, 1, 0, 3 };
> 
> static const
> 
> 
>> +    int luma;
>> +    int pix;
>> +    int lowdiff;
>> +    int highdiff;
>> +    int dsteps = c->mc_dithersteps;
>> +    int maxindex = c->mc_use_5col + 3;
>> +    int maxsteps = c->mc_dithersteps * maxindex + 1;
>> +    int *best_cb = c->mc_best_cb;
>> +
>> +    /* now reduce colors first */
>> +    for (x = 0; x < 256 * 32; x++) {
>> +        luma = best_cb[x];
>> +        pix = luma * maxsteps / 255;
>> +        if (pix > maxsteps)
>> +            pix = maxsteps;
>> +        best_cb[x] = pix;
>> +    }
>> +
>> +    /* and render charset */
>> +    for (charpos = 0; charpos < 256; charpos++) {
>> +        lowdiff = 0;
>> +        highdiff = 0;
>> +        for (y = 0; y < 8; y++) {
>> +            row1 = 0;
>> +            for (x = 0; x < 4; x++) {
>> +                pix = best_cb[y * 4 + x];
>> +                dither = pix % dsteps;
>> +                index1 = pix / dsteps;
>> +                if (index1 == maxindex)
>> +                    index2 = maxindex;
>> +                else
>> +                    index2 = index1 + 1;
>> +
>> +                if (pix > 3 * dsteps)
>> +                    highdiff += pix - 3 * dsteps;
>> +                if (pix < dsteps)
>> +                    lowdiff += dsteps - pix;
>> +
> 
>> +                row1 <<= 2;
>> +                if (prep_dither_patterns[dither][y & 3][x & 3])
>> +                    row1 |= vals[index2];
>> +                else
>> +                    row1 |= vals[index1];
>> +            }
>> +            charset[y] = row1;
> 
> could be simplified slightly with put_bits()
> 
> besides the way you do dithering is uncommon ...
> i assume you have a reason why you dont use ordered dither, or one of the
> error diffusion dithers? last should be vastly better except maybe some
> flickering between frames and the need to consider already set patterns
> of neighborin blocks ...

Or instead of considering neighboring blocks, you could pass a 1 pixel 
border to elbg, with dim=10x6 (there will be pixels that will be in more 
than one block, maybe you could given a smaller weight for them). Then 
you could apply dithering to each one of the block+border codebook 
entries, but keep only the block for your charset.

-Vitor




More information about the ffmpeg-devel mailing list