[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.33, Sun Nov 28 15:18:21 2010 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /*****************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - MB Transfert/Quantization functions -   *  - MB Transfer/Quantization functions -
5   *   *
6   *  Copyright(C) 2001-2003  Peter Ross <pross@xvid.org>   *  Copyright(C) 2001-2010  Peter Ross <pross@xvid.org>
7   *               2001-2003  Michael Militzer <isibaar@xvid.org>   *               2001-2010  Michael Militzer <michael@xvid.org>
8   *               2003       Edouard Gomez <ed.gomez@free.fr>   *               2003       Edouard Gomez <ed.gomez@free.fr>
9   *   *
10   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
# Line 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"
43  #include "../quant/quant_h263.h"  #include "../motion/sad.h"
44  #include "../encoder.h"  #include "../encoder.h"
45    
46  #include "../image/reduced.h"  #include  "../quant/quant_matrix.h"
47    
48  MBFIELDTEST_PTR MBFieldTest;  MBFIELDTEST_PTR MBFieldTest;
49    
# Line 91  Line 91 
91    
92          /* Perform DCT */          /* Perform DCT */
93          start_timer();          start_timer();
94          fdct(&data[0 * 64]);          fdct((short * const)&data[0 * 64]);
95          fdct(&data[1 * 64]);          fdct((short * const)&data[1 * 64]);
96          fdct(&data[2 * 64]);          fdct((short * const)&data[2 * 64]);
97          fdct(&data[3 * 64]);          fdct((short * const)&data[3 * 64]);
98          fdct(&data[4 * 64]);          fdct((short * const)&data[4 * 64]);
99          fdct(&data[5 * 64]);          fdct((short * const)&data[5 * 64]);
100          stop_dct_timer();          stop_dct_timer();
101  }  }
102    
# Line 106  Line 106 
106             const uint8_t cbp)             const uint8_t cbp)
107  {  {
108          start_timer();          start_timer();
109          if(cbp & (1 << (5 - 0))) idct(&data[0 * 64]);          if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]);
110          if(cbp & (1 << (5 - 1))) idct(&data[1 * 64]);          if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]);
111          if(cbp & (1 << (5 - 2))) idct(&data[2 * 64]);          if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]);
112          if(cbp & (1 << (5 - 3))) idct(&data[3 * 64]);          if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]);
113          if(cbp & (1 << (5 - 4))) idct(&data[4 * 64]);          if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]);
114          if(cbp & (1 << (5 - 5))) idct(&data[5 * 64]);          if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]);
115          stop_idct_timer();          stop_idct_timer();
116  }  }
117    
# Line 123  Line 123 
123                           int16_t qcoeff[6 * 64],                           int16_t qcoeff[6 * 64],
124                           int16_t data[6*64])                           int16_t data[6*64])
125  {  {
         int mpeg;  
126          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
127            quant_intraFuncPtr quant;
128    
129          quanth263_intraFuncPtr const quant[2] =          /* check if quant matrices need to be re-initialized with new quant */
130                  {          if (pParam->vol_flags & XVID_VOL_MPEGQUANT) {
131                          (quanth263_intraFuncPtr)quant_intra,                  if (pParam->last_quant_initialized_intra != pMB->quant) {
132                          (quanth263_intraFuncPtr)quant4_intra                          init_intra_matrix(pParam->mpeg_quant_matrices, pMB->quant);
133                  };                  }
134                    quant = quant_mpeg_intra;
135            } else {
136                    quant = quant_h263_intra;
137            }
138    
         mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);  
139          scaler_lum = get_dc_scaler(pMB->quant, 1);          scaler_lum = get_dc_scaler(pMB->quant, 1);
140          scaler_chr = get_dc_scaler(pMB->quant, 0);          scaler_chr = get_dc_scaler(pMB->quant, 0);
141    
142          /* Quantize the block */          /* Quantize the block */
143          start_timer();          start_timer();
144          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum);          quant(&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145          quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum);          quant(&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
146          quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum);          quant(&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
147          quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum);          quant(&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
148          quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr);          quant(&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
149          quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr);          quant(&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
150          stop_quant_timer();          stop_quant_timer();
151  }  }
152    
# Line 157  Line 160 
160          int mpeg;          int mpeg;
161          int scaler_lum, scaler_chr;          int scaler_lum, scaler_chr;
162    
163          quanth263_intraFuncPtr const dequant[2] =          quant_intraFuncPtr const dequant[2] =
164                  {                  {
165                          (quanth263_intraFuncPtr)dequant_intra,                          dequant_h263_intra,
166                          (quanth263_intraFuncPtr)dequant4_intra                          dequant_mpeg_intra
167                  };                  };
168    
169          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 168  Line 171 
171          scaler_chr = get_dc_scaler(iQuant, 0);          scaler_chr = get_dc_scaler(iQuant, 0);
172    
173          start_timer();          start_timer();
174          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);
175          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);
176          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);
177          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);
178          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);
179          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);
180          stop_iquant_timer();          stop_iquant_timer();
181  }  }
182    
   
 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);  
   
