[cvs] / xvidcore / src / utils / mbtransquant.c Repository:
ViewVC logotype

Diff of /xvidcore/src/utils/mbtransquant.c

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

revision 1.21.2.22, Mon Dec 1 10:46:40 2003 UTC revision 1.33, Sun Nov 28 15:18:21 2010 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /*****************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - MB Transfert/Quantization functions -   *  - MB Transfer/Quantization functions -
5   *   *
6   *  Copyright(C) 2001-2003  Peter Ross <pross@xvid.org>   *  Copyright(C) 2001-2010  Peter Ross <pross@xvid.org>
7   *               2001-2003  Michael Militzer <isibaar@xvid.org>   *               2001-2010  Michael Militzer <michael@xvid.org>
8   *               2003       Edouard Gomez <ed.gomez@free.fr>   *               2003       Edouard Gomez <ed.gomez@free.fr>
9   *   *
10   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
# Line 40  Line 40 
40  #include "../dct/fdct.h"  #include "../dct/fdct.h"
41  #include "../dct/idct.h"  #include "../dct/idct.h"
42  #include "../quant/quant.h"  #include "../quant/quant.h"
43    #include "../motion/sad.h"
44  #include "../encoder.h"  #include "../encoder.h"
45    
 #include "../image/reduced.h"  
46  #include  "../quant/quant_matrix.h"  #include  "../quant/quant_matrix.h"
47    
48  MBFIELDTEST_PTR MBFieldTest;  MBFIELDTEST_PTR MBFieldTest;
# Line 91  Line 91 
91    
92          /* Perform DCT */          /* Perform DCT */
93          start_timer();          start_timer();
94          fdct(&data[0 * 64]);          fdct((short * const)&data[0 * 64]);
95          fdct(&data[1 * 64]);          fdct((short * const)&data[1 * 64]);
96          fdct(&data[2 * 64]);          fdct((short * const)&data[2 * 64]);
97          fdct(&data[3 * 64]);          fdct((short * const)&data[3 * 64]);
98          fdct(&data[4 * 64]);          fdct((short * const)&data[4 * 64]);
99          fdct(&data[5 * 64]);          fdct((short * const)&data[5 * 64]);
100          stop_dct_timer();          stop_dct_timer();
101  }  }
102    
# Line 106  Line 106 
106             const uint8_t cbp)             const uint8_t cbp)
107  {  {
108          start_timer();          start_timer();
109          if(cbp & (1 << (5 - 0))) idct(&data[0 * 64]);          if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]);
110          if(cbp & (1 << (5 - 1))) idct(&data[1 * 64]);          if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]);
111          if(cbp & (1 << (5 - 2))) idct(&data[2 * 64]);          if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]);
112          if(cbp & (1 << (5 - 3))) idct(&data[3 * 64]);          if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]);
113          if(cbp & (1 << (5 - 4))) idct(&data[4 * 64]);          if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]);
114          if(cbp & (1 << (5 - 5))) idct(&data[5 * 64]);          if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]);
115          stop_idct_timer();          stop_idct_timer();
116  }  }
117    
# Line 123  Line 123 
123                           int16_t qcoeff[6 * 64],                           int16_t qcoeff[6 * 64],
124                           int16_t data[6*64])                           int16_t data[6*64])
125  {  {
         int mpeg;  
126          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
127            quant_intraFuncPtr quant;
128    
129          quant_intraFuncPtr const quant[2] =          /* check if quant matrices need to be re-initialized with new quant */
130                  {          if (pParam->vol_flags & XVID_VOL_MPEGQUANT) {
131                          quant_h263_intra,                  if (pParam->last_quant_initialized_intra != pMB->quant) {
132                          quant_mpeg_intra                          init_intra_matrix(pParam->mpeg_quant_matrices, pMB->quant);
133                  };                  }
134                    quant = quant_mpeg_intra;
135            } else {
136                    quant = quant_h263_intra;
137            }
138    
         mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);  
139          scaler_lum = get_dc_scaler(pMB->quant, 1);          scaler_lum = get_dc_scaler(pMB->quant, 1);
140          scaler_chr = get_dc_scaler(pMB->quant, 0);          scaler_chr = get_dc_scaler(pMB->quant, 0);
141    
142          /* Quantize the block */          /* Quantize the block */
143          start_timer();          start_timer();
144          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);          quant(&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145          quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);          quant(&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
146          quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);          quant(&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
147          quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);          quant(&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
148          quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);          quant(&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
149          quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);          quant(&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
150          stop_quant_timer();          stop_quant_timer();
151  }  }
152    
# Line 183  Line 186 
186                                             int Q,                                             int Q,
187                                             const uint16_t * const Zigzag,                                             const uint16_t * const Zigzag,
188                                             const uint16_t * const QuantMatrix,                                             const uint16_t * const QuantMatrix,
189                                             int Non_Zero);                                             int Non_Zero,
190                                               int Sum,
191                                               int Lambda_Mod,
192                                               const uint32_t rel_var8,
193                                               const int Metric);
194    
195  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
196  static __inline uint8_t  static __inline uint8_t
# Line 216  Line 223 
223    
224                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);
225    
226                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {                  if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
227                          const uint16_t *matrix;                          const uint16_t *matrix;
228                          const static uint16_t h263matrix[] =                          const static uint16_t h263matrix[] =
229                                  {                                  {
# Line 234  Line 241 
241                          sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],                          sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
242                                                                                   pMB->quant, &scan_tables[0][0],                                                                                   pMB->quant, &scan_tables[0][0],
243                                                                                   matrix,                                                                                   matrix,
244                                                                                   63);                                                                                   63,
245                                                                                     sum,
246                                                                                     pMB->lambda[i],
247                                                                                     pMB->rel_var8[i],
248                                                                                     !!(frame->vop_flags & XVID_VOP_RD_PSNRHVSM));
249                  }                  }
250                  stop_quant_timer();                  stop_quant_timer();
251    
# Line 308  Line 319 
319          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
320          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
321          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
         int vop_reduced;  
