[svn] / branches / dev-api-4 / xvidcore / src / bitstream / mbcoding.c Repository:
ViewVC logotype

Diff of /branches/dev-api-4/xvidcore/src/bitstream/mbcoding.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1003, Sat May 3 19:11:58 2003 UTC revision 1032, Sat May 17 13:37:49 2003 UTC
# Line 738  Line 738 
738          if (frame->vol_flags & XVID_VOL_INTERLACING) {          if (frame->vol_flags & XVID_VOL_INTERLACING) {
739                  if (pMB->cbp) {                  if (pMB->cbp) {
740                          BitstreamPutBit(bs, pMB->field_dct);                          BitstreamPutBit(bs, pMB->field_dct);
741                          DPRINTF(DPRINTF_MB,"codep: field_dct: %i", pMB->field_dct);                          DPRINTF(XVID_DEBUG_MB,"codep: field_dct: %i", pMB->field_dct);
742                  }                  }
743    
744                  // if inter block, write field ME flag                  // if inter block, write field ME flag
745                  if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {                  if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
746                          BitstreamPutBit(bs, pMB->field_pred);                          BitstreamPutBit(bs, pMB->field_pred);
747                          DPRINTF(DPRINTF_MB,"codep: field_pred: %i", pMB->field_pred);                          DPRINTF(XVID_DEBUG_MB,"codep: field_pred: %i", pMB->field_pred);
748    
749                          // write field prediction references                          // write field prediction references
750                          if (pMB->field_pred) {                          if (pMB->field_pred) {
# Line 1162  Line 1162 
1162                  level = BitstreamGetBits(bs, 8);                  level = BitstreamGetBits(bs, 8);
1163    
1164                  if (level == 0 || level == 128)                  if (level == 0 || level == 128)
1165                          DPRINTF(DPRINTF_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d", level);                          DPRINTF(XVID_DEBUG_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d", level);
1166    
1167                  return (level << 24) >> 24;                  return (level << 24) >> 24;
1168          }          }
# Line 1218  Line 1218 
1218          do {          do {
1219                  level = get_coeff(bs, &run, &last, 1, 0);                  level = get_coeff(bs, &run, &last, 1, 0);
1220                  if (run == -1) {                  if (run == -1) {
1221                          DPRINTF(DPRINTF_ERROR,"fatal: invalid run");                          DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run");
1222                          break;                          break;
1223                  }                  }
1224                  coeff += run;                  coeff += run;
1225                  block[scan[coeff]] = level;                  block[scan[coeff]] = level;
1226    
1227                  DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[coeff], level);                  DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i", scan[coeff], level);
1228                  //DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32));                  //DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32));
1229    
1230                  if (level < -2047 || level > 2047) {                  if (level < -2047 || level > 2047) {
1231                          DPRINTF(DPRINTF_ERROR,"warning: intra_overflow %i", level);                          DPRINTF(XVID_DEBUG_ERROR,"warning: intra_overflow %i", level);
1232                  }                  }
1233                  coeff++;                  coeff++;
1234          } while (!last);          } while (!last);
# Line 1251  Line 1251 
1251          do {          do {
1252                  level = get_coeff(bs, &run, &last, 0, 0);                  level = get_coeff(bs, &run, &last, 0, 0);
1253                  if (run == -1) {                  if (run == -1) {
1254                          DPRINTF(DPRINTF_ERROR,"fatal: invalid run");                          DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run");
1255                          break;                          break;
1256                  }                  }
1257                  p += run;                  p += run;
1258    
1259                  block[scan[p]] = level;                  block[scan[p]] = level;
1260    
1261                  DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[p], level);                  DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i", scan[p], level);
1262                  // DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[p], level, BitstreamShowBits(bs, 32));                  // DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i %08x", scan[p], level, BitstreamShowBits(bs, 32));
1263    
1264                  if (level < -2047 || level > 2047) {                  if (level < -2047 || level > 2047) {
1265                          DPRINTF(DPRINTF_ERROR,"warning: inter overflow %i", level);                          DPRINTF(XVID_DEBUG_ERROR,"warning: inter overflow %i", level);
1266                  }                  }
1267                  p++;                  p++;
1268          } while (!last);          } while (!last);
# Line 1270  Line 1270 
1270  }  }
1271    
1272    
   
   
   
   
   
 /************************************************************************  
  *               Trellis based R-D optimal quantization                 *  
  *  not really "bitstream" or "mbcoding" related, but needs VLC tables  *  
  *                                                                      *  
  ************************************************************************/  
   
   
 int __inline  
 RunLevel_CalcBits_inter(const int16_t run, int16_t level)  
 {  
         const int esc_length = 30;  
   
         if (!((level+32) & -64))  
                 return coeff_VLC[0][0][level+32][run].len;  
         else  
                 return esc_length;  
 }  
   
 int __inline  
 RunLevelLast_CalcBits_inter(const int16_t run, const int16_t level)  
 {  
         const int esc_length = 30;  
   
         if (!((level+32) & -64))  
                 return coeff_VLC[0][1][level+32][run].len;  
         else  
                 return esc_length;  
 }  
   
   
 int __inline  
 RunLevel_CalcBits_intra(const int16_t run, int16_t level)  
 {  
         const int esc_length = 30;  
         int bits;  
   
         level = abs(level);  
         if (!(level & -64)) {  
                 bits = coeff_VLC[1][0][level][run].len;  
                 if (bits!=128)  
                         return bits;  
         }  
         return esc_length;  
 }  
   
 int __inline  
 RunLevelLast_CalcBits_intra(const int16_t run, int16_t level)  
 {  
         const int esc_length = 30;  
         int bits;  
   
         level = abs(level);  
         if (!(level & -64)) {  
                 bits = coeff_VLC[1][1][level][run].len;  
                 if (bits!=128)  
                         return bits;  
         }  
         return esc_length;  
 }  
   
 /* based on ffmpeg's trellis quant, thanks! */  
 /* (C) 2003 Michael Niedermayer <michaelni@gmx.at> */  
   
 int  
 dct_quantize_trellis_inter_h263_c (int16_t *qcoeff, const int16_t *data, int quant)  
 {  
   
 /* input: original quantized DCT coefficients (to calc distorion)*/  
 /*                already quantized DCT coefficients */  
 /*                quantizer */  
 /* output: modified table of quantized DCT coefficients */  
   
 /* maybe combining quantize&Trellis would be faster (even that it disables MMX quant) */  
   
   int run_tab[65];  
   int level_tab[65];  
   int score_tab[65];  
   int last_run = 0;  
   int last_level = 0;  
   int last_score = 0;  
   int last_i = 0;  
   int coeff[64];  
   int coeff_count[64];  /* is a table useful for this 0-1 (or 1-2) table? */  
   int last_non_zero, i;  
   
   const uint16_t *const zigzag = &scan_tables[0][0];  
         /* ordinary zigzag order, so it's not INTERLACE compatible, yet  */  
   
   const int qmul = 2*quant;  
   const int qadd = ((quant-1)|1);  
   
 /* quant is not needed anymore after this */  
   
   int score_limit = 0;  
   int left_limit = 0;  
   
   const int lambda = (quant * quant * 123 + 64) >> 7;   // default lagrangian  
   
 /*  control lambda through a ENVIRONMENT variable (for automatic optmization) */  
   
 /*  
   const int lfact=123;  // better control of the lagrangian lambda  
   int lambda = (quant * quant * 123 + 64) >> 7; // default lagrangian  
   
   const char * const trellis_lambda = getenv("TRELLIS_LAMBDA");  
   if(trellis_lambda)  
                 lfact = atoi(trellis_lambda);  
   if (lfact < 1)  
         lfact = 123;    // why this value? Who knows? But 123 seems better than 109 = 0.85<<7  
   
   lambda = (quant * quant * lfact + 64) >> 7;   // lagrangian  
 */  
   
   last_non_zero = -1;  
   for (i = 0; i < 64; i++)  
     {  
       const int level = qcoeff[zigzag[i]];  
   
                 if (level) {  
                         last_non_zero = i;  
   
                         if (level>0) {  
                                 if (level==1) {  
                                         coeff[i] = 1;  
                                         coeff_count[i] = 0;  
                                 } else {  
                                         coeff[i] = level;  
                                         coeff_count[i] = 1;  
                                 }  
                         } else {  
                                 if (level==-1) {  
                                         coeff[i] = -1;  
                                         coeff_count[i] = 0;  
                                 } else {  
                                         coeff[i] = level+1;     // because we check coeff[i] and coeff[i]-1  
                                         coeff_count[i] = 1;  
                                 }  
                         }  
             } else {  
                         coeff[i] = ((data[zigzag[i]]>>31)|1); /* +- 1 because of gap */  
                         coeff_count[i] = 0;  
                 }  
     }  
   
   if (last_non_zero < 0)  
       return last_non_zero;  
   
   score_tab[0] = 0;  
   
   for (i = 0; i <= last_non_zero; i++) {  
     int level, run, j;  
     const int dct_coeff = data[zigzag[i]];  
     const int zero_distortion = dct_coeff * dct_coeff;  
     int best_score = 256 * 256 * 256 * 120;  
   
         int distortion;  
         int dequant_err;  
   
         last_score += zero_distortion;  
   
   
 /****************** level loop unrolled: first check coeff[i] *********/  
     level = coeff[i];  
   
         if (level > 0)  // coeff[i]==0 is not possible here  
                 dequant_err = level * qmul + qadd - dct_coeff;  
         else  
                 dequant_err = level * qmul - qadd - dct_coeff;  
   
         distortion = dequant_err*dequant_err;  
   
         for (run = 0; run <= i - left_limit; run++) {  
   
           int score = distortion + lambda*RunLevel_CalcBits_inter(run, level) + score_tab[i - run];  
   
           if (score < best_score)  
             {  
               best_score = score_tab[i + 1] = score;  
               run_tab[i + 1] = run;  
               level_tab[i + 1] = level;  
             }  
         }  
   
         for (run = 0; run <= i - left_limit; run++) {  
           int score = distortion + lambda*RunLevelLast_CalcBits_inter(run, level) + score_tab[i - run];  
   
       if (score < last_score)  
                 {  
                   last_score = score;  
                   last_run = run;  
                   last_level = level;  
                   last_i = i + 1;  
                 }  
     }  
   
 /****************** level loop unrolled: if possible, check coeff[i]-1 *********/  
   
     if (coeff_count[i]) {  
   
                 level--;  
                 dequant_err -= qmul;  
                 distortion = dequant_err*dequant_err;  
   
                 for (run = 0; run <= i - left_limit; run++) {  
                   int score = distortion + lambda*RunLevel_CalcBits_inter(run, level) + score_tab[i-run];  
   
                   if (score < best_score)  
                     {  
                       best_score = score_tab[i + 1] = score;  
                       run_tab[i + 1] = run;  
                       level_tab[i + 1] = level;  
                     }  
                 }  
   
           for (run = 0; run <= i - left_limit; run++) {  
                   int score = distortion + lambda*RunLevelLast_CalcBits_inter(run, level) + score_tab[i-run];  
   
               if (score < last_score)  
                         {  
                           last_score = score;  
                           last_run = run;  
                           last_level = level;  
                           last_i = i + 1;  
                         }  
   
             }  
         } // of check coeff[i]-1  
   
   
 /****************** checking coeff[i]-2 doesn't isn't supported  *********/  
   
 /****************** add distorsion for higher RUN (-> coeff[i]==0) *******/  
     for (j = left_limit; j <= i; j++)  
           score_tab[j] += zero_distortion;  
   
     score_limit += zero_distortion;  
   
     if (score_tab[i + 1] < score_limit)  
           score_limit = score_tab[i + 1];  
   
  // there is a vlc code in mpeg4 which is 1 bit shorter then another one with a shorter run and the same level  
  // so we finalize only if we have no chance of getting lower than  score_limit + 1*lambda   anymore  
   
         while (score_tab[left_limit] > score_limit + lambda)  
           left_limit++;  
   
   
   } // end of (i=0;i<=last_non_zero;i++)  
   
   last_non_zero = last_i - 1;  
   if (last_non_zero < 0)  
     return last_non_zero;  
   
   i = last_i;  
   
   memset(qcoeff,0x00,64*sizeof(int16_t));  
   
   qcoeff[zigzag[last_non_zero]] = last_level;  
   i -= last_run + 1;  
   
   for (; i > 0; i -= run_tab[i] + 1)  
     {  
       qcoeff[zigzag[i-1]] = level_tab[i];  
     }  
   
   return last_non_zero;  
 }  
   
 int  
 dct_quantize_trellis_inter_mpeg_c (int16_t *qcoeff, const int16_t *data, int quant)  
 { return 64; }  
   
   
   
   
   
1273  /*****************************************************************************  /*****************************************************************************
1274   * VLC tables and other constant arrays   * VLC tables and other constant arrays
1275   ****************************************************************************/   ****************************************************************************/

Legend:
Removed from v.1003  
changed lines
  Added in v.1032

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4