183  static int  static int
184  dct_quantize_trellis_h263_c(int16_t *const Out,  dct_quantize_trellis_c(int16_t *const Out,
185                                                          const int16_t *const In,                                                          const int16_t *const In,
186                                                          int Q,                                                          int Q,
187                                                          const uint16_t * const Zigzag,                                                          const uint16_t * const Zigzag,
188                                                          int Non_Zero);                                             const uint16_t * const QuantMatrix,
189                                               int Non_Zero,
190  static int                                             int Sum,
191  dct_quantize_trellis_mpeg_c(int16_t *const Out,                                             int Lambda_Mod,
192                                                          const int16_t *const In,                                             const uint32_t rel_var8,
193                                                          int Q,                                             const int Metric);
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero);  
194    
195  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
196  static __inline uint8_t  static __inline uint8_t
# Line 214  Line 208 
208          int sum;          int sum;
209          int code_block, mpeg;          int code_block, mpeg;
210    
211          quanth263_interFuncPtr const quant[2] =          quant_interFuncPtr const quant[2] =
212                  {                  {
213                          (quanth263_interFuncPtr)quant_inter,                          quant_h263_inter,
214                          (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  
215                  };                  };
216    
217          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
# Line 233  Line 221 
221                  /* Quantize the block */                  /* Quantize the block */
222                  start_timer();                  start_timer();
223    
224                  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);
225    
226                    if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
227                            const uint16_t *matrix;
228                            const static uint16_t h263matrix[] =
229                                    {
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                                            16, 16, 16, 16, 16, 16, 16, 16,
236                                            16, 16, 16, 16, 16, 16, 16, 16,
237                                            16, 16, 16, 16, 16, 16, 16, 16
238                                    };
239    
240                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {                          matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
241                          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],
242                                                                                     pMB->quant, &scan_tables[0][0],
243                                                                                     matrix,
244                                                                                     63,
245                                                                                     sum,
246                                                                                     pMB->lambda[i],
247                                                                                     pMB->rel_var8[i],
248                                                                                     !!(frame->vop_flags & XVID_VOP_RD_PSNRHVSM));
249                  }                  }
250                  stop_quant_timer();                  stop_quant_timer();
251    
# Line 277  Line 286 
286  {  {
287          int mpeg;          int mpeg;
288    
289          quanth263_interFuncPtr const dequant[2] =          quant_interFuncPtr const dequant[2] =
290                  {                  {
291                          (quanth263_interFuncPtr)dequant_inter,                          dequant_h263_inter,
292                          (quanth263_interFuncPtr)dequant4_inter                          dequant_mpeg_inter
293                  };                  };
294    
295          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
296    
297          start_timer();          start_timer();
298          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);
299          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);
300          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);
301          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);
302          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);
303          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);
304          stop_iquant_timer();          stop_iquant_timer();
305  }  }
306    
# Line 310  Line 319 
319          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
320          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
321          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
         int vop_reduced;  
