[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.17, Wed Oct 1 23:23:01 2003 UTC revision 1.29, Tue Nov 22 10:23:01 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);
 dct_quantize_trellis_mpeg_c(int16_t *const Out,  
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero);  
187    
188  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
189  static __inline uint8_t  static __inline uint8_t
# Line 214  Line 201 
201          int sum;          int sum;
202          int code_block, mpeg;          int code_block, mpeg;
203    
204          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] =  
205                  {                  {
206                          (trellis_func_ptr_t)dct_quantize_trellis_h263_c,                          quant_h263_inter,
207                          (trellis_func_ptr_t)dct_quantize_trellis_mpeg_c                          quant_mpeg_inter
208                  };                  };
209    
210          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 233  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 && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
220                          sum = trellis[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, &scan_tables[0][0], 63);                          const uint16_t *matrix;
221                            const static uint16_t h263matrix[] =
222                                    {
223                                            16, 16, 16, 16, 16, 16, 16, 16,
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                                    };
232    
233                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
234                            sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
235                                                                                     pMB->quant, &scan_tables[0][0],
236                                                                                     matrix,
237                                                                                     63,
238                                                                                     sum);
239                  }                  }
240                  stop_quant_timer();                  stop_quant_timer();
241    
# Line 277  Line 276 
276  {  {
277          int mpeg;          int mpeg;
278    
279          quanth263_interFuncPtr const dequant[2] =          quant_interFuncPtr const dequant[2] =
280                  {                  {
281                          (quanth263_interFuncPtr)dequant_inter,                          dequant_h263_inter,
282                          (quanth263_interFuncPtr)dequant4_inter                          dequant_mpeg_inter
283                  };                  };
284    
285          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
286    
287          start_timer();          start_timer();
288          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);
289          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);
290          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);
291          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);
292          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);
293          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);
294          stop_iquant_timer();          stop_iquant_timer();
295  }  }
296    
# Line 310  Line 309 
309          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
310          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
311          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
         int vop_reduced;  
312          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
313          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);  
314    
315          /* Image pointers */          /* Image pointers */
316          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);
317          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);
318          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];  
319    
320          /* Do the transfer */          /* Do the transfer */
321          start_timer();          start_timer();
322          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
323          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
324          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
325          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
326          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
327          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
328          stop_transfer_timer();          stop_transfer_timer();
329  }  }
330    
# Line 359  Line 342 
342          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
343          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
344          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
         int vop_reduced;  
345          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
346          /* Array of function pointers, indexed by [vop_reduced<<1+add] */  
347          transfer_operation_16to8_t  * const functions[4] =          /* Array of function pointers, indexed by [add] */
348            transfer_operation_16to8_t  * const functions[2] =
349                  {                  {
350                          (transfer_operation_16to8_t*)transfer_16to8copy,                          (transfer_operation_16to8_t*)transfer_16to8copy,
351                          (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  
352                  };                  };
353    
354          transfer_operation_16to8_t *transfer_op = NULL;          transfer_operation_16to8_t *transfer_op = NULL;
355    
356            /* Image pointers */
357            pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
358            pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
359            pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
360    
361          if (pMB->field_dct) {          if (pMB->field_dct) {
362                  next_block = stride;                  next_block = stride;
363                  stride *= 2;                  stride *= 2;
364          }          }
365    
         /* 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;  
   
366          /* Operation function */          /* Operation function */
367          transfer_op = functions[(vop_reduced<<1) + add];          transfer_op = functions[add];
368    
369          /* Do the operation */          /* Do the operation */
370          start_timer();          start_timer();
371          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);
372          if (cbp&16) transfer_op(pY_Cur + cst,              &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
373          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);
374          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);
375          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);
376          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);
377          stop_transfer_timer();          stop_transfer_timer();
# Line 449  Line 423 
423          uint8_t cbp;          uint8_t cbp;
424          uint32_t limit;          uint32_t limit;
425    
426          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
427           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
428    
429          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
430          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 490  Line 462 
462          uint8_t cbp;          uint8_t cbp;
463          uint32_t limit;          uint32_t limit;
464    
465          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
466           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
467    
468          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
469          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 511  Line 481 
481           * History comment:           * History comment:
482           * 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.
483           *           *
484           * 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
485           * to take care of that here           * have to take care of that here
486           */           */
487          if((pParam->plugin_flags & XVID_REQORIGINAL)) {          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
488    
# Line 637  Line 607 
607          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
608  }  }
609    
   
   
   
   
610  /*****************************************************************************  /*****************************************************************************
611   *               Trellis based R-D optimal quantization   *               Trellis based R-D optimal quantization
612   *   *
# Line 648  Line 614 
614   *   *
615   ****************************************************************************/   ****************************************************************************/
616    
   
 #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  
   
