[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.32, Mon Jul 10 08:09:59 2006 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 123  Line 122 
122                           int16_t qcoeff[6 * 64],                           int16_t qcoeff[6 * 64],
123                           int16_t data[6*64])                           int16_t data[6*64])
124  {  {
         int mpeg;  
125          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
126            quant_intraFuncPtr quant;
127    
128          quanth263_intraFuncPtr const quant[2] =          /* check if quant matrices need to be re-initialized with new quant */
129                  {          if (pParam->vol_flags & XVID_VOL_MPEGQUANT) {
130                          (quanth263_intraFuncPtr)quant_intra,                  if (pParam->last_quant_initialized_intra != pMB->quant) {
131                          (quanth263_intraFuncPtr)quant4_intra                          init_intra_matrix(pParam->mpeg_quant_matrices, pMB->quant);
132                  };                  }
133                    quant = quant_mpeg_intra;
134            } else {
135                    quant = quant_h263_intra;
136            }
137    
         mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);  
138          scaler_lum = get_dc_scaler(pMB->quant, 1);          scaler_lum = get_dc_scaler(pMB->quant, 1);
139          scaler_chr = get_dc_scaler(pMB->quant, 0);          scaler_chr = get_dc_scaler(pMB->quant, 0);
140    
141          /* Quantize the block */          /* Quantize the block */
142          start_timer();          start_timer();
143          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum);          quant(&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
144          quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum);          quant(&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145          quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum);          quant(&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
146          quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum);          quant(&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
147          quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr);          quant(&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
148          quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr);          quant(&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
149          stop_quant_timer();          stop_quant_timer();
150  }  }
151    
# Line 157  Line 159 
159          int mpeg;          int mpeg;
160          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
161    
162          quanth263_intraFuncPtr const dequant[2] =          quant_intraFuncPtr const dequant[2] =
163                  {                  {
164                          (quanth263_intraFuncPtr)dequant_intra,                          dequant_h263_intra,
165                          (quanth263_intraFuncPtr)dequant4_intra                          dequant_mpeg_intra
166                  };                  };
167    
168          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 168  Line 170 
170          scaler_chr = get_dc_scaler(iQuant, 0);          scaler_chr = get_dc_scaler(iQuant, 0);
171    
172          start_timer();          start_timer();
173          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);
174          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);
175          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);
176          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);
177          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);
178          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);
179          stop_iquant_timer();          stop_iquant_timer();
180  }  }
181    
   
 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);  
   
 static int  
 dct_quantize_trellis_h263_c(int16_t *const Out,  
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero);  
   
182  static int  static int
183  dct_quantize_trellis_mpeg_c(int16_t *const Out,  dct_quantize_trellis_c(int16_t *const Out,
184                                                          const int16_t *const In,                                                          const int16_t *const In,
185                                                          int Q,                                                          int Q,
186                                                          const uint16_t * const Zigzag,                                                          const uint16_t * const Zigzag,
187                                                          int Non_Zero);                                             const uint16_t * const QuantMatrix,
188                                               int Non_Zero,
189                                               int Sum,
190                                               int Lambda_Mod);
191    
192  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
193  static __inline uint8_t  static __inline uint8_t
# Line 214  Line 205 
205          int sum;          int sum;
206          int code_block, mpeg;          int code_block, mpeg;
207    
208          quanth263_interFuncPtr const quant[2] =          quant_interFuncPtr const quant[2] =
209                  {                  {
210                          (quanth263_interFuncPtr)quant_inter,                          quant_h263_inter,
211                          (quanth263_interFuncPtr)quant4_inter                          quant_mpeg_inter
                 };  
   
         trellis_func_ptr_t const trellis[2] =  
                 {  
                         (trellis_func_ptr_t)dct_quantize_trellis_h263_c,  
                         (trellis_func_ptr_t)dct_quantize_trellis_mpeg_c  
212                  };                  };
213    
214          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 233  Line 218 
218                  /* Quantize the block */                  /* Quantize the block */
219                  start_timer();                  start_timer();
220    
221                  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);
222    
223                    if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
224                            const uint16_t *matrix;
225                            const static uint16_t h263matrix[] =
226                                    {
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                                            16, 16, 16, 16, 16, 16, 16, 16,
233                                            16, 16, 16, 16, 16, 16, 16, 16,
234                                            16, 16, 16, 16, 16, 16, 16, 16
235                                    };
236    
237                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {                          matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
238                          sum = trellis[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, &scan_tables[0][0], 63);                          sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
239                                                                                     pMB->quant, &scan_tables[0][0],
240                                                                                     matrix,
241                                                                                     63,
242                                                                                     sum,
243                                                                                     pMB->lambda[i]);
244                  }                  }
245                  stop_quant_timer();                  stop_quant_timer();
246    
# Line 277  Line 281 
281  {  {
282          int mpeg;          int mpeg;
283    
284          quanth263_interFuncPtr const dequant[2] =          quant_interFuncPtr const dequant[2] =
285                  {                  {
286                          (quanth263_interFuncPtr)dequant_inter,                          dequant_h263_inter,
287                          (quanth263_interFuncPtr)dequant4_inter                          dequant_mpeg_inter
288                  };                  };
289    
290          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
291    
292          start_timer();          start_timer();
293          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);
294          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);
295          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);
296          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);
297          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);
298          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);
299          stop_iquant_timer();          stop_iquant_timer();
300  }  }
301    
# Line 310  Line 314 
314          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
315          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
316          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
         int vop_reduced;  