322          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
323          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
         transfer_operation_8to16_t * const functions[2] =  
                 {  
                         (transfer_operation_8to16_t *)transfer_8to16copy,  
                         (transfer_operation_8to16_t *)filter_18x18_to_8x8  
                 };  
         transfer_operation_8to16_t *transfer_op = NULL;  
   
         vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);  
324    
325          /* Image pointers */          /* Image pointers */
326          pY_Cur = pCurrent->y + (y_pos << (4+vop_reduced)) * stride  + (x_pos << (4+vop_reduced));          pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
327          pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
328          pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
   
         /* Block size */  
         cst = 8<<vop_reduced;  
   
         /* Operation function */  
         transfer_op = functions[vop_reduced];  
329    
330          /* Do the transfer */          /* Do the transfer */
331          start_timer();          start_timer();
332          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
333          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
334          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
335          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
336          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
337          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
338          stop_transfer_timer();          stop_transfer_timer();
339  }  }
340    
# Line 359  Line 352 
352          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
353          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
354          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
         int vop_reduced;  
355          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
356          /* Array of function pointers, indexed by [vop_reduced<<1+add] */  
357          transfer_operation_16to8_t  * const functions[4] =          /* Array of function pointers, indexed by [add] */
358            transfer_operation_16to8_t  * const functions[2] =
359                  {                  {
360                          (transfer_operation_16to8_t*)transfer_16to8copy,                          (transfer_operation_16to8_t*)transfer_16to8copy,
361                          (transfer_operation_16to8_t*)transfer_16to8add,                          (transfer_operation_16to8_t*)transfer_16to8add,
                         (transfer_operation_16to8_t*)copy_upsampled_8x8_16to8,  
                         (transfer_operation_16to8_t*)add_upsampled_8x8_16to8  
362                  };                  };
363    
364          transfer_operation_16to8_t *transfer_op = NULL;          transfer_operation_16to8_t *transfer_op = NULL;
365    
366            /* Image pointers */
367            pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
368            pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
369            pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
370    
371          if (pMB->field_dct) {          if (pMB->field_dct) {
372                  next_block = stride;                  next_block = stride;
373                  stride *= 2;                  stride *= 2;
374          }          }
375    
         /* 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;  
   
376          /* Operation function */          /* Operation function */
377          transfer_op = functions[(vop_reduced<<1) + add];          transfer_op = functions[add];
378    
379          /* Do the operation */          /* Do the operation */
380          start_timer();          start_timer();
381          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);
382          if (cbp&16) transfer_op(pY_Cur + cst,              &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
383          if (cbp& 8) transfer_op(pY_Cur + next_block,       &data[2 * 64], stride);          if (cbp& 8) transfer_op(pY_Cur + next_block,       &data[2 * 64], stride);
384          if (cbp& 4) transfer_op(pY_Cur + next_block + cst, &data[3 * 64], stride);          if (cbp& 4) transfer_op(pY_Cur + next_block + 8,        &data[3 * 64], stride);
385          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);
386          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);
387          stop_transfer_timer();          stop_transfer_timer();
# Line 449  Line 433 
433          uint8_t cbp;          uint8_t cbp;
434          uint32_t limit;          uint32_t limit;
435    
436          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
437           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
438    
439          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
440          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 490  Line 472 
472          uint8_t cbp;          uint8_t cbp;
473          uint32_t limit;          uint32_t limit;
474    
475          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
476           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
477    
478          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
479          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 511  Line 491 
491           * History comment:           * History comment:
492           * 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.
493           *           *
494           * 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
495           * to take care of that here           * have to take care of that here
496           */           */
497          if((pParam->plugin_flags & XVID_REQORIGINAL)) {          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
498    
# Line 637  Line 617 
617          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
618  }  }
619    
   
   
   
   
620  /*****************************************************************************  /*****************************************************************************
621   *               Trellis based R-D optimal quantization   *               Trellis based R-D optimal quantization
622   *   *
# Line 648  Line 624 
624   *   *
625   ****************************************************************************/   ****************************************************************************/
626    
   
 #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  
   
