[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.12, Mon May 12 12:33:16 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  {  {
125          int i;          int scaler_lum, scaler_chr;
126            quant_intraFuncPtr quant;
127    
128          for (i = 0; i < 6; i++) {          /* check if quant matrices need to be re-initialized with new quant */
129                  uint32_t iDcScaler = get_dc_scaler(pMB->quant, i < 4);          if (pParam->vol_flags & XVID_VOL_MPEGQUANT) {
130                    if (pParam->last_quant_initialized_intra != pMB->quant) {
131                            init_intra_matrix(pParam->mpeg_quant_matrices, pMB->quant);
132                    }
133                    quant = quant_mpeg_intra;
134            } else {
135                    quant = quant_h263_intra;
136            }
137    
138            scaler_lum = get_dc_scaler(pMB->quant, 1);
139            scaler_chr = get_dc_scaler(pMB->quant, 0);
140    
141                  /* Quantize the block */                  /* Quantize the block */
142                  start_timer();                  start_timer();
143                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT)) {          quant(&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
144                          quant_intra(&data[i * 64], &qcoeff[i * 64], pMB->quant, iDcScaler);          quant(&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145                  } else {          quant(&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
146                          quant4_intra(&data[i * 64], &qcoeff[i * 64], pMB->quant, iDcScaler);          quant(&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
147                  }          quant(&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
148            quant(&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
149                  stop_quant_timer();                  stop_quant_timer();
150          }          }
 }  
151    
152  /* DeQuantize all blocks -- Intra mode */  /* DeQuantize all blocks -- Intra mode */
153  static __inline void  static __inline void
# Line 146  Line 156 
156                             int16_t qcoeff[6 * 64],                             int16_t qcoeff[6 * 64],
157                             int16_t data[6*64])                             int16_t data[6*64])
158  {  {
159          int i;          int mpeg;
160            int scaler_lum, scaler_chr;
161    
162          for (i = 0; i < 6; i++) {          quant_intraFuncPtr const dequant[2] =
163                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);                  {
164                            dequant_h263_intra,
165                            dequant_mpeg_intra
166                    };
167    
168            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
169            scaler_lum = get_dc_scaler(iQuant, 1);
170            scaler_chr = get_dc_scaler(iQuant, 0);
171    
172                  start_timer();                  start_timer();
173                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT))          dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
174                          dequant_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);          dequant[mpeg](&qcoeff[1 * 64], &data[1 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
175                  else          dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
176                          dequant4_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);          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, pParam->mpeg_quant_matrices);
178            dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
179                  stop_iquant_timer();                  stop_iquant_timer();
180          }          }
 }  
   
