Exemplo n.º 1
0
/** Encodes a single vector of integers (eg, a partition within a
 *  coefficient block) using PVQ
 *
 * @param [in,out] ec         range encoder
 * @param [in]     qg         quantized gain
 * @param [in]     theta      quantized post-prediction theta
 * @param [in]     max_theta  maximum possible quantized theta value
 * @param [in]     in         coefficient vector to code
 * @param [in]     n          number of coefficients in partition
 * @param [in]     k          number of pulses in partition
 * @param [in,out] model      entropy encoder state
 * @param [in,out] adapt      adaptation context
 * @param [in,out] exg        ExQ16 expectation of gain value
 * @param [in,out] ext        ExQ16 expectation of theta value
 * @param [in]     nodesync   do not use info that depend on the reference
 * @param [in]     cdf_ctx    selects which cdf context to use
 * @param [in]     is_keyframe whether we're encoding a keyframe
 * @param [in]     code_skip  whether the "skip rest" flag is allowed
 * @param [in]     skip_rest  when set, we skip all higher bands
 * @param [in]     encode_flip whether we need to encode the CfL flip flag now
 * @param [in]     flip       value of the CfL flip flag
 */
static void pvq_encode_partition(od_ec_enc *ec,
                                 int qg,
                                 int theta,
                                 int max_theta,
                                 const od_coeff *in,
                                 int n,
                                 int k,
                                 generic_encoder model[3],
                                 od_adapt_ctx *adapt,
                                 int *exg,
                                 int *ext,
                                 int nodesync,
                                 int cdf_ctx,
                                 int is_keyframe,
                                 int code_skip,
                                 int skip_rest,
                                 int encode_flip,
                                 int flip) {
  int noref;
  int id;
  noref = (theta == -1);
  id = (qg > 0) + 2*OD_MINI(theta + 1,3) + 8*code_skip*skip_rest;
  if (is_keyframe) {
    OD_ASSERT(id != 8);
    if (id >= 8) id--;
  }
  else {
    OD_ASSERT(id != 10);
    if (id >= 10) id--;
  }
  /* Jointly code gain, theta and noref for small values. Then we handle
     larger gain and theta values. For noref, theta = -1. */
  od_encode_cdf_adapt(ec, id, &adapt->pvq.pvq_gaintheta_cdf[cdf_ctx][0],
   8 + 7*code_skip, adapt->pvq.pvq_gaintheta_increment);
  if (encode_flip) {
    /* We could eventually do some smarter entropy coding here, but it would
       have to be good enough to overcome the overhead of the entropy coder.
       An early attempt using a "toogle" flag with simple adaptation wasn't
       worth the trouble. */
    od_ec_enc_bits(ec, flip, 1);
  }
  if (qg > 0) {
    int tmp;
    tmp = *exg;
    generic_encode(ec, &model[!noref], qg - 1, -1, &tmp, 2);
    OD_IIR_DIADIC(*exg, qg << 16, 2);
  }
  if (theta > 1 && (nodesync || max_theta > 3)) {
    int tmp;
    tmp = *ext;
    generic_encode(ec, &model[2], theta - 2, nodesync ? -1 : max_theta - 3,
     &tmp, 2);
    OD_IIR_DIADIC(*ext, theta << 16, 2);
  }
  od_encode_pvq_codeword(ec, &adapt->pvq.pvq_codeword_ctx, in,
   n - (theta != -1), k);
}
Exemplo n.º 2
0
Arquivo: ectest.c Projeto: kbara/daala
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;
}
Exemplo n.º 3
0
static void od_encode_pvq_codeword(od_ec_enc *ec, od_pvq_codeword_ctx *adapt,
 const od_coeff *in, int n, int k) {
  int i;
  od_encode_band_pvq_splits(ec, adapt, in, n, k, 0);
  for (i = 0; i < n; i++) if (in[i]) od_ec_enc_bits(ec, in[i] < 0, 1);
}