627  /*----------------------------------------------------------------------------  /*----------------------------------------------------------------------------
628   *   *
629   *        Trellis-Based quantization   *        Trellis-Based quantization
# Line 672  Line 635 
635   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
636   *   *
637   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
638   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
639   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
640   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
641   * 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
642   * known, and of fixed sized.   * known, and of fixed size.
643   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
644    
645    
# Line 776  Line 739 
739          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
740  };  };
741    
742  #define TL(q) 0xfe00/(q*q)  /* TL_SHIFT controls the precision of the RD optimizations in trellis
743     * valid range is [10..16]. The bigger, the more trellis is vulnerable
744     * to overflows in cost formulas.
745     *  - 10 allows ac values up to 2^11 == 2048
746     *  - 16 allows ac values up to 2^8 == 256
747     */
748    #define TL_SHIFT 11
749    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
750    
751  static const int Trellis_Lambda_Tabs[31] = {  static const int Trellis_Lambda_Tabs[31] = {
752          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 766 
766          return -1;          return -1;
767  }  }
768    
769  static int __inline  #define TRELLIS_MIN_EFFORT      3
770  Compute_Sum(const int16_t *C, int last)  
771    static __inline uint32_t calc_mseh(int16_t dQ, uint16_t mask,
772                                       const int index, const int Lambda)
773  {  {
774          int sum = 0;          uint32_t t = (mask * Inv_iMask_Coeff[index] + 32) >> 7;
775            uint16_t u = abs(dQ) << 4;
776            uint16_t thresh = (t < 65536) ? t : 65535;
777    
778          while(last--)          if (u <= thresh)
779                  sum += abs(C[last]);                  u = 0; /* The error is not perceivable */
780            else
781                    u -= thresh;
782    
783            u = ((u + iCSF_Round[index]) * iCSF_Coeff[index]) >> 16;
784    
785          return(sum);          return (((Lambda*u*u)>>4) + 4*Lambda*dQ*dQ) / 5;
786  }  }
 /* this routine has been strippen of all debug code */  
