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

Diff of /branches/dev-api-4/xvidcore/src/utils/mbtransquant.c

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

revision 1223, Sun Nov 23 17:01:08 2003 UTC revision 1230, Sun Nov 30 16:13:16 2003 UTC
# Line 21  Line 21 
21   *  along with this program ; if not, write to the Free Software   *  along with this program ; if not, write to the Free Software
22   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23   *   *
24   * $Id: mbtransquant.c,v 1.21.2.19 2003-11-23 17:01:08 edgomez Exp $   * $Id: mbtransquant.c,v 1.21.2.21 2003-11-30 16:13:16 edgomez Exp $
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
# Line 138  Line 138 
138    
139          /* Quantize the block */          /* Quantize the block */
140          start_timer();          start_timer();
141          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum);          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
142          quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum);          quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
143          quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum);          quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
144          quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum);          quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145          quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr);          quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
146          quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr);          quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
147          stop_quant_timer();          stop_quant_timer();
148  }  }
149    
# Line 168  Line 168 
168          scaler_chr = get_dc_scaler(iQuant, 0);          scaler_chr = get_dc_scaler(iQuant, 0);
169    
170          start_timer();          start_timer();
171          dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum);          dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
172          dequant[mpeg](&qcoeff[1 * 64], &data[1 * 64], iQuant, scaler_lum);          dequant[mpeg](&qcoeff[1 * 64], &data[1 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
173          dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum);          dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
174          dequant[mpeg](&qcoeff[3 * 64], &data[3 * 64], iQuant, scaler_lum);          dequant[mpeg](&qcoeff[3 * 64], &data[3 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
175          dequant[mpeg](&qcoeff[4 * 64], &data[4 * 64], iQuant, scaler_chr);          dequant[mpeg](&qcoeff[4 * 64], &data[4 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
176          dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr);          dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
177          stop_iquant_timer();          stop_iquant_timer();
178  }  }
179    
# Line 214  Line 214 
214                  /* Quantize the block */                  /* Quantize the block */
215                  start_timer();                  start_timer();
216    
217                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant);                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);
218    
219                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
220                            const uint16_t *matrix;
221                          const static uint16_t h263matrix[] =                          const static uint16_t h263matrix[] =
222                                  {                                  {
223                                          16, 16, 16, 16, 16, 16, 16, 16,                                          16, 16, 16, 16, 16, 16, 16, 16,
# Line 228  Line 229 
229                                          16, 16, 16, 16, 16, 16, 16, 16,                                          16, 16, 16, 16, 16, 16, 16, 16,
230                                          16, 16, 16, 16, 16, 16, 16, 16                                          16, 16, 16, 16, 16, 16, 16, 16
231                                  };                                  };
232    
233                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
234                          sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],                          sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
235                                                                                   pMB->quant, &scan_tables[0][0],                                                                                   pMB->quant, &scan_tables[0][0],
236                                                                                   (mpeg)?(uint16_t*)get_inter_matrix():h263matrix,                                                                                   matrix,
237                                                                                   63);                                                                                   63);
238                  }                  }
239                  stop_quant_timer();                  stop_quant_timer();
# Line 281  Line 284 
284          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
285    
286          start_timer();          start_timer();
287          if(cbp & (1 << (5 - 0))) dequant[mpeg](&data[0 * 64], &qcoeff[0 * 64], iQuant);          if(cbp & (1 << (5 - 0))) dequant[mpeg](&data[0 * 64], &qcoeff[0 * 64], iQuant, pParam->mpeg_quant_matrices);
288          if(cbp & (1 << (5 - 1))) dequant[mpeg](&data[1 * 64], &qcoeff[1 * 64], iQuant);          if(cbp & (1 << (5 - 1))) dequant[mpeg](&data[1 * 64], &qcoeff[1 * 64], iQuant, pParam->mpeg_quant_matrices);
289          if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant);          if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant, pParam->mpeg_quant_matrices);
290          if(cbp & (1 << (5 - 3))) dequant[mpeg](&data[3 * 64], &qcoeff[3 * 64], iQuant);          if(cbp & (1 << (5 - 3))) dequant[mpeg](&data[3 * 64], &qcoeff[3 * 64], iQuant, pParam->mpeg_quant_matrices);
291          if(cbp & (1 << (5 - 4))) dequant[mpeg](&data[4 * 64], &qcoeff[4 * 64], iQuant);          if(cbp & (1 << (5 - 4))) dequant[mpeg](&data[4 * 64], &qcoeff[4 * 64], iQuant, pParam->mpeg_quant_matrices);
292          if(cbp & (1 << (5 - 5))) dequant[mpeg](&data[5 * 64], &qcoeff[5 * 64], iQuant);          if(cbp & (1 << (5 - 5))) dequant[mpeg](&data[5 * 64], &qcoeff[5 * 64], iQuant, pParam->mpeg_quant_matrices);
293          stop_iquant_timer();          stop_iquant_timer();
294  }  }
295    
# Line 647  Line 650 
650   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
651   *   *
652   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
653   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
654   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
655   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
656   * without using a heap, since the open frontier of the DAG is always   * without using a heap, since the open frontier of the DAG is always
657   * known, and of fixed sized.   * known, and of fixed size.
658   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
659    
660    
# Line 799  Line 802 
802                                             int Non_Zero)                                             int Non_Zero)
803  {  {
804    
805      /*          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
806           * Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),           * (In[]), not quantized one (Out[]). However, it only improves the result
807           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
808           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
809           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
810          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
811    
812          NODE Nodes[65], Last;          NODE Nodes[65], Last;
813          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
814          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
815    
816          const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */          /* it's 1/lambda, actually */
817            const int Lambda = Trellis_Lambda_Tabs[Q-1];
818    
819          int Run_Start = -1;          int Run_Start = -1;
820          uint32_t Min_Cost = 2<<TL_SHIFT;          uint32_t Min_Cost = 2<<TL_SHIFT;
# Line 820  Line 823 
823          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
824    
825          int i, j, sum;          int i, j, sum;
826          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */  
827            /* source (w/ CBP penalty) */
828            Run_Costs[-1] = 2<<TL_SHIFT;
829    
830          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
831          if (Non_Zero<0)          if (Non_Zero<0)
# Line 860  Line 865 
865                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
866                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
867    
868                                  /*                                  /* TODO: what about tie-breaks? Should we favor short runs or
                                  * TODO: what about tie-breaks? Should we favor short runs or  
869                                   * long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
870                                   * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                                  */  
871    
872                                  /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
873    
874                                  if (Cost<Best_Cost) {                                  if (Cost<Best_Cost) {
875                                          Best_Cost    = Cost;                                          Best_Cost    = Cost;
# Line 881  Line 884 
884                          }                          }
885                          if (Last_Node==i)                          if (Last_Node==i)
886                                  Last.Level = Nodes[i].Level;                                  Last.Level = Nodes[i].Level;
887                  } else { /* "big" levels */                  } else if (51U>(uint32_t)(Level1+25)) {
888                            /* "big" levels (not less than ESC3, though) */
889                          const uint8_t *Tbl_L1, *Tbl_L2, *Tbl_L1_Last, *Tbl_L2_Last;                          const uint8_t *Tbl_L1, *Tbl_L2, *Tbl_L1_Last, *Tbl_L2_Last;
890                          int Level2;                          int Level2;
891                          int dQ1, dQ2;                          int dQ1, dQ2;
# Line 917  Line 921 
921                                  uint32_t Cost1, Cost2;                                  uint32_t Cost1, Cost2;
922                                  int bLevel;                                  int bLevel;
923    
924                                  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
925                                   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
926                                   *      if (Cost_Base>=Best_Cost) continue;                                   *      if (Cost_Base>=Best_Cost) continue;
927                                   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
                                  */  
928    
929                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
930                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
# Line 956  Line 959 
959                                          Last_Node  = i;                                          Last_Node  = i;
960                                  }                                  }
961                          } /* end of "for Run" */                          } /* end of "for Run" */
962                    } else {
963                            /* Very very high levels, with no chance of being optimizable
964                             * => Simply pick best Run. */
965                            int Run;
966                            for(Run=i-Run_Start; Run>0; --Run) {
967                                    /* 30 bits + no distortion */
968                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
969                                    if (Cost<Best_Cost) {
970                                            Best_Cost = Cost;
971                                            Nodes[i].Run   = Run;
972                                            Nodes[i].Level = Level1;
973                                    }
974    
975                                    if (Cost<Last_Cost) {
976                                            Last_Cost  = Cost;
977                                            Last.Run   = Run;
978                                            Last.Level = Level1;
979                                            Last_Node  = i;
980                                    }
981                  }                  }
982                    }
983    
984    
985                  Run_Costs[i] = Best_Cost;                  Run_Costs[i] = Best_Cost;
986    
# Line 965  Line 988 
988                          Min_Cost = Best_Cost;                          Min_Cost = Best_Cost;
989                          Run_Start = i;                          Run_Start = i;
990                  } else {                  } else {
991                          /*                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
992                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * there's a code shorter by 1 bit for a larger run (!), same
993                           * a code shorter by 1 bit for a larger run (!), same level. We give                           * level. We give it a chance by not moving the left barrier too
994                           * it a chance by not moving the left barrier too much.                           * much. */
                          */  
   
995                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
996                                  Run_Start++;                                  Run_Start++;
997    
998                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
999                             * one */
1000                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1001                          Min_Cost += Dist0;                          Min_Cost += Dist0;
1002                  }                  }
1003          }          }
1004    
1005          /* It seems trellis doesn't give good results... just compute the Out sum and          /* It seems trellis doesn't give good results... just compute the Out sum
1006           * quit (even if we did not modify it, upperlayer relies on this data) */           * and quit */
1007          if (Last_Node<0)          if (Last_Node<0)
1008                  return Compute_Sum(Out, Non_Zero);                  return Compute_Sum(Out, Non_Zero);
1009    

Legend:
Removed from v.1223  
changed lines
  Added in v.1230

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