[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