[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.16, Wed Sep 10 00:54:27 2003 UTC revision 1.31, Sat Dec 10 05:20:35 2005 UTC
# Line 39  Line 39 
39  #include "../bitstream/zigzag.h"  #include "../bitstream/zigzag.h"
40  #include "../dct/fdct.h"  #include "../dct/fdct.h"
41  #include "../dct/idct.h"  #include "../dct/idct.h"
42  #include "../quant/quant_mpeg4.h"  #include "../quant/quant.h"
 #include "../quant/quant_h263.h"  
43  #include "../encoder.h"  #include "../encoder.h"
44    
45  #include "../image/reduced.h"  #include  "../quant/quant_matrix.h"
46    
47  MBFIELDTEST_PTR MBFieldTest;  MBFIELDTEST_PTR MBFieldTest;
48    
# Line 91  Line 90 
90    
91          /* Perform DCT */          /* Perform DCT */
92          start_timer();          start_timer();
93          fdct(&data[0 * 64]);          fdct((short * const)&data[0 * 64]);
94          fdct(&data[1 * 64]);          fdct((short * const)&data[1 * 64]);
95          fdct(&data[2 * 64]);          fdct((short * const)&data[2 * 64]);
96          fdct(&data[3 * 64]);          fdct((short * const)&data[3 * 64]);
97          fdct(&data[4 * 64]);          fdct((short * const)&data[4 * 64]);
98          fdct(&data[5 * 64]);          fdct((short * const)&data[5 * 64]);
99          stop_dct_timer();          stop_dct_timer();
100  }  }
101    
# Line 106  Line 105 
105             const uint8_t cbp)             const uint8_t cbp)
106  {  {
107          start_timer();          start_timer();
108          if(cbp & (1 << (5 - 0))) idct(&data[0 * 64]);          if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]);
109          if(cbp & (1 << (5 - 1))) idct(&data[1 * 64]);          if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]);
110          if(cbp & (1 << (5 - 2))) idct(&data[2 * 64]);          if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]);
111          if(cbp & (1 << (5 - 3))) idct(&data[3 * 64]);          if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]);
112          if(cbp & (1 << (5 - 4))) idct(&data[4 * 64]);          if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]);
113          if(cbp & (1 << (5 - 5))) idct(&data[5 * 64]);          if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]);
114          stop_idct_timer();          stop_idct_timer();
115  }  }
116    
# Line 126  Line 125 
125          int mpeg;          int mpeg;
126          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
127    
128          quanth263_intraFuncPtr const quant[2] =          quant_intraFuncPtr const quant[2] =
129                  {                  {
130                          (quanth263_intraFuncPtr)quant_intra,                          quant_h263_intra,
131                          (quanth263_intraFuncPtr)quant4_intra                          quant_mpeg_intra
132                  };                  };
133    
134          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 138  Line 137 
137    
138          /* Quantize the block */          /* Quantize the block */
139          start_timer();          start_timer();
140          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);
141          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);
142          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);
143          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);
144          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);
145          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);
146          stop_quant_timer();          stop_quant_timer();
147  }  }
148    
# Line 157  Line 156 
156          int mpeg;          int mpeg;
157          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
158    
159          quanth263_intraFuncPtr const dequant[2] =          quant_intraFuncPtr const dequant[2] =
160                  {                  {
161                          (quanth263_intraFuncPtr)dequant_intra,                          dequant_h263_intra,
162                          (quanth263_intraFuncPtr)dequant4_intra                          dequant_mpeg_intra
163                  };                  };
164    
165          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 168  Line 167 
167          scaler_chr = get_dc_scaler(iQuant, 0);          scaler_chr = get_dc_scaler(iQuant, 0);
168    
169          start_timer();          start_timer();
170          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);
171          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);
172          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);
173          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);
174          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);
175          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);
176          stop_iquant_timer();          stop_iquant_timer();
177  }  }
178    
   
 typedef int (*trellis_func_ptr_t)(int16_t *const Out,  
                                                                   const int16_t *const In,  
                                                                   int Q,  
                                                                   const uint16_t * const Zigzag,  
                                                                   int Non_Zero);  
   
