[FFmpeg-soc] [soc]: r2411 - in nellyenc: checkout.sh ffmpeg.patch nellymoserenc.c

Benjamin Larsson banan at ludd.ltu.se
Wed Jun 11 11:28:06 CEST 2008


bwolowiec wrote:
> Author: bwolowiec
> Date: Sun Jun  8 23:33:15 2008
> New Revision: 2411
>
> Log:
> initial commit: simple nellymoser encoder. It's slow and has average quality of sound.
>   

[...]

> +
> +static void encode_block(NellyMoserEncodeContext *s,
> +        unsigned char *buf, int buf_size, int16_t *samples){
> +    PutBitContext2 pb;
> +    int bits[NELLY_BUF_LEN];
> +    int i, j, k, l, b;
> +    int bs, bk;
> +    float pows[NELLY_FILL_LEN];
> +    float *bptr, val;
> +    float pval;
> +    float best, tmp, stmp;
> +    int off[NELLY_BANDS], base; // -1
> +    float ss=1./1.;
> +    float scale=1./1.;
> +
> +    for(i=0; i<NELLY_BUF_LEN*3; i++){
> +        s->float_buf[i] = samples[i]*ss;
> +    }
> +    apply_mdct(s, s->float_buf, s->mdct_out);
> +    apply_mdct(s, s->float_buf+NELLY_BUF_LEN, s->mdct_out+NELLY_BUF_LEN);
>   

I think you should set the last 4 samples to 0 in each mdct buffer. The 
last coeffs aren't coded.

> +
> +    for(i=0; i<NELLY_SAMPLES; i++){
> +        av_log(s->avctx, AV_LOG_DEBUG, "%3i: %f (%f)\n", i, s->mdct_out[i],
> +                s->float_buf[i]);
> +    }
> +
> +    init_put_bits2(&pb, buf, buf_size*8);
> +
> +    /* FIXME: use better (fast) algorithm... */
>   

Please describe the algorithms you use.

> +    best = 1e10;
> +    bk = 0;
> +    for(k=0; k<64; k++){
> +        pval = pow(2,(ff_nelly_init_table[k])/2048) * scale;
> +        tmp = fabs(((s->mdct_out[0]+s->mdct_out[1])/2)/(pval));
> +        if(tmp<1) tmp = 1/tmp;
> +        if(best > tmp){
> +            bk = k;
> +            best = tmp;
> +        }
> +    }
> +
> +    av_log(s->avctx, AV_LOG_DEBUG, "base_best=%f\n", best  );
> +
> +    base = bk;
> +    put_bits2(&pb, 6, base);
> +    j=0;
> +
> +    val = ff_nelly_init_table[base];
> +    for(i=0; i<NELLY_BANDS; i++){
> +        if (i > 0){
> +            /* FIXME: use better (fast) algorithm... */
> +            best = 1e10;
> +            bk = 0;
> +            for(k=0; k<32; k++){
> +                stmp = 0;
> +                pval = pow(2,(val+ff_nelly_delta_table[k])/2048) * scale;
> +
> +                for(b=0; b<2; b++){
> +                    for(l=0; l<ff_nelly_band_sizes_table[i]; l++){
> +                        tmp = fabs(s->mdct_out[j+l+b*NELLY_BUF_LEN]/(pval));
> +                        if(tmp<0.90) tmp=0.90;
> +                        if(tmp<1) tmp = 1/tmp;
> +                        if(tmp>5) tmp=5;
> +                    }
> +                    stmp += tmp*tmp;
> +                }
> +
> +
> +                if(best > stmp){
> +                    bk = k;
> +                    best = stmp;
> +                }
> +            }
> +            av_log(s->avctx, AV_LOG_DEBUG, "best=%f\n", best  );
> +            off[i] = bk;
> +            put_bits2(&pb, 5, off[i]); // [5] -> -1
> +            j+=ff_nelly_band_sizes_table[i];
> +            val += ff_nelly_delta_table[off[i]];
> +        }
> +    }
> +
> +    val = ff_nelly_init_table[base];
> +    bptr = pows;
> +    for (i=0 ; i<NELLY_BANDS ; i++) {
> +        if (i > 0)
> +            val += ff_nelly_delta_table[off[i]];
> +        for (j = 0; j < ff_nelly_band_sizes_table[i]; j++) {
> +            *bptr++ = val;
> +            av_log(s->avctx, AV_LOG_DEBUG, " exp: %f\n",
> +                -pow(2,val/2048.)*scale);
> +        }
> +    }
> +
> +    ff_nelly_get_sample_bits(pows, bits);
>   

This function should be renamed to bitallocation 
(ff_nelly_get_bitallocation).
> +
> +    bs=0;
> +    for (i = 0; i < 2; i++) { //2
> +
> +        for (j = 0; j < NELLY_FILL_LEN; j++) {
> +            bs+=bits[j];
> +            if (bits[j] > 0) {
> +                /* FIXME: use better (fast) algorithm... */
> +                av_log(s->avctx, AV_LOG_DEBUG, "bits=%i\n", bits[j]);
> +                pval = -pow(2, pows[j]/2048)*scale;
> +                av_log(s->avctx, AV_LOG_DEBUG, "pval=%f\n", pval);
> +                best = 1e10;
> +                bk = 0;
> +                for(k=0; k<(1<<bits[j]); k++){
> +                    tmp = s->mdct_out[i*NELLY_BUF_LEN + j]
> +                        /(ff_nelly_dequantization_table[(1<<bits[j])-1+k]*pval);
> +                    if(tmp<0) continue;
> +                    if(tmp<1) tmp = 1/tmp;
> +                    if(best > tmp){
> +                        bk = k;
> +                        best = tmp;
> +                    }
> +                }
> +                av_log(s->avctx, AV_LOG_DEBUG, "bk=%3i best_deq=%f send=%f\n",
> +                        bk,
> +                        best,
> +                        (ff_nelly_dequantization_table[(1<<bits[j])-1+bk]*pval)
> +                      );
> +                put_bits2(&pb, bits[j], bk);
> +            }
> +        }
> +        av_log(s->avctx, AV_LOG_DEBUG, "count=%i (%i)\n",
> +                put_bits2_count(&pb),
> +                NELLY_HEADER_BITS + NELLY_DETAIL_BITS
> +                );
> +        if(!i)
> +            put_bits2(&pb, NELLY_HEADER_BITS + NELLY_DETAIL_BITS - put_bits2_count(&pb) , 0);
> +
> +        av_log(s->avctx, AV_LOG_DEBUG, "count=%i (%i)\n",
> +                put_bits2_count(&pb),
> +                NELLY_HEADER_BITS + NELLY_DETAIL_BITS
> +                );
> +    }
> +
> +    av_log(s->avctx, AV_LOG_DEBUG, "bs=%i\n", bs);
> +}
>   
It's nice to see a working encoder. Now we need to understand the format 
better so we can optimize the implementation. So start document the 
format, that way we will be able to figure out how to optimally encode.

MvH
Benjamin Larsson





More information about the FFmpeg-soc mailing list