617  /*----------------------------------------------------------------------------  /*----------------------------------------------------------------------------
618   *   *
619   *        Trellis-Based quantization   *        Trellis-Based quantization
# Line 672  Line 625 
625   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
626   *   *
627   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
628   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
629   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
630   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
631   * 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
632   * known, and of fixed sized.   * known, and of fixed size.
633   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
634    
635    
# Line 776  Line 729 
729          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
730  };  };
731    
732  #define TL(q) 0xfe00/(q*q)  /* TL_SHIFT controls the precision of the RD optimizations in trellis
733     * valid range is [10..16]. The bigger, the more trellis is vulnerable
734     * to overflows in cost formulas.
735     *  - 10 allows ac values up to 2^11 == 2048
736     *  - 16 allows ac values up to 2^8 == 256
737     */
738    #define TL_SHIFT 11
739    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
740    
741  static const int Trellis_Lambda_Tabs[31] = {  static const int Trellis_Lambda_Tabs[31] = {
742          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 756 
756          return -1;          return -1;
757  }  }
758    
 static int __inline  
 Compute_Sum(const int16_t *C, int last)  
 {  
         int sum = 0;  
   
         while(last--)  
                 sum += abs(C[last]);  
   
         return(sum);  
 }  
759  /* this routine has been strippen of all debug code */  /* this routine has been strippen of all debug code */
   