179  static int  static int
180  dct_quantize_trellis_h263_c(int16_t *const Out,  dct_quantize_trellis_c(int16_t *const Out,
181                                                          const int16_t *const In,                                                          const int16_t *const In,
182                                                          int Q,                                                          int Q,
183                                                          const uint16_t * const Zigzag,                                                          const uint16_t * const Zigzag,
184                                                          int Non_Zero);                                             const uint16_t * const QuantMatrix,
185                                               int Non_Zero,
186  static int                                             int Sum,
187  dct_quantize_trellis_mpeg_c(int16_t *const Out,                                             int Lambda_Mod);
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero);  
188    
189  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
190  static __inline uint8_t  static __inline uint8_t
# Line 214  Line 202 
202          int sum;          int sum;
203          int code_block, mpeg;          int code_block, mpeg;
204    
205          quanth263_interFuncPtr const quant[2] =          quant_interFuncPtr const quant[2] =
                 {  
                         (quanth263_interFuncPtr)quant_inter,  
                         (quanth263_interFuncPtr)quant4_inter  
                 };  
   
         trellis_func_ptr_t const trellis[2] =  
206                  {                  {
207                          (trellis_func_ptr_t)dct_quantize_trellis_h263_c,                          quant_h263_inter,
208                          (trellis_func_ptr_t)dct_quantize_trellis_mpeg_c                          quant_mpeg_inter
209                  };                  };
210    
211          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 233  Line 215 
215                  /* Quantize the block */                  /* Quantize the block */
216                  start_timer();                  start_timer();
217    
218                  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);
219    
220                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {                  if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
221                          sum = trellis[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, &scan_tables[0][0], 63);                          const uint16_t *matrix;
222                            const static uint16_t h263matrix[] =
223                                    {
224                                            16, 16, 16, 16, 16, 16, 16, 16,
225                                            16, 16, 16, 16, 16, 16, 16, 16,
226                                            16, 16, 16, 16, 16, 16, 16, 16,
227                                            16, 16, 16, 16, 16, 16, 16, 16,
228                                            16, 16, 16, 16, 16, 16, 16, 16,
229                                            16, 16, 16, 16, 16, 16, 16, 16,
230                                            16, 16, 16, 16, 16, 16, 16, 16,
231                                            16, 16, 16, 16, 16, 16, 16, 16
232                                    };
233    
234                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
235                            sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
236                                                                                     pMB->quant, &scan_tables[0][0],
237                                                                                     matrix,
238                                                                                     63,
239                                                                                     sum,
240                                                                                     pMB->lambda[i]);
241                  }                  }
242                  stop_quant_timer();                  stop_quant_timer();
243    
# Line 277  Line 278 
278  {  {
279          int mpeg;          int mpeg;
280    
281          quanth263_interFuncPtr const dequant[2] =          quant_interFuncPtr const dequant[2] =
282                  {                  {
283                          (quanth263_interFuncPtr)dequant_inter,                          dequant_h263_inter,
284                          (quanth263_interFuncPtr)dequant4_inter                          dequant_mpeg_inter
285                  };                  };
286    
287          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
288    
289          start_timer();          start_timer();
290          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);
291          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);
292          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);
293          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);
294          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);
295          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);
296          stop_iquant_timer();          stop_iquant_timer();
297  }  }
298    
# Line 310  Line 311 
311          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
312          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
313          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
         int vop_reduced;  
314          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
315          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);  
316    
317          /* Image pointers */          /* Image pointers */
318          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);
319          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);
320          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];  
321    
322          /* Do the transfer */          /* Do the transfer */
323          start_timer();          start_timer();
324          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
325          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
326          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
327          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
328          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
329          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
330          stop_transfer_timer();          stop_transfer_timer();
331  }  }
332    
# Line 359  Line 344 
344          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
345          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
346          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
         int vop_reduced;  
347          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
348          /* Array of function pointers, indexed by [vop_reduced<<1+add] */  
349          transfer_operation_16to8_t  * const functions[4] =          /* Array of function pointers, indexed by [add] */
350            transfer_operation_16to8_t  * const functions[2] =
351                  {                  {
352                          (transfer_operation_16to8_t*)transfer_16to8copy,                          (transfer_operation_16to8_t*)transfer_16to8copy,
353                          (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  
354                  };                  };
355    
356          transfer_operation_16to8_t *transfer_op = NULL;          transfer_operation_16to8_t *transfer_op = NULL;
357    
358            /* Image pointers */
359            pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
360            pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
361            pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
362    
363          if (pMB->field_dct) {          if (pMB->field_dct) {
364                  next_block = stride;                  next_block = stride;
365                  stride *= 2;                  stride *= 2;
366          }          }
367    
         /* Makes this vars booleans */  
         vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);  
   
         /* Image pointers */  
         pY_Cur = pCurrent->y + (y_pos << (4+vop_reduced)) * stride  + (x_pos << (4+vop_reduced));  
         pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));  
         pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));  
   
         /* Block size */  
         cst = 8<<vop_reduced;  
   