181    
182  static int  static int
183  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,
184                                               const int16_t *const In,
185  static int                                             int Q,
186  dct_quantize_trellis_mpeg_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero);                                             const uint16_t * const Zigzag,
187                                               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 182  Line 203 
203          int i;          int i;
204          uint8_t cbp = 0;          uint8_t cbp = 0;
205          int sum;          int sum;
206          int code_block;          int code_block, mpeg;
207    
208            quant_interFuncPtr const quant[2] =
209                    {
210                            quant_h263_inter,
211                            quant_mpeg_inter
212                    };
213    
214            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
215    
216          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
217    
218                  /* Quantize the block */                  /* Quantize the block */
219                  start_timer();                  start_timer();
220                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT)) {  
221                          sum = quant_inter(&qcoeff[i*64], &data[i*64], pMB->quant);                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);
222                          if ( (sum) && (frame->vop_flags & XVID_VOP_TRELLISQUANT) ) {  
223                                  sum = dct_quantize_trellis_h263_c(&qcoeff[i*64], &data[i*64], pMB->quant, &scan_tables[0][0], 63)+1;                  if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
224                                  limit = 1;                          const uint16_t *matrix;
225                          }                          const static uint16_t h263matrix[] =
226                  } else {                                  {
227                          sum = quant4_inter(&qcoeff[i * 64], &data[i * 64], pMB->quant);                                          16, 16, 16, 16, 16, 16, 16, 16,
228  //                      if ( (sum) && (frame->vop_flags & XVID_VOP_TRELLISQUANT) )                                          16, 16, 16, 16, 16, 16, 16, 16,
229  //                              sum = dct_quantize_trellis_mpeg_c (&qcoeff[i*64], &data[i*64], pMB->quant)+1;                                          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                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
238                            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 236  Line 279 
279                             int16_t qcoeff[6 * 64],                             int16_t qcoeff[6 * 64],
280                             const uint8_t cbp)                             const uint8_t cbp)
281  {  {
282          int i;          int mpeg;
283    
284            quant_interFuncPtr const dequant[2] =
285                    {
286                            dequant_h263_inter,
287                            dequant_mpeg_inter
288                    };
289    
290            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
291    
         for (i = 0; i < 6; i++) {  
                 if (cbp & (1 << (5 - i))) {  
292                          start_timer();                          start_timer();
293                          if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT))          if(cbp & (1 << (5 - 0))) dequant[mpeg](&data[0 * 64], &qcoeff[0 * 64], iQuant, pParam->mpeg_quant_matrices);
294                                  dequant_inter(&data[i * 64], &qcoeff[i * 64], iQuant);          if(cbp & (1 << (5 - 1))) dequant[mpeg](&data[1 * 64], &qcoeff[1 * 64], iQuant, pParam->mpeg_quant_matrices);
295                          else          if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant, pParam->mpeg_quant_matrices);
296                                  dequant4_inter(&data[i * 64], &qcoeff[i * 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, pParam->mpeg_quant_matrices);
298            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    
302  typedef void (transfer_operation_8to16_t) (int16_t *Dst, const uint8_t *Src, int BpS);  typedef void (transfer_operation_8to16_t) (int16_t *Dst, const uint8_t *Src, int BpS);
303  typedef void (transfer_operation_16to8_t) (uint8_t *Dst, const int16_t *Src, int BpS);  typedef void (transfer_operation_16to8_t) (uint8_t *Dst, const int16_t *Src, int BpS);
# Line 265  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;  
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 *transfer_op = NULL;  
   
         if ((frame->vop_flags & XVID_VOP_REDUCED)) {  
   
                 /* Image pointers */  
                 pY_Cur = pCurrent->y + (y_pos << 5) * stride  + (x_pos << 5);  
                 pU_Cur = pCurrent->u + (y_pos << 4) * stride2 + (x_pos << 4);  
                 pV_Cur = pCurrent->v + (y_pos << 4) * stride2 + (x_pos << 4);  
   
                 /* Block size */  
                 cst = 16;  
   
                 /* Operation function */  
                 transfer_op = (transfer_operation_8to16_t*)filter_18x18_to_8x8;  
         } else {  
319    
320                  /* Image pointers */                  /* Image pointers */
321                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
322                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
323                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
324    
                 /* Block size */  
                 cst = 8;  
   
                 /* Operation function */  
                 transfer_op = (transfer_operation_8to16_t*)transfer_8to16copy;  
         }  
   
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 314  Line 340 
340                           const uint32_t x_pos,                           const uint32_t x_pos,
341                           const uint32_t y_pos,                           const uint32_t y_pos,
342                           int16_t data[6 * 64],                           int16_t data[6 * 64],
343                           const uint32_t add,                           const uint32_t add, /* Must be 1 or 0 */
344                           const uint8_t cbp)                           const uint8_t cbp)
345  {  {
346          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
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;  
350          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
         transfer_operation_16to8_t *transfer_op = NULL;  
   
         if (pMB->field_dct) {  
                 next_block = stride;  
                 stride *= 2;  
         }  
   
         if ((frame->vop_flags & XVID_VOP_REDUCED)) {  
351    
352                  /* Image pointers */          /* Array of function pointers, indexed by [add] */
353                  pY_Cur = pCurrent->y + (y_pos << 5) * stride  + (x_pos << 5);          transfer_operation_16to8_t  * const functions[2] =
354                  pU_Cur = pCurrent->u + (y_pos << 4) * stride2 + (x_pos << 4);                  {
355                  pV_Cur = pCurrent->v + (y_pos << 4) * stride2 + (x_pos << 4);                          (transfer_operation_16to8_t*)transfer_16to8copy,
356                            (transfer_operation_16to8_t*)transfer_16to8add,
357                  /* Block size */                  };
                 cst = 16;  
358    
359                  /* Operation function */          transfer_operation_16to8_t *transfer_op = NULL;
                 if(add)  
                         transfer_op = (transfer_operation_16to8_t*)add_upsampled_8x8_16to8;  
                 else  
                         transfer_op = (transfer_operation_16to8_t*)copy_upsampled_8x8_16to8;  
         } else {  
360    
361                  /* Image pointers */                  /* Image pointers */
362                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
363                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
364                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
365    
366                  /* Block size */          if (pMB->field_dct) {
367                  cst = 8;                  next_block = stride;
368                    stride *= 2;
369            }
370    
371                  /* Operation function */                  /* Operation function */
372                  if(add)          transfer_op = functions[add];
                         transfer_op = (transfer_operation_16to8_t*)transfer_16to8add;  
                 else  
                         transfer_op = (transfer_operation_16to8_t*)transfer_16to8copy;  
         }  
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 419  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 430  Line 437 
437          /* Set the limit threshold */          /* Set the limit threshold */
438          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);
439    
440            if (frame->vop_flags & XVID_VOP_CARTOON)
441                    limit *= 3;
442    
443          /* Quantize the block */          /* Quantize the block */
444          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);
445    
# Line 457  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 468  Line 476 
476          /* Set the limit threshold */          /* Set the limit threshold */
477          limit = BVOP_TOOSMALL_LIMIT;          limit = BVOP_TOOSMALL_LIMIT;
478    
479            if (frame->vop_flags & XVID_VOP_CARTOON)
480                    limit *= 2;
481    
482          /* Quantize the block */          /* Quantize the block */
483          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);
484    
# Line 475  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 546  Line 557 
557    
558          /* left blocks */          /* left blocks */
559    
560          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
561          MOVLINE(tmp, LINE(0, 1));          MOVLINE(tmp, LINE(0, 1));
562          MOVLINE(LINE(0, 1), LINE(0, 2));          MOVLINE(LINE(0, 1), LINE(0, 2));
563          MOVLINE(LINE(0, 2), LINE(0, 4));          MOVLINE(LINE(0, 2), LINE(0, 4));
564          MOVLINE(LINE(0, 4), LINE(2, 0));          MOVLINE(LINE(0, 4), LINE(2, 0));
565          MOVLINE(LINE(2, 0), tmp);          MOVLINE(LINE(2, 0), tmp);
566    
567          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
568          MOVLINE(tmp, LINE(0, 3));          MOVLINE(tmp, LINE(0, 3));
569          MOVLINE(LINE(0, 3), LINE(0, 6));          MOVLINE(LINE(0, 3), LINE(0, 6));
570          MOVLINE(LINE(0, 6), LINE(2, 4));          MOVLINE(LINE(0, 6), LINE(2, 4));
571          MOVLINE(LINE(2, 4), LINE(2, 1));          MOVLINE(LINE(2, 4), LINE(2, 1));
572          MOVLINE(LINE(2, 1), tmp);          MOVLINE(LINE(2, 1), tmp);
573    
574          // 5=10, 10=5          /* 5=10, 10=5 */
575          MOVLINE(tmp, LINE(0, 5));          MOVLINE(tmp, LINE(0, 5));
576          MOVLINE(LINE(0, 5), LINE(2, 2));          MOVLINE(LINE(0, 5), LINE(2, 2));
577          MOVLINE(LINE(2, 2), tmp);          MOVLINE(LINE(2, 2), tmp);
578    
579          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
580          MOVLINE(tmp, LINE(0, 7));          MOVLINE(tmp, LINE(0, 7));
581          MOVLINE(LINE(0, 7), LINE(2, 6));          MOVLINE(LINE(0, 7), LINE(2, 6));
582          MOVLINE(LINE(2, 6), LINE(2, 5));          MOVLINE(LINE(2, 6), LINE(2, 5));
# Line 574  Line 585 
585    
586          /* right blocks */          /* right blocks */
587    
588          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
589          MOVLINE(tmp, LINE(1, 1));          MOVLINE(tmp, LINE(1, 1));
590          MOVLINE(LINE(1, 1), LINE(1, 2));          MOVLINE(LINE(1, 1), LINE(1, 2));
591          MOVLINE(LINE(1, 2), LINE(1, 4));          MOVLINE(LINE(1, 2), LINE(1, 4));
592          MOVLINE(LINE(1, 4), LINE(3, 0));          MOVLINE(LINE(1, 4), LINE(3, 0));
593          MOVLINE(LINE(3, 0), tmp);          MOVLINE(LINE(3, 0), tmp);
594    
595          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
596          MOVLINE(tmp, LINE(1, 3));          MOVLINE(tmp, LINE(1, 3));
597          MOVLINE(LINE(1, 3), LINE(1, 6));          MOVLINE(LINE(1, 3), LINE(1, 6));
598          MOVLINE(LINE(1, 6), LINE(3, 4));          MOVLINE(LINE(1, 6), LINE(3, 4));
599          MOVLINE(LINE(3, 4), LINE(3, 1));          MOVLINE(LINE(3, 4), LINE(3, 1));
600          MOVLINE(LINE(3, 1), tmp);          MOVLINE(LINE(3, 1), tmp);
601    
602          // 5=10, 10=5          /* 5=10, 10=5 */
603          MOVLINE(tmp, LINE(1, 5));          MOVLINE(tmp, LINE(1, 5));
604          MOVLINE(LINE(1, 5), LINE(3, 2));          MOVLINE(LINE(1, 5), LINE(3, 2));
605          MOVLINE(LINE(3, 2), tmp);          MOVLINE(LINE(3, 2), tmp);
606    
607          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
608          MOVLINE(tmp, LINE(1, 7));          MOVLINE(tmp, LINE(1, 7));
609          MOVLINE(LINE(1, 7), LINE(3, 6));          MOVLINE(LINE(1, 7), LINE(3, 6));
610          MOVLINE(LINE(3, 6), LINE(3, 5));          MOVLINE(LINE(3, 6), LINE(3, 5));
# Line 601  Line 612 
612          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
613  }  }
614    
615    /*****************************************************************************
616     *               Trellis based R-D optimal quantization
617     *
618     *   Trellis Quant code (C) 2003 Pascal Massimino skal(at)planet-d.net
619     *
620     ****************************************************************************/
621    
622    /*----------------------------------------------------------------------------
623     *
624     *        Trellis-Based quantization
625     *
626     * So far I understand this paper:
627     *
628     *  "Trellis-Based R-D Optimal Quantization in H.263+"
629     *    J.Wen, M.Luttrell, J.Villasenor
630     *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
631     *
632     * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
633     * Source Shortest Path algo. But due to the underlying graph structure
634     * ("Trellis"), it can be turned into a dynamic programming algo,
635     * partially saving the explicit graph's nodes representation. And
636     * without using a heap, since the open frontier of the DAG is always
637     * known, and of fixed size.
638     *--------------------------------------------------------------------------*/
639    
640    
641    
642  /************************************************************************  /* Codes lengths for relevant levels. */
  *               Trellis based R-D optimal quantization                 *  
  *                                                                      *  
  *   Trellis Quant code (C) 2003 Pascal Massimino skal(at)planet-d.net  *  
  *                                                                      *  
  ************************************************************************/  
   
   
 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; }  
   
   
 //////////////////////////////////////////////////////////  
 //  
 //        Trellis-Based quantization  
 //  
 // So far I understand this paper:  
 //  
 //  "Trellis-Based R-D Optimal Quantization in H.263+"  
 //    J.Wen, M.Luttrell, J.Villasenor  
 //    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.  
 //  
 // we are at stake with a simplified Bellmand-Ford / Dijkstra Single  
 // Source Shorted Path algo. But due to the underlying graph structure  
 // ("Trellis"), it can be turned into a dynamic programming algo,  
 // partially saving the explicit graph's nodes representation. And  
 // without using a heap, since the open frontier of the DAG is always  
 // known, and of fixed sized.  
 //  
 //////////////////////////////////////////////////////////  
   
   
 //////////////////////////////////////////////////////////  
 // Codes lengths for relevant levels.  