760  static int  static int
761  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,
762                                               const int16_t *const In,
763                                               int Q,
764                                               const uint16_t * const Zigzag,
765                                               const uint16_t * const QuantMatrix,
766                                               int Non_Zero,
767                                               int Sum)
768  {  {
769    
770      /*          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
771           * 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
772           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
773           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
774           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
775          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
776    
777          NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
778          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
779          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
780          const int Mult = 2*Q;  
781          const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
782          const int Lev0 = Mult + Bias;          const int Lambda = Trellis_Lambda_Tabs[Q-1];
         const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */  
783    
784          int Run_Start = -1;          int Run_Start = -1;
785          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
786    
787          int Last_Node = -1;          int Last_Node = -1;
788          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
789    
790          int i, j, sum;          int i, j;
791          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */  
792            /* source (w/ CBP penalty) */
793            Run_Costs[-1] = 2<<TL_SHIFT;
794    
795          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
796          if (Non_Zero<0)          if (Non_Zero<0)
797                  return 0; /* Sum is zero if there are only zero coeffs */                  return 0; /* Sum is zero if there are only zero coeffs */
798    
799          for(i=0; i<=Non_Zero; i++) {          for(i=0; i<=Non_Zero; i++) {
800                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
801                    const int Mult = 2*q;
802                    const int Bias = (q-1) | 1;
803                    const int Lev0 = Mult + Bias;
804    
805                  const int AC = In[Zigzag[i]];                  const int AC = In[Zigzag[i]];
806                  const int Level1 = Out[Zigzag[i]];                  const int Level1 = Out[Zigzag[i]];
807                  const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = Lambda* AC*AC;
808                  uint32_t Best_Cost = 0xf0000000;                  uint32_t Best_Cost = 0xf0000000;
809                  Last_Cost += Dist0;                  Last_Cost += Dist0;
810    
# Line 864  Line 824 
824                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
825    
826                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
827                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
828                          for(Run=i-Run_Start; Run>0; --Run) {                          for(Run=i-Run_Start; Run>0; --Run) {
829                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
830                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
831                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
832    
833                                  /*                                  /* TODO: what about tie-breaks? Should we favor short runs or
                                  * TODO: what about tie-breaks? Should we favor short runs or  
834                                   * long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
835                                   * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                                  */  
836    
837                                  /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
838    
839                                  if (Cost<Best_Cost) {                                  if (Cost<Best_Cost) {
840                                          Best_Cost    = Cost;                                          Best_Cost    = Cost;
# Line 891  Line 849 
849                          }                          }
850                          if (Last_Node==i)                          if (Last_Node==i)
851                                  Last.Level = Nodes[i].Level;                                  Last.Level = Nodes[i].Level;
852                  } else { /* "big" levels */                  } else if (51U>(uint32_t)(Level1+25)) {
853                            /* "big" levels (not less than ESC3, though) */
854                          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;
855                          int Level2;                          int Level2;
856                          int dQ1, dQ2;                          int dQ1, dQ2;
# Line 927  Line 886 
886                                  uint32_t Cost1, Cost2;                                  uint32_t Cost1, Cost2;
887                                  int bLevel;                                  int bLevel;
888    
889                                  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
890                                   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
891                                   *      if (Cost_Base>=Best_Cost) continue;                                   *      if (Cost_Base>=Best_Cost) continue;
892                                   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
                                  */  
893    
894                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
895                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
896    
897                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
898                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 949  Line 907 
907                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
908                                  }                                  }
909    
910                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
911                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
912    
913                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
914                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 966  Line 924 
924                                          Last_Node  = i;                                          Last_Node  = i;
925                                  }                                  }
926                          } /* end of "for Run" */                          } /* end of "for Run" */
927                    } else {
928                            /* Very very high levels, with no chance of being optimizable
929                             * => Simply pick best Run. */
930                            int Run;
931                            for(Run=i-Run_Start; Run>0; --Run) {
932                                    /* 30 bits + no distortion */
933                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
934                                    if (Cost<Best_Cost) {
935                                            Best_Cost = Cost;
936                                            Nodes[i].Run   = Run;
937                                            Nodes[i].Level = Level1;
938                                    }
939    
940                                    if (Cost<Last_Cost) {
941                                            Last_Cost  = Cost;
942                                            Last.Run   = Run;
943                                            Last.Level = Level1;
944                                            Last_Node  = i;
945                                    }
946                            }
947                  }                  }
948    
949    
950                  Run_Costs[i] = Best_Cost;                  Run_Costs[i] = Best_Cost;
951    
952                  if (Best_Cost < Min_Cost + Dist0) {                  if (Best_Cost < Min_Cost + Dist0) {
953                          Min_Cost = Best_Cost;                          Min_Cost = Best_Cost;
954                          Run_Start = i;                          Run_Start = i;
955                  } else {                  } else {
956                          /*                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
957                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * there's a code shorter by 1 bit for a larger run (!), same
958                           * 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
959                           * it a chance by not moving the left barrier too much.                           * much. */
960                           */                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
   
                         while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
961                                  Run_Start++;                                  Run_Start++;
962    
963                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
964                             * one */
965                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
966                          Min_Cost += Dist0;                          Min_Cost += Dist0;
967                  }                  }
968          }          }
969    
970          /* 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
971           * quit (even if we did not modify it, upperlayer relies on this data) */           * and return the original sum value */
972          if (Last_Node<0)          if (Last_Node<0)
973                  return Compute_Sum(Out, Non_Zero);                  return Sum;
974    
975          /* reconstruct optimal sequence backward with surviving paths */          /* reconstruct optimal sequence backward with surviving paths */
976          memset(Out, 0x00, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
977          Out[Zigzag[Last_Node]] = Last.Level;          Out[Zigzag[Last_Node]] = Last.Level;
978          i = Last_Node - Last.Run;          i = Last_Node - Last.Run;
979          sum = 0;          Sum = abs(Last.Level);
980          while(i>=0) {          while(i>=0) {
981                  Out[Zigzag[i]] = Nodes[i].Level;                  Out[Zigzag[i]] = Nodes[i].Level;
982                  sum += abs(Nodes[i].Level);                  Sum += abs(Nodes[i].Level);
983                  i -= Nodes[i].Run;                  i -= Nodes[i].Run;
984          }          }
985    
986          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);  
987  }  }
988    
989  /* original version including heavy debugging info */  /* original version including heavy debugging info */
# Line 1072  Line 1042 
1042                  V -= Ref[Zigzag[i]];                  V -= Ref[Zigzag[i]];
1043                  Dist += V*V;                  Dist += V*V;
1044          }          }
1045          Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1046          if (DBG==1)          if (DBG==1)
1047                  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 );
1048          return Cost;          return Cost;
# Line 1104  Line 1074 
1074          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 */
1075    
1076          int Run_Start = -1;          int Run_Start = -1;
1077          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1078          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1079    
1080          int Last_Node = -1;          int Last_Node = -1;
1081          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
# Line 1144  Line 1114 
1114                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
1115    
1116                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
1117                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1118                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
1119                          {                          {
1120                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1121                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1122                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1123    
1124                                  /*                                  /*
1125                                   * 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 1195 
1195   * 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:
1196   *        if (Cost_Base>=Best_Cost) continue;   *        if (Cost_Base>=Best_Cost) continue;
1197   */   */
1198                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1199                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1200    
1201                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1202                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1240  Line 1210 
1210                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
1211                                  }                                  }
1212    
1213                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1214                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1215    
1216                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1217                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1287  Line 1257 
1257                           * it a chance by not moving the left barrier too much.                           * it a chance by not moving the left barrier too much.
1258                           */                           */
1259    
1260                          while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1261                                  Run_Start++;                                  Run_Start++;
1262    
1263                          /* 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.17  
changed lines
  Added in v.1.29

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