368          /* Operation function */          /* Operation function */
369          transfer_op = functions[(vop_reduced<<1) + add];          transfer_op = functions[add];
370    
371          /* Do the operation */          /* Do the operation */
372          start_timer();          start_timer();
373          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);
374          if (cbp&16) transfer_op(pY_Cur + cst,              &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
375          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);
376          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);
377          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);
378          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);
379          stop_transfer_timer();          stop_transfer_timer();
# Line 449  Line 425 
425          uint8_t cbp;          uint8_t cbp;
426          uint32_t limit;          uint32_t limit;
427    
428          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
429           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
430    
431          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
432          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 490  Line 464 
464          uint8_t cbp;          uint8_t cbp;
465          uint32_t limit;          uint32_t limit;
466    
467          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
468           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
469    
470          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
471          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 511  Line 483 
483           * History comment:           * History comment:
484           * We don't have to DeQuant, iDCT and Transfer back data for B-frames.           * We don't have to DeQuant, iDCT and Transfer back data for B-frames.
485           *           *
486           * BUT some plugins require the original frame to be passed so we have           * BUT some plugins require the rebuilt original frame to be passed so we
487           * to take care of that here           * have to take care of that here
488           */           */
489          if((pParam->plugin_flags & XVID_REQORIGINAL)) {          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
490    
# Line 637  Line 609 
609          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
610  }  }
611    
   
   
   
   
612  /*****************************************************************************  /*****************************************************************************
613   *               Trellis based R-D optimal quantization   *               Trellis based R-D optimal quantization
614   *   *
# Line 648  Line 616 
616   *   *
617   ****************************************************************************/   ****************************************************************************/
618    
   
 #if 0  
 static int  
 dct_quantize_trellis_mpeg_c(int16_t *const Out,  
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero)  
 {  
         return 63;  
 }  
 #endif  
   
619  /*----------------------------------------------------------------------------  /*----------------------------------------------------------------------------
620   *   *
621   *        Trellis-Based quantization   *        Trellis-Based quantization
# Line 672  Line 627 
627   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
628   *   *
629   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
630   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
631   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
632   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
633   * 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
634   * known, and of fixed sized.   * known, and of fixed size.
635   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
636    
637    
# Line 776  Line 731 
731          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
732  };  };
733    
734  #define TL(q) 0xfe00/(q*q)  /* TL_SHIFT controls the precision of the RD optimizations in trellis
735     * valid range is [10..16]. The bigger, the more trellis is vulnerable
736     * to overflows in cost formulas.
737     *  - 10 allows ac values up to 2^11 == 2048
738     *  - 16 allows ac values up to 2^8 == 256
739     */
740    #define TL_SHIFT 11
741    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
742    
743  static const int Trellis_Lambda_Tabs[31] = {  static const int Trellis_Lambda_Tabs[31] = {
744          TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),          TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),
# Line 796  Line 758 
758          return -1;          return -1;
759  }  }
760    
761  static int __inline  #define TRELLIS_MIN_EFFORT      3
 Compute_Sum(const int16_t *C, int last)  
 {  
         int sum = 0;  
   
         while(last--)  
                 sum += abs(C[last]);  
762    
         return(sum);  
 }  
763  /* this routine has been strippen of all debug code */  /* this routine has been strippen of all debug code */
   