643    
644    // let's factorize:  /* let's factorize: */
645  static const uint8_t Code_Len0[64] = {  static const uint8_t Code_Len0[64] = {
646    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
647    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
# Line 707  Line 706 
706     3, 4, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9,10,10,10,10,10,10,10,10,12,12,13,13,12,13,14,15,15,     3, 4, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9,10,10,10,10,10,10,10,10,12,12,13,13,12,13,14,15,15,
707    15,16,16,16,16,17,17,17,18,18,19,19,19,19,19,19,19,19,21,21,22,22,30,30,30,30,30,30,30,30,30,30 };    15,16,16,16,16,17,17,17,18,18,19,19,19,19,19,19,19,19,21,21,22,22,30,30,30,30,30,30,30,30,30,30 };
708    
709    // a few more table for LAST table:  /* a few more table for LAST table: */
710  static const uint8_t Code_Len21[64] = {  static const uint8_t Code_Len21[64] = {
711    13,20,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,    13,20,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
712    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};
# Line 722  Line 721 
721    12,13,13,13,13,13,13,13,13,14,16,16,16,16,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19};    12,13,13,13,13,13,13,13,13,14,16,16,16,16,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19};
722    
723    
724  static const uint8_t * const B16_17_Code_Len[24] = { // levels [1..24]  static const uint8_t * const B16_17_Code_Len[24] = { /* levels [1..24] */
725    Code_Len20,Code_Len19,Code_Len18,Code_Len17,    Code_Len20,Code_Len19,Code_Len18,Code_Len17,
726    Code_Len16,Code_Len15,Code_Len14,Code_Len13,    Code_Len16,Code_Len15,Code_Len14,Code_Len13,
727    Code_Len12,Code_Len11,Code_Len10,Code_Len9,    Code_Len12,Code_Len11,Code_Len10,Code_Len9,
# Line 731  Line 730 
730    Code_Len2, Code_Len1, Code_Len1, Code_Len1,    Code_Len2, Code_Len1, Code_Len1, Code_Len1,
731  };  };
732    
733  static const uint8_t * const B16_17_Code_Len_Last[6] = { // levels [1..6]  static const uint8_t * const B16_17_Code_Len_Last[6] = { /* levels [1..6] */
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 745  Line 751 
751  };  };
752  #undef TL  #undef TL
753    
754  static __inline int Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)  static int __inline
755    Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)
756  {  {
757    while(i>=0)    while(i>=0)
758      if (C[Zigzag[i]])      if (C[Zigzag[i]])
# Line 754  Line 761 
761    return -1;    return -1;
762  }  }
763    
764  //////////////////////////////////////////////////////////  #define TRELLIS_MIN_EFFORT      3
 // this routine has been strippen of all debug code  
 //////////////////////////////////////////////////////////  
