From: "Gabriel Bouvigne" <[EMAIL PROTECTED]>
Subject: [MP3 ENCODER] today's idea
Date: Fri, 16 Jun 2000 23:55:52 +0200

> Here is today's idea for cbr encoding:
> 
> assuming we have to granules A and B, A got a distortion level of 0.1
> (arbitrary choosen unit) and B a distortion level of 0.6.
> 
> The idea would be in this case, as B got an high distortion, to requantize
> granule A in order to get, as an example, a distortion ratio of 0.3. This
> would save bits, and increase the bit reservoir for next granule, which then
> could have a distortion ratio of 0.4. So the idea would be in the case of a
> granule containing high or very high distortion to reduce the previous
> granule quality in order to get a more constant distortion ratio. However
> such a thing would increase buffering complexity.
> 
> What do you think about it?
> 

If we don't use reservoir much optimally, it may not be difficult.
Here is a quick hack of such adjustment.
Some parameters in this code are not the best value.

Iwasa Kazmi

/************************************************************************/
/*  iteration_loop()                                                    */
/************************************************************************/
void
iteration_loop( lame_global_flags *gfp,
                FLOAT8 pe[2][2], FLOAT8 ms_ener_ratio[2],
                FLOAT8 xr[2][2][576], III_psy_ratio ratio[2][2],
                int l3_enc[2][2][576],
                III_scalefac_t scalefac[2][2])
{
  lame_internal_flags *gfc=gfp->internal_flags;
  FLOAT8 xfsf[2][2][4][SBMAX_l];
  FLOAT8 noise[2][2][4]; /* over,max_noise,over_noise,tot_noise; */
  III_psy_xmin l3_xmin[2];
  gr_info *cod_info;
  int bitsPerFrame;
  int mean_bits,max_bits;
  int ch, gr, i, bit_rate;
  III_side_info_t *l3_side;
  FLOAT8 xr_save[2][2][576];
  int targ_bits[2][2];

  l3_side = &gfc->l3_side;

  iteration_init(gfp,l3_side,l3_enc);
  bit_rate = bitrate_table[gfp->version][gfc->bitrate_index];


  getframebits(gfp,&bitsPerFrame, &mean_bits);
  ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame );

  /* quantize! */




  for ( gr = 0; gr < gfc->mode_gr; gr++ ) {

    if (gfc->mode_ext==MPG_MD_MS_LR) 
      ms_convert(xr[gr], xr[gr]);
    
    max_bits=on_pe(gfp,pe,l3_side,targ_bits[gr],mean_bits, gr);

    if (gfc->mode_ext==MPG_MD_MS_LR) 
      reduce_side(targ_bits[gr],ms_ener_ratio[gr],mean_bits,max_bits);
  }

  memcpy(xr_save, xr, sizeof(xr_save));
    
  for (ch=0 ; ch < gfc->stereo ; ch ++) {
    int try_count = 0;
try:
    for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
      cod_info = &l3_side->gr[gr].ch[ch].tt;    
      if (!init_outer_loop(gfp,xr[gr][ch], cod_info))
        {
          /* xr contains no energy 
           * cod_info was set in init_outer_loop above
           */
          memset(&scalefac[gr][ch],0,sizeof(III_scalefac_t));
          memset(l3_enc[gr][ch],0,576*sizeof(int));
          memset(xfsf[gr][ch],0,sizeof(xfsf[gr][ch]));
          noise[gr][ch][0]=noise[gr][ch][1]=noise[gr][ch][2]=noise[gr][ch][3]=0;
        }
      else
        {
          int try_count = 0;
          calc_xmin(gfp,xr[gr][ch], &ratio[gr][ch], cod_info, &l3_xmin[ch]);
          outer_loop( gfp,xr[gr][ch], targ_bits[gr][ch], noise[gr][ch],
                      &l3_xmin[ch], l3_enc[gr][ch], 
                      &scalefac[gr][ch], cod_info, xfsf[gr][ch], ch);
        }
    }
    try_count++;
    if (gfc->mode_gr == 2 && try_count < 5)
      {
        FLOAT8 noise_d;
        noise_d= noise[0][ch][2] - noise[1][ch][2];
printf("gr noise balancing: %f\n", noise_d);
        if (noise_d > 0.6)
          {
            int bits;
            bits = targ_bits[1][ch] * 0.03;
            targ_bits[1][ch] -= bits;
            targ_bits[0][ch] += bits;
printf("gr noise balancing: try %d  (+%d) %f\n", try_count, bits, noise_d);
            memcpy(xr[0][ch], xr_save[0][ch], sizeof(FLOAT8)*576);
            memcpy(xr[1][ch], xr_save[1][ch], sizeof(FLOAT8)*576);
            goto try;
          }
        if (noise_d < -0.6)
          {
            int bits;
            bits = targ_bits[0][ch] * 0.03;
            targ_bits[0][ch] -= bits;
            targ_bits[1][ch] += bits;
printf("gr noise balancing: try %d  (-%d) %f\n", try_count, bits, noise_d);
            memcpy(xr[0][ch], xr_save[0][ch], sizeof(FLOAT8)*576);
            memcpy(xr[1][ch], xr_save[1][ch], sizeof(FLOAT8)*576);
            goto try;
          }
      }
  }

  for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
    for (ch=0 ; ch < gfc->stereo ; ch ++) {
      cod_info = &l3_side->gr[gr].ch[ch].tt;    
      best_scalefac_store(gfp,gr, ch, l3_enc, l3_side, scalefac);
      if (gfc->use_best_huffman==1 && cod_info->block_type != SHORT_TYPE) {
        best_huffman_divide(gfc, gr, ch, cod_info, l3_enc[gr][ch]);
      }
      assert((int)cod_info->part2_3_length < 4096);
      if (gfp->gtkflag)
        set_pinfo (gfp, cod_info, &ratio[gr][ch], &scalefac[gr][ch], xr[gr][ch], 
xfsf[gr][ch], noise[gr][ch], gr, ch);

#define NORES_TEST
#ifndef NORES_TEST
      ResvAdjust(gfp,cod_info, l3_side, mean_bits );
#endif
      /* set the sign of l3_enc */
      for ( i = 0; i < 576; i++) {
        if (xr[gr][ch][i] < 0)
          l3_enc[gr][ch][i] *= -1;
      }
    }
  } /* loop over gr */

#ifdef NORES_TEST
  /* replace ResvAdjust above with this code if you do not want
     the second granule to use bits saved by the first granule.
     when combined with --nores, this is usefull for testing only */
  for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
    for ( ch =  0; ch < gfc->stereo; ch++ ) {
        cod_info = &l3_side->gr[gr].ch[ch].tt;
        ResvAdjust(gfp, cod_info, l3_side, mean_bits );
    }
  }
#endif



  ResvFrameEnd(gfp,l3_side, mean_bits );
}

Reply via email to