764  static int  static int
765  dct_quantize_trellis_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)  dct_quantize_trellis_c(int16_t *const Out,
766                                               const int16_t *const In,
767                                               int Q,
768                                               const uint16_t * const Zigzag,
769                                               const uint16_t * const QuantMatrix,
770                                               int Non_Zero,
771                                               int Sum,
772                                               int Lambda_Mod)
773  {  {
774    
775      /*          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
776           * 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
777           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
778           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
779           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
780          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
781    
782          NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
783          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
784          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
785          const int Mult = 2*Q;  
786          const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
787          const int Lev0 = Mult + Bias;          const int Lambda = (Lambda_Mod*Trellis_Lambda_Tabs[Q-1])>>LAMBDA_EXP;
         const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */  
788    
789          int Run_Start = -1;          int Run_Start = -1;
790          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
791    
792          int Last_Node = -1;          int Last_Node = -1;
793          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
794    
795          int i, j, sum;          int i, j;
796          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */  
797            /* source (w/ CBP penalty) */
798            Run_Costs[-1] = 2<<TL_SHIFT;
799    
800          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
801          if (Non_Zero<0)          if (Non_Zero < TRELLIS_MIN_EFFORT)
802                  return 0; /* Sum is zero if there are only zero coeffs */                  Non_Zero = TRELLIS_MIN_EFFORT;
803    
804          for(i=0; i<=Non_Zero; i++) {          for(i=0; i<=Non_Zero; i++) {
805                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
806                    const int Mult = 2*q;
807                    const int Bias = (q-1) | 1;
808                    const int Lev0 = Mult + Bias;
809    
810                  const int AC = In[Zigzag[i]];                  const int AC = In[Zigzag[i]];
811                  const int Level1 = Out[Zigzag[i]];                  const int Level1 = Out[Zigzag[i]];
812                  const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = Lambda* AC*AC;
813                  uint32_t Best_Cost = 0xf0000000;                  uint32_t Best_Cost = 0xf0000000;
814                  Last_Cost += Dist0;                  Last_Cost += Dist0;
815    
# Line 864  Line 829 
829                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
830    
831                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
832                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
833                          for(Run=i-Run_Start; Run>0; --Run) {                          for(Run=i-Run_Start; Run>0; --Run) {
834                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
835                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
836                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
837    
838                                  /*                                  /* TODO: what about tie-breaks? Should we favor short runs or
                                  * TODO: what about tie-breaks? Should we favor short runs or  
839                                   * long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
840                                   * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                                  */  
841    
842                                  /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
843    
844                                  if (Cost<Best_Cost) {                                  if (Cost<Best_Cost) {
845                                          Best_Cost    = Cost;                                          Best_Cost    = Cost;
# Line 891  Line 854 
854                          }                          }
855                          if (Last_Node==i)                          if (Last_Node==i)
856                                  Last.Level = Nodes[i].Level;                                  Last.Level = Nodes[i].Level;
857                  } else { /* "big" levels */                  } else if (51U>(uint32_t)(Level1+25)) {
858                            /* "big" levels (not less than ESC3, though) */
859                          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;
860                          int Level2;                          int Level2;
861                          int dQ1, dQ2;                          int dQ1, dQ2;
# Line 927  Line 891 
891                                  uint32_t Cost1, Cost2;                                  uint32_t Cost1, Cost2;
892                                  int bLevel;                                  int bLevel;
893    
894                                  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
895                                   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
896                                   *      if (Cost_Base>=Best_Cost) continue;                                   *      if (Cost_Base>=Best_Cost) continue;
897                                   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
                                  */  
898    
899                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
900                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
901    
902                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
903                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 949  Line 912 
912                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
913                                  }                                  }
914    
915                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
916                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
917    
918                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
919                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 966  Line 929 
929                                          Last_Node  = i;                                          Last_Node  = i;
930                                  }                                  }
931                          } /* end of "for Run" */                          } /* end of "for Run" */
932                    } else {
933                            /* Very very high levels, with no chance of being optimizable
934                             * => Simply pick best Run. */
935                            int Run;
936                            for(Run=i-Run_Start; Run>0; --Run) {
937                                    /* 30 bits + no distortion */
938                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
939                                    if (Cost<Best_Cost) {
940                                            Best_Cost = Cost;
941                                            Nodes[i].Run   = Run;
942                                            Nodes[i].Level = Level1;
943                                    }
944    
945                                    if (Cost<Last_Cost) {
946                                            Last_Cost  = Cost;
947                                            Last.Run   = Run;
948                                            Last.Level = Level1;
949                                            Last_Node  = i;
950                                    }
951                            }
952                  }                  }
953    
954    
955                  Run_Costs[i] = Best_Cost;                  Run_Costs[i] = Best_Cost;
956    
957                  if (Best_Cost < Min_Cost + Dist0) {                  if (Best_Cost < Min_Cost + Dist0) {
958                          Min_Cost = Best_Cost;                          Min_Cost = Best_Cost;
959                          Run_Start = i;                          Run_Start = i;
960                  } else {                  } else {
961                          /*                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
962                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * there's a code shorter by 1 bit for a larger run (!), same
963                           * 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
964                           * it a chance by not moving the left barrier too much.                           * much. */
965                           */                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
   
                         while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
966                                  Run_Start++;                                  Run_Start++;
967    
968                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
969                             * one */
970                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
971                          Min_Cost += Dist0;                          Min_Cost += Dist0;
972                  }                  }
973          }          }
974    
975          /* It seems trellis doesn't give good results... just compute the Out sum and          /* It seems trellis doesn't give good results... just leave the block untouched
976           * quit (even if we did not modify it, upperlayer relies on this data) */           * and return the original sum value */
977          if (Last_Node<0)          if (Last_Node<0)
978                  return Compute_Sum(Out, Non_Zero);                  return Sum;
979    
980          /* reconstruct optimal sequence backward with surviving paths */          /* reconstruct optimal sequence backward with surviving paths */
981          memset(Out, 0x00, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
982          Out[Zigzag[Last_Node]] = Last.Level;          Out[Zigzag[Last_Node]] = Last.Level;
983          i = Last_Node - Last.Run;          i = Last_Node - Last.Run;
984          sum = 0;          Sum = abs(Last.Level);
985          while(i>=0) {          while(i>=0) {
986                  Out[Zigzag[i]] = Nodes[i].Level;                  Out[Zigzag[i]] = Nodes[i].Level;
987                  sum += abs(Nodes[i].Level);                  Sum += abs(Nodes[i].Level);
988                  i -= Nodes[i].Run;                  i -= Nodes[i].Run;
989          }          }
990    
991          return sum;          return Sum;
 }  
   
 static int  
 dct_quantize_trellis_mpeg_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)  
 {  
         /* ToDo: Ok ok it's just a place holder for Gruel -- damn write this one :-) */  
         return Compute_Sum(Out, 63);  
992  }  }
993    
994  /* original version including heavy debugging info */  /* original version including heavy debugging info */
# Line 1072  Line 1047 
1047                  V -= Ref[Zigzag[i]];                  V -= Ref[Zigzag[i]];
1048                  Dist += V*V;                  Dist += V*V;
1049          }          }
1050          Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1051          if (DBG==1)          if (DBG==1)
1052                  printf( " Last:%2d/%2d Cost = [(Bits=%5.0d) + Lambda*(Dist=%6.0d) = %d ] >>12= %d ", Last,Max, Bits, Dist, Cost, Cost>>12 );                  printf( " Last:%2d/%2d Cost = [(Bits=%5.0d) + Lambda*(Dist=%6.0d) = %d ] >>12= %d ", Last,Max, Bits, Dist, Cost, Cost>>12 );
1053          return Cost;          return Cost;
# Line 1104  Line 1079 
1079          const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */          const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */
1080    
1081          int Run_Start = -1;          int Run_Start = -1;
1082          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1083          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1084    
1085          int Last_Node = -1;          int Last_Node = -1;
1086          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
# Line 1144  Line 1119 
1119                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
1120    
1121                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
1122                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1123                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
1124                          {                          {
1125                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1126                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1127                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1128    
1129                                  /*                                  /*
1130                                   * TODO: what about tie-breaks? Should we favor short runs or                                   * TODO: what about tie-breaks? Should we favor short runs or
# Line 1225  Line 1200 
1200   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1201   *        if (Cost_Base>=Best_Cost) continue;   *        if (Cost_Base>=Best_Cost) continue;
1202   */   */
1203                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1204                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1205    
1206                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1207                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1240  Line 1215 
1215                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
1216                                  }                                  }
1217    
1218                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1219                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1220    
1221                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1222                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1287  Line 1262 
1262                           * it a chance by not moving the left barrier too much.                           * it a chance by not moving the left barrier too much.
1263                           */                           */
1264    
1265                          while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1266                                  Run_Start++;                                  Run_Start++;
1267    
1268                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this one */

Legend:
Removed from v.1.21.2.16  
changed lines
  Added in v.1.31

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