[Ffmpeg-devel] [PATCH] CYUV encoder resurrected

Michael Niedermayer michaelni
Sun Mar 4 19:49:37 CET 2007


Hi

On Sat, Mar 03, 2007 at 11:23:22PM -0700, Loren Merritt wrote:
> On Sat, 3 Mar 2007, Michael Niedermayer wrote:
> >On Fri, Mar 02, 2007 at 08:10:12PM -0700, Loren Merritt wrote:
> >
> >>Better yet, don't compute abs at all. The whole codec (without trellis) is
> >>13% faster this way.
> >
> >hmm, if this code matters so much speedwise then i think it could be 
> >changed
> >to
> >int p = *pred;
> >int bi = itable[(sample - p) & 0xff];
> >*pred = p + table[bi];
> >if(*pred & ~0xff){
> >   bi = itable2[(sample - p) & 0xff];
> >   *pred = p + table[bi];
> >}
> >
> >where itable2 rounds in the oposite direction than itable
> 
> Old code was wrong. It only triggered the correction when the quantized 
> delta overflows and the input doesn't, but it should also trigger when the 
> input delta overflows and the quantized one doesn't.
> After fixing that I don't see how to implement the correction as a table, 
> but I can avoid the search.

new code seems wrong too, ive attached some test code, with your new code,
my 2 table variant and bruteforce quantization

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The misfortune of the wise is better than the prosperity of the fool.
-- Epicurus
-------------- next part --------------

#include <stdio.h>
#include <inttypes.h>
#include <limits.h>
#include <assert.h>

#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)

static int quantize_sample(int sample, int *pred, const int8_t *table, const uint8_t *itable)
{
    int p = *pred;
    int bi = itable[(sample - p) & 0xff];
    int res = (p + table[bi]) & 0xff;
    int error = res - sample;
    if((unsigned)(error + 0x80) > 0xff){
        if(error > 0)
            bi++;
        else
            bi--;
        bi &= 15;
        res = (p + table[bi]) & 0xff;
    }
    *pred = res;
    return bi;
}

static int quantize_sample1(int sample, int *pred, const uint8_t *table, const uint8_t *itable1, const uint8_t *itable2)
{
    int p = *pred;
    int bi = itable1[(sample - p) & 0xff];
    int res = (p + table[bi]) & 0xff;
    int error = res - sample;

    if((unsigned)(error + 0x80) > 0xff){
        bi = itable2[(sample - p) & 0xff];
        res = (p + table[bi]) & 0xff;
    }
    *pred = res;
    return bi;
}

static int quantize_sample2(int sample, int *pred, const uint8_t *table)
{
    int p = *pred;
    int i, bi;
    int berror= 256;

    for(i=0; i<16; i++){
        int res= (p + table[i]) & 0xff;
        int error = abs(res - sample);
        if(error < berror){
            berror= error;
            bi= i;
        }
    }
    *pred = (p + table[bi]) & 0xff;
    return bi;
}

static void build_inverse_table(uint8_t *itable, const int8_t *table)
{
    int d, i;
    for(i=1; i<16; i++)
        assert(table[i] > table[i-1]);
    for(d=-128; d<128; d++){
        int bscore = INT_MAX;
        for(i=0; i<16; i++){
            int score = abs(d - table[i]);
            if(score > bscore)
                break;
            bscore = score;
        }
        itable[d&0xff] = i-1;
    }
}


static void build_inverse_table1(uint8_t *itable1, uint8_t *itable2, const uint8_t *table)
{
    int d, i;
    for(d=0; d<256; d++){
        int bscore0 = INT_MAX;
        int bscore1 = INT_MIN;
        for(i=0; i<16; i++){
            int score = (d - table[i]) & 0xFF;

            if(score < bscore0){
                bscore0 = score;
                itable1[d] = i;
            }
            if(score > bscore1){
                bscore1 = score;
                itable2[d] = i;
            }
        }
        if(256-bscore1 < bscore0)
            FFSWAP(int, itable1[d], itable2[d]);
    }
}

main(){
    static const int8_t table[16] = {
        -116, -75, -48, -31, -18,  -9, -4, -3, 0, 1, 4,  9, 18, 32, 54, 95
        //-39, -22, -13,  -8,  -5,  -2, -1,  0, 1, 2, 5,  8, 13, 20, 31, 48
    };

    static uint8_t itable[256], itable1[256], itable2[256];
    int x,y, e[3]={0}, pred;

    build_inverse_table(itable, table);

    build_inverse_table1(itable1, itable2, table);

    for(x=0; x<256; x++){
        for(y=0; y<256; y++){
            pred= x;
            quantize_sample(y, &pred, table, itable);
            e[0] += abs(y - pred);

            pred= x;
            quantize_sample1(y, &pred, table, itable1, itable2);
            e[1] += abs(y - pred);

            pred= x;
            quantize_sample2(y, &pred, table);
            e[2] += abs(y - pred);
        }
    }
    printf("errors:%d %d %d\n", e[0], e[1], e[2]);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070304/4e1f49c3/attachment.pgp>



More information about the ffmpeg-devel mailing list