322          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
323          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
         transfer_operation_8to16_t * const functions[2] =  
                 {  
                         (transfer_operation_8to16_t *)transfer_8to16copy,  
                         (transfer_operation_8to16_t *)filter_18x18_to_8x8  
                 };  
         transfer_operation_8to16_t *transfer_op = NULL;  
   
         vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);  
324    
325          /* Image pointers */          /* Image pointers */
326          pY_Cur = pCurrent->y + (y_pos << (4+vop_reduced)) * stride  + (x_pos << (4+vop_reduced));          pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
327          pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
328          pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
   
         /* Block size */  
         cst = 8<<vop_reduced;  
   
         /* Operation function */  
         transfer_op = functions[vop_reduced];  
329    
330          /* Do the transfer */          /* Do the transfer */
331          start_timer();          start_timer();
332          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
333          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
334          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
335          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
336          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
337          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
338          stop_transfer_timer();          stop_transfer_timer();
339  }  }
340    
# Line 357  Line 352 
352          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
353          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
354          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
         int vop_reduced;  
355          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
356    
357          /* Array of function pointers, indexed by [vop_reduced<<1+add] */          /* Array of function pointers, indexed by [add] */
358          transfer_operation_16to8_t  * const functions[4] =          transfer_operation_16to8_t  * const functions[2] =
359                  {                  {
360                          (transfer_operation_16to8_t*)transfer_16to8copy,                          (transfer_operation_16to8_t*)transfer_16to8copy,
361                          (transfer_operation_16to8_t*)transfer_16to8add,                          (transfer_operation_16to8_t*)transfer_16to8add,
                         (transfer_operation_16to8_t*)copy_upsampled_8x8_16to8,  
                         (transfer_operation_16to8_t*)add_upsampled_8x8_16to8  
362                  };                  };
363    
364          transfer_operation_16to8_t *transfer_op = NULL;          transfer_operation_16to8_t *transfer_op = NULL;
365    
         /* Makes this vars booleans */  
         vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);  
   
