Beispiel #1
0
static double od_pvq_rate(int qg, int icgr, int theta, int ts,
 const od_adapt_ctx *adapt, const od_coeff *y0, int k, int n,
 int is_keyframe, int pli) {
  double rate;
#if OD_PVQ_RATE_APPROX
  /* Estimates the number of bits it will cost to encode K pulses in
     N dimensions based on experimental data for bitrate vs K. */
  rate = n*OD_LOG2(1+log(n*2)*k/n);
  OD_UNUSED(adapt);
  OD_UNUSED(y0);
  OD_UNUSED(bs);
#else
  if (k > 0){
    od_ec_enc ec;
    od_pvq_codeword_ctx cd;
    int tell;
    od_ec_enc_init(&ec, 1000);
    OD_COPY(&cd, &adapt->pvq.pvq_codeword_ctx, 1);
    tell = od_ec_enc_tell_frac(&ec);
    od_encode_pvq_codeword(&ec, &cd, y0, n - (theta != -1), k);
    rate = (od_ec_enc_tell_frac(&ec)-tell)/8.;
    od_ec_enc_clear(&ec);
  }
  else rate = 0;
#endif
  if (qg > 0 && theta >= 0) {
    /* Approximate cost of entropy-coding theta */
    rate += .9*OD_LOG2(ts);
    /* Adding a cost to using the H/V pred because it's going to be off
       most of the time. Cost is optimized on subset1, while making
       sure we don't hurt the checkerboard image too much.
       FIXME: Do real RDO instead of this arbitrary cost. */
    if (is_keyframe && pli == 0) rate += 6;
    if (qg == icgr) rate -= .5;
  }
  return rate;
}
Beispiel #2
0
int main(int _argc,char **_argv) {
    od_ec_enc      enc;
    od_ec_enc      enc_bak;
    od_ec_dec      dec;
    long           nbits;
    long           nbits2;
    double         entropy;
    int            ft;
    int            ftb;
    int            sz;
    int            i;
    int            ret;
    unsigned int   sym;
    unsigned int   seed;
    unsigned char *ptr;
    ogg_uint32_t   ptr_sz;
    const char    *env_seed;
    ret=EXIT_SUCCESS;
    entropy=0;
    if(_argc>2) {
        fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
        return EXIT_FAILURE;
    }
    env_seed=getenv("SEED");
    if(_argc>1)seed=atoi(_argv[1]);
    else if(env_seed)seed=atoi(env_seed);
    else seed=time(NULL);
    /*Trigger resize during termination.*/
    for(ft=2; ft<1024; ft++) {
        for(i=0; i<ft; i++) {
            od_ec_enc_init(&enc,ft+i&1);
            od_ec_enc_uint(&enc,i,ft);
            nbits=od_ec_enc_tell_frac(&enc);
            ptr=od_ec_enc_done(&enc,&ptr_sz);
            od_ec_dec_init(&dec,ptr,ptr_sz);
            sym=od_ec_dec_uint(&dec,ft);
            if(sym!=(unsigned)i) {
                fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
                ret=EXIT_FAILURE;
            }
            nbits2=od_ec_dec_tell_frac(&dec);
            if(nbits!=nbits2) {
                fprintf(stderr,"enc_tell_frac == %li, dec_tell_frac == %li\n",
                        nbits,nbits2);
                ret=EXIT_FAILURE;
            }
            if(dec.error) {
                fprintf(stderr,"uint error decoding %i with ft of %i.\n",i,ft);
                ret=EXIT_FAILURE;
            }
            od_ec_enc_clear(&enc);
        }
    }
    /*Raw bits only w/ resize*/
    for(ftb=1; ftb<17; ftb++) {
        for(i=0; i<(1<<ftb); i++) {
            od_ec_enc_init(&enc,ftb+i&1);
            od_ec_enc_checkpoint(&enc_bak,&enc);
            od_ec_enc_bits(&enc,i,ftb);
            od_ec_enc_rollback(&enc,&enc_bak);
            od_ec_enc_bits(&enc,i,ftb);
            ptr=od_ec_enc_done(&enc,&ptr_sz);
            if(ptr_sz!=(unsigned)ftb+7>>3) {
                fprintf(stderr,"Used %li bytes to encode %i bits directly.\n",
                        (long)ptr_sz,ftb);
                ret=EXIT_FAILURE;
            }
            od_ec_dec_init(&dec,ptr,ptr_sz);
            sym=od_ec_dec_bits(&dec,ftb);
            if(sym!=(unsigned)i) {
                fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
                ret=EXIT_FAILURE;
            }
            od_ec_enc_clear(&enc);
        }
    }
    /*Testing unsigned integer corruption*/
    od_ec_enc_init(&enc,2);
    od_ec_enc_uint(&enc,128,129);
    od_ec_enc_checkpoint(&enc_bak,&enc);
    od_ec_enc_uint(&enc,128,129);
    od_ec_enc_uint(&enc,128,129);
    od_ec_enc_uint(&enc,128,129);
    od_ec_enc_rollback(&enc,&enc_bak);
    ptr=od_ec_enc_done(&enc,&ptr_sz);
    if(ptr_sz!=1) {
        fprintf(stderr,"Incorrect output size %li.\n",(long)ptr_sz);
        ret=EXIT_FAILURE;
    }
    for(i=0; i<256; i++) {
        ptr[ptr_sz-1]=i;
        od_ec_dec_init(&dec,ptr,ptr_sz);
        sym=od_ec_dec_uint(&dec,129);
        if(i>=228 && i!=240 && !dec.error) {
            fprintf(stderr,"Failed to detect uint error with %i.\n",i);
            ret=EXIT_FAILURE;
        }
        if(sym>=255) {
            fprintf(stderr,"Corrupt uint out of range %i>=255 for %d.\n",sym,i);
            ret=EXIT_FAILURE;
        }
    }
    od_ec_enc_clear(&enc);
    /*Testing encoding of unsigned integers.*/
    od_ec_enc_init(&enc,1);
    for(ft=2; ft<1024; ft++) {
        for(i=0; i<ft; i++) {
            entropy+=log(ft)*M_LOG2E;
            od_ec_enc_checkpoint(&enc_bak,&enc);
            od_ec_enc_uint(&enc,0,ft);
            od_ec_enc_rollback(&enc,&enc_bak);
            od_ec_enc_uint(&enc,i,ft);
            od_ec_enc_checkpoint(&enc_bak,&enc);
            od_ec_enc_uint(&enc,1,ft);
            od_ec_enc_rollback(&enc,&enc_bak);
        }
        if(ft==512)ptr=od_ec_enc_done(&enc,&ptr_sz);
    }
    /*Testing encoding of raw bit values.*/
    for(ftb=1; ftb<16; ftb++) {
        for(i=0; i<(1<<ftb); i++) {
            entropy+=ftb;
            nbits=od_ec_enc_tell(&enc);
            od_ec_enc_bits(&enc,i,ftb);
            nbits2=od_ec_enc_tell(&enc);
            if(nbits2-nbits!=ftb) {
                fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
                        nbits2-nbits,ftb);
                ret=EXIT_FAILURE;
            }
        }
    }
    nbits=od_ec_enc_tell_frac(&enc);
    ptr=od_ec_enc_done(&enc,&ptr_sz);
    fprintf(stderr,
            "Encoded %0.2f bits of entropy to %0.2f bits (%0.3f%% wasted).\n",
            entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
    fprintf(stderr,"Packed to %li bytes.\n",(long)ptr_sz);
    od_ec_dec_init(&dec,ptr,ptr_sz);
    for(ft=2; ft<1024; ft++) {
        for(i=0; i<ft; i++) {
            sym=od_ec_dec_uint(&dec,ft);
            if(sym!=(unsigned)i) {
                fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
                ret=EXIT_FAILURE;
            }
        }
    }
    for(ftb=1; ftb<16; ftb++) {
        for(i=0; i<(1<<ftb); i++) {
            sym=od_ec_dec_bits(&dec,ftb);
            if(sym!=(unsigned)i) {
                fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
                ret=EXIT_FAILURE;
            }
        }
    }
    nbits2=od_ec_dec_tell_frac(&dec);
    if(nbits!=nbits2) {
        fprintf(stderr,
                "Reported number of bits used was %0.2f, should be %0.2f.\n",
                ldexp(nbits2,-3),ldexp(nbits,-3));
        ret=EXIT_FAILURE;
    }
    srand(seed);
    fprintf(stderr,"Testing random streams... Random seed: %u (%.4X).\n",
            seed,rand()&65535);
    for(i=0; i<409600; i++) {
        unsigned *data;
        unsigned *tell;
        unsigned  tell_bits;
        int       j;
        int zeros;
        ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;
        sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
        data=(unsigned *)malloc(sz*sizeof(*data));
        tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
        od_ec_enc_reset(&enc);
        zeros=rand()%13==0;
        tell[0]=od_ec_enc_tell_frac(&enc);
        for(j=0; j<sz; j++) {
            if(zeros)data[j]=0;
            else data[j]=rand()%ft;
            od_ec_enc_uint(&enc,data[j],ft);
            tell[j+1]=od_ec_enc_tell_frac(&enc);
            if(rand()&7==0) {
                od_ec_enc_checkpoint(&enc_bak,&enc);
                od_ec_enc_uint(&enc,rand()&1?0:ft-1,ft);
                od_ec_enc_rollback(&enc,&enc_bak);
            }
        }
        if(!(rand()&1)) {
            while(od_ec_enc_tell(&enc)&7)od_ec_enc_uint(&enc,rand()&1,2);
        }
        tell_bits=od_ec_enc_tell(&enc);
        ptr=od_ec_enc_done(&enc,&ptr_sz);
        if(tell_bits!=(unsigned)od_ec_enc_tell(&enc)) {
            fprintf(stderr,"od_ec_enc_tell() changed after od_ec_enc_done(): "
                    "%u instead of %u (Random seed: %u).\n",
                    (unsigned)od_ec_enc_tell(&enc),tell_bits,seed);
            ret=EXIT_FAILURE;
        }
        if(tell_bits+7>>3<ptr_sz) {
            fprintf(stderr,"od_ec_enc_tell() lied: "
                    "there's %i bytes instead of %i (Random seed: %u).\n",
                    ptr_sz,tell_bits+7>>3,seed);
            ret=EXIT_FAILURE;
        }
        od_ec_dec_init(&dec,ptr,ptr_sz);
        if(od_ec_dec_tell_frac(&dec)!=tell[0]) {
            fprintf(stderr,"od_ec_dec_tell() mismatch between encoder and decoder "
                    "at symbol %i: %u instead of %u (Random seed: %u).\n",
                    0,(unsigned)od_ec_dec_tell_frac(&dec),tell[0],seed);
            ret=EXIT_FAILURE;
        }
        for(j=0; j<sz; j++) {
            sym=od_ec_dec_uint(&dec,ft);
            if(sym!=data[j]) {
                fprintf(stderr,"Decoded %i instead of %i with ft of %i "
                        "at position %i of %i (Random seed: %u).\n",
                        sym,data[j],ft,j,sz,seed);
                ret=EXIT_FAILURE;
            }
            if(od_ec_dec_tell_frac(&dec)!=tell[j+1]) {
                fprintf(stderr,"od_ec_dec_tell() mismatch between encoder and decoder "
                        "at symbol %i: %u instead of %u (Random seed: %u).\n",
                        j+1,(unsigned)od_ec_dec_tell_frac(&dec),tell[j+1],seed);
                ret=EXIT_FAILURE;
            }
        }
        free(tell);
        free(data);
    }
    /*Test compatibility between multiple different encode/decode routines.*/
    for(i=0; i<409600; i++) {
        unsigned *fz;
        unsigned *ftb;
        unsigned *data;
        unsigned *tell;
        unsigned *enc_method;
        int       j;
        sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
        fz=(unsigned *)malloc(sz*sizeof(*fz));
        ftb=(unsigned *)malloc(sz*sizeof(*ftb));
        data=(unsigned *)malloc(sz*sizeof(*data));
        tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
        enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
        od_ec_enc_reset(&enc);
        tell[0]=od_ec_enc_tell_frac(&enc);
        for(j=0; j<sz; j++) {
            data[j]=rand()/((RAND_MAX>>1)+1);
            ftb[j]=(rand()%15)+1;
            fz[j]=rand()%32766>>15-ftb[j];
            fz[j]=OD_MAXI(fz[j],1);
            enc_method[j]=rand()&1;
            switch(enc_method[j]) {
            case 0: {
                if(rand()&1)od_ec_encode_bool_q15(&enc,data[j],fz[j]<<15-ftb[j]);
                else od_ec_encode_bool(&enc,data[j],fz[j]<<15-ftb[j],32768);
            }
            break;
            case 1: {
                ogg_uint16_t cdf[2];
                cdf[0]=fz[j];
                cdf[1]=1U<<ftb[j];
                od_ec_encode_cdf_unscaled_dyadic(&enc,data[j],cdf,2,ftb[j]);
            }
            break;
            }
            tell[j+1]=od_ec_enc_tell_frac(&enc);
        }
        ptr=od_ec_enc_done(&enc,&ptr_sz);
        if(od_ec_enc_tell(&enc)+7U>>3<ptr_sz) {
            fprintf(stderr,"od_ec_enc_tell() lied: "
                    "there's %i bytes instead of %i (Random seed: %u).\n",
                    ptr_sz,od_ec_enc_tell(&enc)+7>>3,seed);
            ret=EXIT_FAILURE;
        }
        od_ec_dec_init(&dec,ptr,ptr_sz);
        if(od_ec_dec_tell_frac(&dec)!=tell[0]) {
            fprintf(stderr,"od_ec_dec_tell() mismatch between encoder and decoder "
                    "at symbol %i: %u instead of %u (Random seed: %u).\n",
                    0,(unsigned)od_ec_dec_tell_frac(&dec),tell[0],seed);
            ret=EXIT_FAILURE;
        }
        for(j=0; j<sz; j++) {
            int      dec_method;
            dec_method=rand()&1;
            switch(dec_method) {
            case 0: {
                if(rand()&1)sym=od_ec_decode_bool_q15(&dec,fz[j]<<15-ftb[j]);
                else sym=od_ec_decode_bool(&dec,fz[j]<<15-ftb[j],32768);
            }
            break;
            case 1: {
                ogg_uint16_t cdf[2];
                cdf[0]=fz[j];
                cdf[1]=1U<<ftb[j];
                sym=od_ec_decode_cdf_unscaled_dyadic(&dec,cdf,2,ftb[j]);
            }
            break;
            }
            if(sym!=data[j]) {
                fprintf(stderr,"Decoded %i instead of %i with fz=%i and ftb=%i "
                        "at position %i of %i (Random seed: %u).\n",
                        sym,data[j],fz[j],ftb[j],j,sz,seed);
                fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
                        enc_method[j],dec_method);
                ret=EXIT_FAILURE;
            }
            if(od_ec_dec_tell_frac(&dec)!=tell[j+1]) {
                fprintf(stderr,"od_ec_dec_tell() mismatch between encoder and decoder "
                        "at symbol %i: %u instead of %u (Random seed: %u).\n",
                        j+1,(unsigned)od_ec_dec_tell_frac(&dec),tell[j+1],seed);
                ret=EXIT_FAILURE;
            }
        }
        free(enc_method);
        free(tell);
        free(data);
        free(ftb);
        free(fz);
    }
    od_ec_enc_reset(&enc);
    od_ec_encode_bool_q15(&enc,0,16384);
    od_ec_encode_bool_q15(&enc,0,16384);
    od_ec_encode_bool_q15(&enc,0,16384);
    od_ec_encode_bool_q15(&enc,0,16384);
    od_ec_encode_bool_q15(&enc,0,24576);
    od_ec_enc_patch_initial_bits(&enc,3,2);
    if(enc.error) {
        fprintf(stderr,"od_ec_enc_patch_initial_bits() failed.\n");
        ret=EXIT_FAILURE;
    }
    od_ec_enc_patch_initial_bits(&enc,0,5);
    if(!enc.error) {
        fprintf(stderr,
                "od_ec_enc_patch_initial_bits() didn't fail when it should have.\n");
        ret=EXIT_FAILURE;
    }
    od_ec_enc_reset(&enc);
    od_ec_encode_bool_q15(&enc,0,16384);
    od_ec_encode_bool_q15(&enc,0,16384);
    od_ec_encode_bool_q15(&enc,1,32256);
    od_ec_encode_bool_q15(&enc,0,24576);
    od_ec_enc_patch_initial_bits(&enc,0,2);
    if(enc.error) {
        fprintf(stderr,"od_ec_enc_patch_initial_bits() failed.\n");
        ret=EXIT_FAILURE;
    }
    ptr=od_ec_enc_done(&enc,&ptr_sz);
    if(ptr_sz!=2||ptr[0]!=63) {
        fprintf(stderr,
                "Got %i when expecting 63 for od_ec_enc_patch_initial_bits().\n",ptr[0]);
        ret=EXIT_FAILURE;
    }
    od_ec_enc_clear(&enc);
    return ret;
}