765    
766    /* 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 (In[]),          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
779      // not quantized one (Out[]). However, it only improves the result *very*           * (In[]), not quantized one (Out[]). However, it only improves the result
780      // slightly (~0.01dB), whereas speed drops to crawling level :)           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
781      // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
782             * 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;    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 -1;                  Non_Zero = TRELLIS_MIN_EFFORT;
806    
807            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    
   for(i=0; i<=Non_Zero; i++)  
   {  
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    
819      if ((uint32_t)(Level1+1)<3)                 // very specialized loop for -1,0,+1                  /* very specialized loop for -1,0,+1 */
820      {                  if ((uint32_t)(Level1+1)<3) {
821          int dQ;          int dQ;
822                  int Run;                  int Run;
823        uint32_t Cost0;        uint32_t Cost0;
# Line 814  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 840  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 if (51U>(uint32_t)(Level1+25)) {
861      else                      // "big" levels                          /* "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 858  Line 874 
874          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
875          Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;          Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;
876          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;
877        } else { // Level1<-1                          } else { /* Level1<-1 */
878          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
879          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
880          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 867  Line 883 
883          Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;          Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;
884          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;
885        }        }
886    
887        Dist1 = Lambda*dQ1*dQ1;        Dist1 = Lambda*dQ1*dQ1;
888        Dist2 = Lambda*dQ2*dQ2;        Dist2 = Lambda*dQ2*dQ2;
889        dDist21 = Dist2-Dist1;        dDist21 = Dist2-Dist1;
# Line 877  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, uncomment the following:                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
898  //        if (Cost_Base>=Best_Cost) continue;                                   * uncomment the following:
899  // (? doesn't seem to have any effect -- gruel )                                   *              if (Cost_Base>=Best_Cost) continue;
900                                     * (? 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;
907                           bLevel = Level2;                           bLevel = Level2;
908                    } else                                  } else {
909                           bLevel = Level1;                           bLevel = Level1;
910                                    }
911    
912          if (Cost1<Best_Cost) {          if (Cost1<Best_Cost) {
913            Best_Cost = Cost1;            Best_Cost = Cost1;
# Line 896  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;
923                           bLevel = Level2;                           bLevel = Level2;
924                    } else                                  } else {
925                           bLevel = Level1;                           bLevel = Level1;
926                                    }
927    
928          if (Cost1<Last_Cost) {          if (Cost1<Last_Cost) {
929            Last_Cost  = Cost1;            Last_Cost  = Cost1;
# Line 911  Line 931 
931            Last.Level = bLevel;            Last.Level = bLevel;
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    
960      if (Best_Cost < Min_Cost + Dist0) {      if (Best_Cost < Min_Cost + Dist0) {
961        Min_Cost = Best_Cost;        Min_Cost = Best_Cost;
962        Run_Start = i;        Run_Start = i;
963      }                  } else {
964      else                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
965      {                           * there's a code shorter by 1 bit for a larger run (!), same
966          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * level. We give it a chance by not moving the left barrier too
967          // a code shorter by 1 bit for a larger run (!), same level. We give                           * much. */
968          // it a chance by not moving the left barrier too much.                          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 leave the block untouched
979             * and return the original sum value */
980    if (Last_Node<0)    if (Last_Node<0)
981      return -1;                  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 = 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);
991      i -= Nodes[i].Run;      i -= Nodes[i].Run;
992    }    }
   return Last_Node;  
 }  
   
   