787    
788    /* this routine has been strippen of all debug code */
789  static int  static int
790  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,
791                                               const int16_t *const In,
792                                               int Q,
793                                               const uint16_t * const Zigzag,
794                                               const uint16_t * const QuantMatrix,
795                                               int Non_Zero,
796                                               int Sum,
797                                               int Lambda_Mod,
798                                               const uint32_t rel_var8,
799                                               const int Metric)
800  {  {
801    
802      /*          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
803           * 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
804           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
805           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
806           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
807          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
808    
809          NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
810          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
811          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
812          const int Mult = 2*Q;  
813          const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
814          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 */  
815    
816          int Run_Start = -1;          int Run_Start = -1;
817          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
818    
819          int Last_Node = -1;          int Last_Node = -1;
820          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
821    
822          int i, j, sum;          int i, j;
823          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */  
824            uint32_t mask = (Metric) ? ((isqrt(2*coeff8_energy(In)*rel_var8) + 48) >> 6) : 0;
825    
826            /* source (w/ CBP penalty) */
827            Run_Costs[-1] = 2<<TL_SHIFT;
828    
829          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
830          if (Non_Zero<0)          if (Non_Zero < TRELLIS_MIN_EFFORT)
831                  return 0; /* Sum is zero if there are only zero coeffs */                  Non_Zero = TRELLIS_MIN_EFFORT;
832    
833          for(i=0; i<=Non_Zero; i++) {          for(i=0; i<=Non_Zero; i++) {
834                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
835                    const int Mult = 2*q;
836                    const int Bias = (q-1) | 1;
837                    const int Lev0 = Mult + Bias;
838    
839                  const int AC = In[Zigzag[i]];                  const int AC = In[Zigzag[i]];
840                  const int Level1 = Out[Zigzag[i]];                  const int Level1 = Out[Zigzag[i]];
841                  const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = (Metric) ? (calc_mseh(AC, mask, Zigzag[i], Lambda)) : (Lambda* AC*AC);
842                  uint32_t Best_Cost = 0xf0000000;                  uint32_t Best_Cost = 0xf0000000;
843                  Last_Cost += Dist0;                  Last_Cost += Dist0;
844    
# Line 861  Line 855 
855                                  Nodes[i].Level = 1;                                  Nodes[i].Level = 1;
856                                  dQ = Lev0 - AC;                                  dQ = Lev0 - AC;
857                          }                          }
858                          Cost0 = Lambda*dQ*dQ;                          Cost0 = (Metric) ? (calc_mseh(dQ, mask, Zigzag[i], Lambda)) : (Lambda*dQ*dQ);
859    
860                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
861                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
862                          for(Run=i-Run_Start; Run>0; --Run) {                          for(Run=i-Run_Start; Run>0; --Run) {
863                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
864                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
865                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
866    
867                                  /*                                  /* TODO: what about tie-breaks? Should we favor short runs or
                                  * TODO: what about tie-breaks? Should we favor short runs or  
868                                   * long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
869                                   * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                                  */  
870    
871                                  /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
872    
873                                  if (Cost<Best_Cost) {                                  if (Cost<Best_Cost) {
874                                          Best_Cost    = Cost;                                          Best_Cost    = Cost;
# Line 891  Line 883 
883                          }                          }
884                          if (Last_Node==i)                          if (Last_Node==i)
885                                  Last.Level = Nodes[i].Level;                                  Last.Level = Nodes[i].Level;
886                  } else { /* "big" levels */                  } else if (51U>(uint32_t)(Level1+25)) {
887                            /* "big" levels (not less than ESC3, though) */
888                          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;
889                          int Level2;                          int Level2;
890                          int dQ1, dQ2;                          int dQ1, dQ2;
# Line 917  Line 910 
910                                  Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;                                  Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;
911                          }                          }
912    
913                            if (Metric) {
914                                    Dist1 = calc_mseh(dQ1, mask, Zigzag[i], Lambda);
915                                    Dist2 = calc_mseh(dQ2, mask, Zigzag[i], Lambda);
916                            }
917                            else {
918                          Dist1 = Lambda*dQ1*dQ1;                          Dist1 = Lambda*dQ1*dQ1;
919                          Dist2 = Lambda*dQ2*dQ2;                          Dist2 = Lambda*dQ2*dQ2;
920                            }
921                          dDist21 = Dist2-Dist1;                          dDist21 = Dist2-Dist1;
922    
923                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
# Line 927  Line 926 
926                                  uint32_t Cost1, Cost2;                                  uint32_t Cost1, Cost2;
927                                  int bLevel;                                  int bLevel;
928    
929                                  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
930                                   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
931                                   *      if (Cost_Base>=Best_Cost) continue;                                   *      if (Cost_Base>=Best_Cost) continue;
932                                   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
                                  */  
933    
934                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
935                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
936    
937                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
938                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 949  Line 947 
947                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
948                                  }                                  }
949    
950                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
951                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
952    
953                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
954                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 966  Line 964 
964                                          Last_Node  = i;                                          Last_Node  = i;
965                                  }                                  }
966                          } /* end of "for Run" */                          } /* end of "for Run" */
967                    } else {
968                            /* Very very high levels, with no chance of being optimizable
969                             * => Simply pick best Run. */
970                            int Run;
971                            for(Run=i-Run_Start; Run>0; --Run) {
972                                    /* 30 bits + no distortion */
973                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
974                                    if (Cost<Best_Cost) {
975                                            Best_Cost = Cost;
976                                            Nodes[i].Run   = Run;
977                                            Nodes[i].Level = Level1;
978                                    }
979    
980                                    if (Cost<Last_Cost) {
981                                            Last_Cost  = Cost;
982                                            Last.Run   = Run;
983                                            Last.Level = Level1;
984                                            Last_Node  = i;
985                                    }
986                            }
987                  }                  }
988    
989    
990                  Run_Costs[i] = Best_Cost;                  Run_Costs[i] = Best_Cost;
991    
992                  if (Best_Cost < Min_Cost + Dist0) {                  if (Best_Cost < Min_Cost + Dist0) {
993                          Min_Cost = Best_Cost;                          Min_Cost = Best_Cost;
994                          Run_Start = i;                          Run_Start = i;
995                  } else {                  } else {
996                          /*                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
997                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * there's a code shorter by 1 bit for a larger run (!), same
998                           * 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
999                           * it a chance by not moving the left barrier too much.                           * much. */
1000                           */                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
   
                         while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
1001                                  Run_Start++;                                  Run_Start++;
1002    
1003                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
1004                             * one */
1005                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1006                          Min_Cost += Dist0;                          Min_Cost += Dist0;
1007                  }                  }
1008          }          }
1009    
1010          /* 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
1011           * quit (even if we did not modify it, upperlayer relies on this data) */           * and return the original sum value */
1012          if (Last_Node<0)          if (Last_Node<0)
1013                  return Compute_Sum(Out, Non_Zero);                  return Sum;
1014    
1015          /* reconstruct optimal sequence backward with surviving paths */          /* reconstruct optimal sequence backward with surviving paths */
1016          memset(Out, 0x00, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
1017          Out[Zigzag[Last_Node]] = Last.Level;          Out[Zigzag[Last_Node]] = Last.Level;
1018          i = Last_Node - Last.Run;          i = Last_Node - Last.Run;
1019          sum = 0;          Sum = abs(Last.Level);
1020          while(i>=0) {          while(i>=0) {
1021                  Out[Zigzag[i]] = Nodes[i].Level;                  Out[Zigzag[i]] = Nodes[i].Level;
1022                  sum += abs(Nodes[i].Level);                  Sum += abs(Nodes[i].Level);
1023                  i -= Nodes[i].Run;                  i -= Nodes[i].Run;
1024          }          }
1025    
1026          return sum;          return Sum;
 }  
   
 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);  