366          /* Image pointers */          /* Image pointers */
367          pY_Cur = pCurrent->y + (y_pos << (4+vop_reduced)) * stride  + (x_pos << (4+vop_reduced));          pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
368          pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
369          pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
370    
371          if (pMB->field_dct) {          if (pMB->field_dct) {
372                  next_block = stride;                  next_block = stride;
373                  stride *= 2;                  stride *= 2;
374          }          }
375    
         /* Block size */  
         cst = 8<<vop_reduced;  
   
376          /* Operation function */          /* Operation function */
377          transfer_op = functions[(vop_reduced<<1) + add];          transfer_op = functions[add];
378    
379          /* Do the operation */          /* Do the operation */
380          start_timer();          start_timer();
381          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);
382          if (cbp&16) transfer_op(pY_Cur + cst,              &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
383          if (cbp& 8) transfer_op(pY_Cur + next_block,       &data[2 * 64], stride);          if (cbp& 8) transfer_op(pY_Cur + next_block,       &data[2 * 64], stride);
384          if (cbp& 4) transfer_op(pY_Cur + next_block + cst, &data[3 * 64], stride);          if (cbp& 4) transfer_op(pY_Cur + next_block + 8,        &data[3 * 64], stride);
385          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);
386          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);
387          stop_transfer_timer();          stop_transfer_timer();
# Line 781  Line 766 
766          return -1;          return -1;
767  }  }
768    
769  static int __inline  #define TRELLIS_MIN_EFFORT      3
770  Compute_Sum(const int16_t *C, int last)  
771    static __inline uint32_t calc_mseh(int16_t dQ, uint16_t mask,
772                                       const int index, const int Lambda)
773  {  {
774          int sum = 0;          uint32_t t = (mask * Inv_iMask_Coeff[index] + 32) >> 7;
775            uint16_t u = abs(dQ) << 4;
776            uint16_t thresh = (t < 65536) ? t : 65535;
777    
778          while(last--)          if (u <= thresh)
779                  sum += abs(C[last]);                  u = 0; /* The error is not perceivable */
780            else
781                    u -= thresh;
782    
783            u = ((u + iCSF_Round[index]) * iCSF_Coeff[index]) >> 16;
784    
785          return(sum);          return (((Lambda*u*u)>>4) + 4*Lambda*dQ*dQ) / 5;
786  }  }
787    
788  /* this routine has been strippen of all debug code */  /* this routine has been strippen of all debug code */
# Line 799  Line 792 
792                                             int Q,                                             int Q,
793                                             const uint16_t * const Zigzag,                                             const uint16_t * const Zigzag,
794                                             const uint16_t * const QuantMatrix,                                             const uint16_t * const QuantMatrix,
795                                             int Non_Zero)                                             int Non_Zero,
796                                               int Sum,
797                                               int Lambda_Mod,
798                                               const uint32_t rel_var8,
799                                               const int Metric)
800  {  {
801    
802          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
# Line 809  Line 806 
806           * helps. */           * helps. */
807          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
808    
809          NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
810          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
811          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
812    
813          /* it's 1/lambda, actually */          /* it's 1/lambda, actually */
814          const int Lambda = Trellis_Lambda_Tabs[Q-1];          const int Lambda = (Lambda_Mod*Trellis_Lambda_Tabs[Q-1])>>LAMBDA_EXP;
815    
816          int Run_Start = -1;          int Run_Start = -1;
817          uint32_t Min_Cost = 2<<TL_SHIFT;          uint32_t Min_Cost = 2<<TL_SHIFT;
# Line 822  Line 819 
819          int Last_Node = -1;          int Last_Node = -1;
820          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
821    
822          int i, j, sum;          int i, j;
823    
824            uint32_t mask = (Metric) ? ((isqrt(2*coeff8_energy(In)*rel_var8) + 48) >> 6) : 0;
825    
826          /* source (w/ CBP penalty) */          /* source (w/ CBP penalty) */
827          Run_Costs[-1] = 2<<TL_SHIFT;          Run_Costs[-1] = 2<<TL_SHIFT;
828    
829          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
830          if (Non_Zero<0)          if (Non_Zero < TRELLIS_MIN_EFFORT)
831                  return 0; /* Sum is zero if there are only zero coeffs */                  Non_Zero = TRELLIS_MIN_EFFORT;
832    
833          for(i=0; i<=Non_Zero; i++) {          for(i=0; i<=Non_Zero; i++) {
834                  const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);                  const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
# Line 839  Line 838 
838    
839                  const int AC = In[Zigzag[i]];                  const int AC = In[Zigzag[i]];
840                  const int Level1 = Out[Zigzag[i]];                  const int Level1 = Out[Zigzag[i]];
841                  const unsigned int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = (Metric) ? (calc_mseh(AC, mask, Zigzag[i], Lambda)) : (Lambda* AC*AC);
842                  uint32_t Best_Cost = 0xf0000000;                  uint32_t Best_Cost = 0xf0000000;
843                  Last_Cost += Dist0;                  Last_Cost += Dist0;
844    
# Line 856  Line 855 
855                                  Nodes[i].Level = 1;                                  Nodes[i].Level = 1;
856                                  dQ = Lev0 - AC;                                  dQ = Lev0 - AC;
857                          }                          }
858                          Cost0 = Lambda*dQ*dQ;                          Cost0 = (Metric) ? (calc_mseh(dQ, mask, Zigzag[i], Lambda)) : (Lambda*dQ*dQ);
859    
860                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
861                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
# Line 911  Line 910 
910                                  Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;                                  Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;
911                          }                          }
912    
913                            if (Metric) {
914                                    Dist1 = calc_mseh(dQ1, mask, Zigzag[i], Lambda);
915                                    Dist2 = calc_mseh(dQ2, mask, Zigzag[i], Lambda);
916                            }
917                            else {
918                          Dist1 = Lambda*dQ1*dQ1;                          Dist1 = Lambda*dQ1*dQ1;
919                          Dist2 = Lambda*dQ2*dQ2;                          Dist2 = Lambda*dQ2*dQ2;
920                            }
921                          dDist21 = Dist2-Dist1;                          dDist21 = Dist2-Dist1;
922    
923                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
# Line 1002  Line 1007 
1007                  }                  }
1008          }          }
1009    
1010          /* It seems trellis doesn't give good results... just compute the Out sum          /* It seems trellis doesn't give good results... just leave the block untouched
1011           * and quit */           * and return the original sum value */
1012          if (Last_Node<0)          if (Last_Node<0)
1013                  return Compute_Sum(Out, Non_Zero);                  return Sum;
1014    
1015          /* reconstruct optimal sequence backward with surviving paths */          /* reconstruct optimal sequence backward with surviving paths */
1016          memset(Out, 0x00, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
1017          Out[Zigzag[Last_Node]] = Last.Level;          Out[Zigzag[Last_Node]] = Last.Level;
1018          i = Last_Node - Last.Run;          i = Last_Node - Last.Run;
1019          sum = 0;          Sum = abs(Last.Level);
1020          while(i>=0) {          while(i>=0) {
1021                  Out[Zigzag[i]] = Nodes[i].Level;                  Out[Zigzag[i]] = Nodes[i].Level;
1022                  sum += abs(Nodes[i].Level);                  Sum += abs(Nodes[i].Level);
1023                  i -= Nodes[i].Run;                  i -= Nodes[i].Run;
1024          }          }
1025    
1026          return sum;          return Sum;
1027  }  }
1028    
1029  /* original version including heavy debugging info */  /* original version including heavy debugging info */

Legend:
Removed from v.1.21.2.22  
changed lines
  Added in v.1.33

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