993    
994            return Sum;
995    }
996    
997    /* original version including heavy debugging info */
   
   
   
   
   
   
 //////////////////////////////////////////////////////////  
 // original version including heavy debugging info  
 //////////////////////////////////////////////////////////  
   
998    
999  #ifdef DBGTRELL  #ifdef DBGTRELL
1000    
# Line 987  Line 1018 
1018      int j=0, j0=0;      int j=0, j0=0;
1019      int Run, Level;      int Run, Level;
1020    
1021      Bits = 2;   // CBP                  Bits = 2;   /* CBP */
1022      while(j<Last) {      while(j<Last) {
1023        while(!C[Zigzag[j]])        while(!C[Zigzag[j]])
1024                          j++;                          j++;
# Line 1019  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 1034  Line 1065 
1065  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_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)
1066  {  {
1067    
1068      // Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),      /*
1069      // not quantized one (Out[]). However, it only improves the result *very*           * Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),
1070      // slightly (~0.01dB), whereas speed drops to crawling level :)           * not quantized one (Out[]). However, it only improves the result *very*
1071      // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,           * slightly (~0.01dB), whereas speed drops to crawling level :)
1072             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.
1073             */
1074    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
1075    
1076    NODE Nodes[65], Last;    NODE Nodes[65], Last;
# Line 1047  Line 1079 
1079    const int Mult = 2*Q;    const int Mult = 2*Q;
1080    const int Bias = (Q-1) | 1;    const int Bias = (Q-1) | 1;
1081    const int Lev0 = Mult + Bias;    const int Lev0 = Mult + Bias;
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 1059  Line 1091 
1091    int i, j;    int i, j;
1092    
1093  #if (DBG>0)  #if (DBG>0)
1094    Last.Level = 0; Last.Run = -1; // just initialize to smthg          Last.Level = 0; Last.Run = -1; /* just initialize to smthg */
1095  #endif  #endif
1096    
1097    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
# Line 1074  Line 1106 
1106      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
1107      Last_Cost += Dist0;      Last_Cost += Dist0;
1108    
1109      if ((uint32_t)(Level1+1)<3)                 // very specialized loop for -1,0,+1                  if ((uint32_t)(Level1+1)<3)                 /* very specialized loop for -1,0,+1 */
1110      {      {
1111          int dQ;          int dQ;
1112                  int Run;                  int Run;
# Line 1090  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            // TODO: what about tie-breaks? Should we favor short runs or                                  /*
1133            // long runs? Although the error is the same, it would not be                                   * TODO: what about tie-breaks? Should we favor short runs or
1134            // spread the same way along high and low frequencies...                                   * long runs? Although the error is the same, it would not be
1135                                     * spread the same way along high and low frequencies...
1136                                     */
1137          if (Cost<Best_Cost) {          if (Cost<Best_Cost) {
1138            Best_Cost    = Cost;            Best_Cost    = Cost;
1139            Nodes[i].Run = Run;            Nodes[i].Run = Run;
# Line 1129  Line 1163 
1163          printf( "\n" );          printf( "\n" );
1164        }        }
1165      }      }
1166      else                      // "big" levels                  else                      /* "big" levels */
1167      {      {
1168        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;
1169        int Level2;        int Level2;
# Line 1146  Line 1180 
1180          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
1181          Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;          Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;
1182          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;
1183        } else { // Level1<-1                          } else { /* Level1<-1 */
1184          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
1185          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
1186          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 1165  Line 1199 
1199          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
1200          int bLevel;          int bLevel;
1201    
1202  // for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:  /*
1203  //        if (Cost_Base>=Best_Cost) continue;   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1204     *        if (Cost_Base>=Best_Cost) continue;
1205          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);   */
1206          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1207                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1208    
1209          if (Cost2<Cost1) {          if (Cost2<Cost1) {
1210                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1183  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 1198  Line 1233 
1233            Last.Level = bLevel;            Last.Level = bLevel;
1234            Last_Node  = i;            Last_Node  = i;
1235          }          }
1236        } //end of "for Run"                          } /* end of "for Run" */
1237    
1238        if (DBG==1) {        if (DBG==1) {
1239          Run_Costs[i] = Best_Cost;          Run_Costs[i] = Best_Cost;
# Line 1224  Line 1259 
1259      }      }
1260      else      else
1261      {      {
1262          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                          /*
1263          // a code shorter by 1 bit for a larger run (!), same level. We give                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's
1264          // it a chance by not moving the left barrier too much.                           * a code shorter by 1 bit for a larger run (!), same level. We give
1265                             * 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 */
1272        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1273        Min_Cost += Dist0;        Min_Cost += Dist0;
1274      }      }
# Line 1249  Line 1286 
1286    if (Last_Node<0)    if (Last_Node<0)
1287      return -1;      return -1;
1288    
1289         // reconstruct optimal sequence backward with surviving paths          /* reconstruct optimal sequence backward with surviving paths */
1290    memset(Out, 0x00, 64*sizeof(*Out));    memset(Out, 0x00, 64*sizeof(*Out));
1291    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
1292    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;

Legend:
Removed from v.1.21.2.12  
changed lines
  Added in v.1.32

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