[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