317          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
318          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);  
319    
320          /* Image pointers */          /* Image pointers */
321          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);
322          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);
323          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];  
324    
325          /* Do the transfer */          /* Do the transfer */
326          start_timer();          start_timer();
327          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
328          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
329          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
330          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
331          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
332          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
333          stop_transfer_timer();          stop_transfer_timer();
334  }  }
335    
# Line 359  Line 347 
347          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
348          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
349          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
         int vop_reduced;  
350          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
351          /* Array of function pointers, indexed by [vop_reduced<<1+add] */  
352          transfer_operation_16to8_t  * const functions[4] =          /* Array of function pointers, indexed by [add] */
353            transfer_operation_16to8_t  * const functions[2] =
354                  {                  {
355                          (transfer_operation_16to8_t*)transfer_16to8copy,                          (transfer_operation_16to8_t*)transfer_16to8copy,
356                          (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  
357                  };                  };
358    
359          transfer_operation_16to8_t *transfer_op = NULL;          transfer_operation_16to8_t *transfer_op = NULL;
360    
361            /* Image pointers */
362            pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
363            pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
364            pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
365    
366          if (pMB->field_dct) {          if (pMB->field_dct) {
367                  next_block = stride;                  next_block = stride;
368                  stride *= 2;                  stride *= 2;
369          }          }
370    
         /* 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;  
   
371          /* Operation function */          /* Operation function */
372          transfer_op = functions[(vop_reduced<<1) + add];          transfer_op = functions[add];
373    
374          /* Do the operation */          /* Do the operation */
375          start_timer();          start_timer();
376          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);
377          if (cbp&16) transfer_op(pY_Cur + cst,              &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
378          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);
379          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);
380          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);
381          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);
382          stop_transfer_timer();          stop_transfer_timer();
# Line 449  Line 428 
428          uint8_t cbp;          uint8_t cbp;
429          uint32_t limit;          uint32_t limit;
430    
431          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
432           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
433    
434          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
435          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 490  Line 467 
467          uint8_t cbp;          uint8_t cbp;
468          uint32_t limit;          uint32_t limit;
469    
470          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
471           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
472    
473          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
474          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 511  Line 486 
486           * History comment:           * History comment:
487           * 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.
488           *           *
489           * 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
490           * to take care of that here           * have to take care of that here
491           */           */
492          if((pParam->plugin_flags & XVID_REQORIGINAL)) {          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
493    
# Line 637  Line 612 
612          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
613  }  }
614    
   
   
   
   
615  /*****************************************************************************  /*****************************************************************************
616   *               Trellis based R-D optimal quantization   *               Trellis based R-D optimal quantization
617   *   *
# Line 648  Line 619 
619   *   *
620   ****************************************************************************/   ****************************************************************************/
621    
   
 #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  
   