1027  }  }
1028    
1029  /* original version including heavy debugging info */  /* original version including heavy debugging info */
# Line 1072  Line 1082 
1082                  V -= Ref[Zigzag[i]];                  V -= Ref[Zigzag[i]];
1083                  Dist += V*V;                  Dist += V*V;
1084          }          }
1085          Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1086          if (DBG==1)          if (DBG==1)
1087                  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 );
1088          return Cost;          return Cost;
# Line 1104  Line 1114 
1114          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 */
1115    
1116          int Run_Start = -1;          int Run_Start = -1;
1117          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1118          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1119    
1120          int Last_Node = -1;          int Last_Node = -1;
1121          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
# Line 1144  Line 1154 
1154                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
1155    
1156                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
1157                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1158                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
1159                          {                          {
1160                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1161                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1162                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1163    
1164                                  /*                                  /*
1165                                   * 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 1235 
1235   * 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:
1236   *        if (Cost_Base>=Best_Cost) continue;   *        if (Cost_Base>=Best_Cost) continue;
1237   */   */
1238                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1239                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1240    
1241                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1242                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1240  Line 1250 
1250                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
1251                                  }                                  }
1252    
1253                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1254                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1255    
1256                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1257                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1287  Line 1297 
1297                           * it a chance by not moving the left barrier too much.                           * it a chance by not moving the left barrier too much.
1298                           */                           */
1299    
1300                          while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1301                                  Run_Start++;                                  Run_Start++;
1302    
1303                          /* 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.33

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