622  /*----------------------------------------------------------------------------  /*----------------------------------------------------------------------------
623   *   *
624   *        Trellis-Based quantization   *        Trellis-Based quantization
# Line 672  Line 630 
630   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
631   *   *
632   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
633   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
634   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
635   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
636   * 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
637   * known, and of fixed sized.   * known, and of fixed size.
638   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
639    
640    
# Line 776  Line 734 
734          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
735  };  };
736    
737  #define TL(q) 0xfe00/(q*q)  /* TL_SHIFT controls the precision of the RD optimizations in trellis
738     * valid range is [10..16]. The bigger, the more trellis is vulnerable
739     * to overflows in cost formulas.
740     *  - 10 allows ac values up to 2^11 == 2048
741     *  - 16 allows ac values up to 2^8 == 256
742     */
743    #define TL_SHIFT 11
744    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
745    
746  static const int Trellis_Lambda_Tabs[31] = {  static const int Trellis_Lambda_Tabs[31] = {
747          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 761 
761          return -1;          return -1;
762  }  }
763    
764  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]);  
765    
         return(sum);  
 }  
766  /* this routine has been strippen of all debug code */  /* this routine has been strippen of all debug code */
   
767  static int  static int
768  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,
769                                               const int16_t *const In,
770                                               int Q,
771                                               const uint16_t * const Zigzag,
772                                               const uint16_t * const QuantMatrix,
773                                               int Non_Zero,
774                                               int Sum,
775                                               int Lambda_Mod)
776  {  {
777    
778      /*          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
779           * 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
780           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
781           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
782           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
783          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
784    
785          NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
786          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
787          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
788          const int Mult = 2*Q;  
789          const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
790          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 */  
791    
792          int Run_Start = -1;          int Run_Start = -1;
793          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
794    
795          int Last_Node = -1;          int Last_Node = -1;
796          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
797    
798          int i, j, sum;          int i, j;
799          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */  
800            /* source (w/ CBP penalty) */
801            Run_Costs[-1] = 2<<TL_SHIFT;
802    
803          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
804          if (Non_Zero<0)          if (Non_Zero < TRELLIS_MIN_EFFORT)
805                  return 0; /* Sum is zero if there are only zero coeffs */                  Non_Zero = TRELLIS_MIN_EFFORT;
806    
807          for(i=0; i<=Non_Zero; i++) {          for(i=0; i<=Non_Zero; i++) {
808                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
809                    const int Mult = 2*q;
810                    const int Bias = (q-1) | 1;
811                    const int Lev0 = Mult + Bias;
812    
813                  const int AC = In[Zigzag[i]];                  const int AC = In[Zigzag[i]];
814                  const int Level1 = Out[Zigzag[i]];                  const int Level1 = Out[Zigzag[i]];
815                  const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = Lambda* AC*AC;
816                  uint32_t Best_Cost = 0xf0000000;                  uint32_t Best_Cost = 0xf0000000;
817                  Last_Cost += Dist0;                  Last_Cost += Dist0;
818    
# Line 864  Line 832 
832                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
833    
834                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
835                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
836                          for(Run=i-Run_Start; Run>0; --Run) {                          for(Run=i-Run_Start; Run>0; --Run) {
837                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
838                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
839                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
840    
841                                  /*                                  /* TODO: what about tie-breaks? Should we favor short runs or
                                  * TODO: what about tie-breaks? Should we favor short runs or  
842                                   * long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
843                                   * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                                  */  
844    
845                                  /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
846    
847                                  if (Cost<Best_Cost) {                                  if (Cost<Best_Cost) {
848                                          Best_Cost    = Cost;                                          Best_Cost    = Cost;
# Line 891  Line 857 
857                          }                          }
858                          if (Last_Node==i)                          if (Last_Node==i)
859                                  Last.Level = Nodes[i].Level;                                  Last.Level = Nodes[i].Level;
860                  } else { /* "big" levels */                  } else if (51U>(uint32_t)(Level1+25)) {
861                            /* "big" levels (not less than ESC3, though) */
862                          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;
863                          int Level2;                          int Level2;
864                          int dQ1, dQ2;                          int dQ1, dQ2;
# Line 927  Line 894 
894                                  uint32_t Cost1, Cost2;                                  uint32_t Cost1, Cost2;
895                                  int bLevel;                                  int bLevel;
896    
897                                  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
898                                   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
899                                   *      if (Cost_Base>=Best_Cost) continue;                                   *      if (Cost_Base>=Best_Cost) continue;
900                                   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
                                  */  
901    
902                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
903                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
904    
905                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
906                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 949  Line 915 
915                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
916                                  }                                  }
917    
918                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
919                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
920    
921                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
922                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 966  Line 932 
932                                          Last_Node  = i;                                          Last_Node  = i;
933                                  }                                  }
934                          } /* end of "for Run" */                          } /* end of "for Run" */
935                    } else {
936                            /* Very very high levels, with no chance of being optimizable
937                             * => Simply pick best Run. */
938                            int Run;
939                            for(Run=i-Run_Start; Run>0; --Run) {
940                                    /* 30 bits + no distortion */
941                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
942                                    if (Cost<Best_Cost) {
943                                            Best_Cost = Cost;
944                                            Nodes[i].Run   = Run;
945                                            Nodes[i].Level = Level1;
946                                    }
947    
948                                    if (Cost<Last_Cost) {
949                                            Last_Cost  = Cost;
950                                            Last.Run   = Run;
951                                            Last.Level = Level1;
952                                            Last_Node  = i;
953                                    }
954                  }                  }
955                    }
956    
957    
958                  Run_Costs[i] = Best_Cost;                  Run_Costs[i] = Best_Cost;
959    
# Line 975  Line 961 
961                          Min_Cost = Best_Cost;                          Min_Cost = Best_Cost;
962                          Run_Start = i;                          Run_Start = i;
963                  } else {                  } else {
964                          /*                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
965                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * there's a code shorter by 1 bit for a larger run (!), same
966                           * 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
967                           * it a chance by not moving the left barrier too much.                           * much. */
968                           */                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
   
                         while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
969                                  Run_Start++;                                  Run_Start++;
970    
971                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
972                             * one */
973                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
974                          Min_Cost += Dist0;                          Min_Cost += Dist0;
975                  }                  }
976          }          }
977    
978          /* 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
979           * quit (even if we did not modify it, upperlayer relies on this data) */           * and return the original sum value */
980          if (Last_Node<0)          if (Last_Node<0)
981                  return Compute_Sum(Out, Non_Zero);                  return Sum;
982    
983          /* reconstruct optimal sequence backward with surviving paths */          /* reconstruct optimal sequence backward with surviving paths */
984          memset(Out, 0x00, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
985          Out[Zigzag[Last_Node]] = Last.Level;          Out[Zigzag[Last_Node]] = Last.Level;
986          i = Last_Node - Last.Run;          i = Last_Node - Last.Run;
987          sum = 0;          Sum = abs(Last.Level);
988          while(i>=0) {          while(i>=0) {
989                  Out[Zigzag[i]] = Nodes[i].Level;                  Out[Zigzag[i]] = Nodes[i].Level;
990                  sum += abs(Nodes[i].Level);                  Sum += abs(Nodes[i].Level);
991                  i -= Nodes[i].Run;                  i -= Nodes[i].Run;
992          }          }
993    
994          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);  
995  }  }
996    
997  /* original version including heavy debugging info */  /* original version including heavy debugging info */
# Line 1072  Line 1050 
1050                  V -= Ref[Zigzag[i]];                  V -= Ref[Zigzag[i]];
1051                  Dist += V*V;                  Dist += V*V;
1052          }          }
1053          Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1054          if (DBG==1)          if (DBG==1)
1055                  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 );
1056          return Cost;          return Cost;
# Line 1104  Line 1082 
1082          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 */
1083    
1084          int Run_Start = -1;          int Run_Start = -1;
1085          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1086          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1087    
1088          int Last_Node = -1;          int Last_Node = -1;
1089          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
# Line 1144  Line 1122 
1122                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
1123    
1124                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
1125                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1126                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
1127                          {                          {
1128                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1129                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1130                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1131    
1132                                  /*                                  /*
1133                                   * 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 1203 
1203   * 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:
1204   *        if (Cost_Base>=Best_Cost) continue;   *        if (Cost_Base>=Best_Cost) continue;
1205   */   */
1206                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1207                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1208    
1209                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1210                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1240  Line 1218 
1218                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
1219                                  }                                  }
1220    
1221                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1222                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1223    
1224                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1225                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1287  Line 1265 
1265                           * it a chance by not moving the left barrier too much.                           * it a chance by not moving the left barrier too much.
1266                           */                           */
1267    
1268                          while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1269                                  Run_Start++;                                  Run_Start++;
1270    
1271                          /* 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.32

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