[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.10, Fri May 9 22:03:13 2003 UTC revision 1.30, Fri Dec 9 04:45:35 2005 UTC
# Line 25  Line 25 
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
28  #include <string.h>  #include <stdio.h>
29  #include <stdlib.h>  #include <stdlib.h>
30    #include <string.h>
31    
32  #include "../portab.h"  #include "../portab.h"
33  #include "mbfunctions.h"  #include "mbfunctions.h"
# Line 38  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 90  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 105  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 122  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 mpeg;
126            int scaler_lum, scaler_chr;
127    
128          for (i = 0; i < 6; i++) {          quant_intraFuncPtr const quant[2] =
129                  uint32_t iDcScaler = get_dc_scaler(pMB->quant, i < 4);                  {
130                            quant_h263_intra,
131                            quant_mpeg_intra
132                    };
133    
134            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
135            scaler_lum = get_dc_scaler(pMB->quant, 1);
136            scaler_chr = get_dc_scaler(pMB->quant, 0);
137    
138                  /* Quantize the block */                  /* Quantize the block */
139                  start_timer();                  start_timer();
140                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT)) {          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
141                          quant_intra(&data[i * 64], &qcoeff[i * 64], pMB->quant, iDcScaler);          quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
142                  } else {          quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
143                          quant4_intra(&data[i * 64], &qcoeff[i * 64], pMB->quant, iDcScaler);          quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
144                  }          quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
145            quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
146                  stop_quant_timer();                  stop_quant_timer();
147          }          }
 }  
148    
149  /* DeQuantize all blocks -- Intra mode */  /* DeQuantize all blocks -- Intra mode */
150  static __inline void  static __inline void
# Line 145  Line 153 
153                             int16_t qcoeff[6 * 64],                             int16_t qcoeff[6 * 64],
154                             int16_t data[6*64])                             int16_t data[6*64])
155  {  {
156          int i;          int mpeg;
157            int scaler_lum, scaler_chr;
158    
159          for (i = 0; i < 6; i++) {          quant_intraFuncPtr const dequant[2] =
160                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);                  {
161                            dequant_h263_intra,
162                            dequant_mpeg_intra
163                    };
164    
165            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
166            scaler_lum = get_dc_scaler(iQuant, 1);
167            scaler_chr = get_dc_scaler(iQuant, 0);
168    
169                  start_timer();                  start_timer();
170                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT))          dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
171                          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);
172                  else          dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
173                          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);
174            dequant[mpeg](&qcoeff[4 * 64], &data[4 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
175            dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
176                  stop_iquant_timer();                  stop_iquant_timer();
177          }          }
 }  
   
   
 static int  
 dct_quantize_trellis_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero);  
178    
179  static int  static int
180  dct_quantize_trellis_mpeg_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,
181                                               const int16_t *const In,
182                                               int Q,
183                                               const uint16_t * const Zigzag,
184                                               const uint16_t * const QuantMatrix,
185                                               int Non_Zero,
186                                               int Sum,
187                                               int Lambda_Mod);
188    
189  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
190  static __inline uint8_t  static __inline uint8_t
# Line 181  Line 200 
200          int i;          int i;
201          uint8_t cbp = 0;          uint8_t cbp = 0;
202          int sum;          int sum;
203          int code_block;          int code_block, mpeg;
204    
205            quant_interFuncPtr const quant[2] =
206                    {
207                            quant_h263_inter,
208                            quant_mpeg_inter
209                    };
210    
211            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
212    
213          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
214    
215                  /* Quantize the block */                  /* Quantize the block */
216                  start_timer();                  start_timer();
217                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT)) {  
218                          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);
219                          if ( (sum) && (frame->vop_flags & XVID_VOP_TRELLISQUANT) ) {  
220                                  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)) {
221                                  limit = 1;                          const uint16_t *matrix;
222                          }                          const static uint16_t h263matrix[] =
223                  } else {                                  {
224                          sum = quant4_inter(&qcoeff[i * 64], &data[i * 64], pMB->quant);                                          16, 16, 16, 16, 16, 16, 16, 16,
225  //                      if ( (sum) && (frame->vop_flags & XVID_VOP_TRELLISQUANT) )                                          16, 16, 16, 16, 16, 16, 16, 16,
226  //                              sum = dct_quantize_trellis_mpeg_c (&qcoeff[i*64], &data[i*64], pMB->quant)+1;                                          16, 16, 16, 16, 16, 16, 16, 16,
227                                            16, 16, 16, 16, 16, 16, 16, 16,
228                                            16, 16, 16, 16, 16, 16, 16, 16,
229                                            16, 16, 16, 16, 16, 16, 16, 16,
230                                            16, 16, 16, 16, 16, 16, 16, 16,
231                                            16, 16, 16, 16, 16, 16, 16, 16
232                                    };
233    
234                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
235                            sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
236                                                                                     pMB->quant, &scan_tables[0][0],
237                                                                                     matrix,
238                                                                                     63,
239                                                                                     sum,
240                                                                                     pMB->lambda[i]);
241                  }                  }
242                  stop_quant_timer();                  stop_quant_timer();
243    
# Line 235  Line 276 
276                             int16_t qcoeff[6 * 64],                             int16_t qcoeff[6 * 64],
277                             const uint8_t cbp)                             const uint8_t cbp)
278  {  {
279          int i;          int mpeg;
280    
281            quant_interFuncPtr const dequant[2] =
282                    {
283                            dequant_h263_inter,
284                            dequant_mpeg_inter
285                    };
286    
287            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
288    
         for (i = 0; i < 6; i++) {  
                 if (cbp & (1 << (5 - i))) {  
289                          start_timer();                          start_timer();
290                          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);
291                                  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);
292                          else          if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant, pParam->mpeg_quant_matrices);
293                                  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);
294            if(cbp & (1 << (5 - 4))) dequant[mpeg](&data[4 * 64], &qcoeff[4 * 64], iQuant, pParam->mpeg_quant_matrices);
295            if(cbp & (1 << (5 - 5))) dequant[mpeg](&data[5 * 64], &qcoeff[5 * 64], iQuant, pParam->mpeg_quant_matrices);
296                          stop_iquant_timer();                          stop_iquant_timer();
297                  }                  }
         }  
 }  
298    
299  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);
300  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 264  Line 311 
311          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
312          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
313          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
314          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
315          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
         transfer_operation_8to16_t *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 {  
316    
317                  /* Image pointers */                  /* Image pointers */
318                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
319                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
320                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
321    
                 /* Block size */  
                 cst = 8;  
   
                 /* Operation function */  
                 transfer_op = (transfer_operation_8to16_t*)transfer_8to16copy;  
         }  
   
322          /* Do the transfer */          /* Do the transfer */
323          start_timer();          start_timer();
324          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
325          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
326          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
327          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
328          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
329          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
330          stop_transfer_timer();          stop_transfer_timer();
331  }  }
332    
# Line 313  Line 337 
337                           const uint32_t x_pos,                           const uint32_t x_pos,
338                           const uint32_t y_pos,                           const uint32_t y_pos,
339                           int16_t data[6 * 64],                           int16_t data[6 * 64],
340                           const uint32_t add,                           const uint32_t add, /* Must be 1 or 0 */
341                           const uint8_t cbp)                           const uint8_t cbp)
342  {  {
343          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
344          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
345          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
346          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
347          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)) {  
   
                 /* 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);  
348    
349                  /* Block size */          /* Array of function pointers, indexed by [add] */
350                  cst = 16;          transfer_operation_16to8_t  * const functions[2] =
351                    {
352                            (transfer_operation_16to8_t*)transfer_16to8copy,
353                            (transfer_operation_16to8_t*)transfer_16to8add,
354                    };
355    
356                  /* 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 {  
357    
358                  /* Image pointers */                  /* Image pointers */
359                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
360                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
361                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
362    
363                  /* Block size */          if (pMB->field_dct) {
364                  cst = 8;                  next_block = stride;
365                    stride *= 2;
366            }
367    
368                  /* Operation function */                  /* Operation function */
369                  if(add)          transfer_op = functions[add];
                         transfer_op = (transfer_operation_16to8_t*)transfer_16to8add;  
                 else  
                         transfer_op = (transfer_operation_16to8_t*)transfer_16to8copy;  
         }  
370    
371          /* Do the operation */          /* Do the operation */
372          start_timer();          start_timer();
373          if (cbp&32) transfer_op(pY_Cur, &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur, &data[0 * 64], stride);
374          if (cbp&16) transfer_op(pY_Cur + cst, &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
375          if (cbp& 8) transfer_op(pY_Cur + next_block, &data[2 * 64], stride);          if (cbp& 8) transfer_op(pY_Cur + next_block, &data[2 * 64], stride);
376          if (cbp& 4) transfer_op(pY_Cur + next_block + cst, &data[3 * 64], stride);          if (cbp& 4) transfer_op(pY_Cur + next_block + 8,        &data[3 * 64], stride);
377          if (cbp& 2) transfer_op(pU_Cur, &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur, &data[4 * 64], stride2);
378          if (cbp& 1) transfer_op(pV_Cur, &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur, &data[5 * 64], stride2);
379          stop_transfer_timer();          stop_transfer_timer();
# Line 418  Line 425 
425          uint8_t cbp;          uint8_t cbp;
426          uint32_t limit;          uint32_t limit;
427    
428          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
429           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
430    
431          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
432          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 429  Line 434 
434          /* Set the limit threshold */          /* Set the limit threshold */
435          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);
436    
437            if (frame->vop_flags & XVID_VOP_CARTOON)
438                    limit *= 3;
439    
440          /* Quantize the block */          /* Quantize the block */
441          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);
442    
# Line 456  Line 464 
464          uint8_t cbp;          uint8_t cbp;
465          uint32_t limit;          uint32_t limit;
466    
467          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
468           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
469    
470          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
471          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 467  Line 473 
473          /* Set the limit threshold */          /* Set the limit threshold */
474          limit = BVOP_TOOSMALL_LIMIT;          limit = BVOP_TOOSMALL_LIMIT;
475    
476            if (frame->vop_flags & XVID_VOP_CARTOON)
477                    limit *= 2;
478    
479          /* Quantize the block */          /* Quantize the block */
480          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);
481    
# Line 474  Line 483 
483           * History comment:           * History comment:
484           * We don't have to DeQuant, iDCT and Transfer back data for B-frames.           * We don't have to DeQuant, iDCT and Transfer back data for B-frames.
485           *           *
486           * BUT some plugins require the original frame to be passed so we have           * BUT some plugins require the rebuilt original frame to be passed so we
487           * to take care of that here           * have to take care of that here
488           */           */
489          if((pParam->plugin_flags & XVID_REQORIGINAL)) {          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
490    
# Line 545  Line 554 
554    
555          /* left blocks */          /* left blocks */
556    
557          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
558          MOVLINE(tmp, LINE(0, 1));          MOVLINE(tmp, LINE(0, 1));
559          MOVLINE(LINE(0, 1), LINE(0, 2));          MOVLINE(LINE(0, 1), LINE(0, 2));
560          MOVLINE(LINE(0, 2), LINE(0, 4));          MOVLINE(LINE(0, 2), LINE(0, 4));
561          MOVLINE(LINE(0, 4), LINE(2, 0));          MOVLINE(LINE(0, 4), LINE(2, 0));
562          MOVLINE(LINE(2, 0), tmp);          MOVLINE(LINE(2, 0), tmp);
563    
564          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
565          MOVLINE(tmp, LINE(0, 3));          MOVLINE(tmp, LINE(0, 3));
566          MOVLINE(LINE(0, 3), LINE(0, 6));          MOVLINE(LINE(0, 3), LINE(0, 6));
567          MOVLINE(LINE(0, 6), LINE(2, 4));          MOVLINE(LINE(0, 6), LINE(2, 4));
568          MOVLINE(LINE(2, 4), LINE(2, 1));          MOVLINE(LINE(2, 4), LINE(2, 1));
569          MOVLINE(LINE(2, 1), tmp);          MOVLINE(LINE(2, 1), tmp);
570    
571          // 5=10, 10=5          /* 5=10, 10=5 */
572          MOVLINE(tmp, LINE(0, 5));          MOVLINE(tmp, LINE(0, 5));
573          MOVLINE(LINE(0, 5), LINE(2, 2));          MOVLINE(LINE(0, 5), LINE(2, 2));
574          MOVLINE(LINE(2, 2), tmp);          MOVLINE(LINE(2, 2), tmp);
575    
576          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
577          MOVLINE(tmp, LINE(0, 7));          MOVLINE(tmp, LINE(0, 7));
578          MOVLINE(LINE(0, 7), LINE(2, 6));          MOVLINE(LINE(0, 7), LINE(2, 6));
579          MOVLINE(LINE(2, 6), LINE(2, 5));          MOVLINE(LINE(2, 6), LINE(2, 5));
# Line 573  Line 582 
582    
583          /* right blocks */          /* right blocks */
584    
585          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
586          MOVLINE(tmp, LINE(1, 1));          MOVLINE(tmp, LINE(1, 1));
587          MOVLINE(LINE(1, 1), LINE(1, 2));          MOVLINE(LINE(1, 1), LINE(1, 2));
588          MOVLINE(LINE(1, 2), LINE(1, 4));          MOVLINE(LINE(1, 2), LINE(1, 4));
589          MOVLINE(LINE(1, 4), LINE(3, 0));          MOVLINE(LINE(1, 4), LINE(3, 0));
590          MOVLINE(LINE(3, 0), tmp);          MOVLINE(LINE(3, 0), tmp);
591    
592          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
593          MOVLINE(tmp, LINE(1, 3));          MOVLINE(tmp, LINE(1, 3));
594          MOVLINE(LINE(1, 3), LINE(1, 6));          MOVLINE(LINE(1, 3), LINE(1, 6));
595          MOVLINE(LINE(1, 6), LINE(3, 4));          MOVLINE(LINE(1, 6), LINE(3, 4));
596          MOVLINE(LINE(3, 4), LINE(3, 1));          MOVLINE(LINE(3, 4), LINE(3, 1));
597          MOVLINE(LINE(3, 1), tmp);          MOVLINE(LINE(3, 1), tmp);
598    
599          // 5=10, 10=5          /* 5=10, 10=5 */
600          MOVLINE(tmp, LINE(1, 5));          MOVLINE(tmp, LINE(1, 5));
601          MOVLINE(LINE(1, 5), LINE(3, 2));          MOVLINE(LINE(1, 5), LINE(3, 2));
602          MOVLINE(LINE(3, 2), tmp);          MOVLINE(LINE(3, 2), tmp);
603    
604          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
605          MOVLINE(tmp, LINE(1, 7));          MOVLINE(tmp, LINE(1, 7));
606          MOVLINE(LINE(1, 7), LINE(3, 6));          MOVLINE(LINE(1, 7), LINE(3, 6));
607          MOVLINE(LINE(3, 6), LINE(3, 5));          MOVLINE(LINE(3, 6), LINE(3, 5));
# Line 600  Line 609 
609          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
610  }  }
611    
612    /*****************************************************************************
613     *               Trellis based R-D optimal quantization
614     *
615     *   Trellis Quant code (C) 2003 Pascal Massimino skal(at)planet-d.net
616     *
617     ****************************************************************************/
618    
619    /*----------------------------------------------------------------------------
620     *
621     *        Trellis-Based quantization
622     *
623     * So far I understand this paper:
624     *
625     *  "Trellis-Based R-D Optimal Quantization in H.263+"
626     *    J.Wen, M.Luttrell, J.Villasenor
627     *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
628     *
629     * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
630     * Source Shortest Path algo. But due to the underlying graph structure
631     * ("Trellis"), it can be turned into a dynamic programming algo,
632     * partially saving the explicit graph's nodes representation. And
633     * without using a heap, since the open frontier of the DAG is always
634     * known, and of fixed size.
635     *--------------------------------------------------------------------------*/
636    
637    
638    
639  /************************************************************************  /* 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_inter_mpeg_c (int16_t *qcoeff, const int16_t *data, int quant)  
 { 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.  
640    
641    // let's factorize:  /* let's factorize: */
642  static const uint8_t Code_Len0[64] = {  static const uint8_t Code_Len0[64] = {
643    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,
644    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 705  Line 703 
703     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,
704    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 };
705    
706    // a few more table for LAST table:  /* a few more table for LAST table: */
707  static const uint8_t Code_Len21[64] = {  static const uint8_t Code_Len21[64] = {
708    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,
709    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 720  Line 718 
718    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};
719    
720    
721  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] */
722    Code_Len20,Code_Len19,Code_Len18,Code_Len17,    Code_Len20,Code_Len19,Code_Len18,Code_Len17,
723    Code_Len16,Code_Len15,Code_Len14,Code_Len13,    Code_Len16,Code_Len15,Code_Len14,Code_Len13,
724    Code_Len12,Code_Len11,Code_Len10,Code_Len9,    Code_Len12,Code_Len11,Code_Len10,Code_Len9,
# Line 729  Line 727 
727    Code_Len2, Code_Len1, Code_Len1, Code_Len1,    Code_Len2, Code_Len1, Code_Len1, Code_Len1,
728  };  };
729    
730  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] */
731    Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,    Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
732  };  };
733    
734  #define TL(q) 0xfe00/(q*q)  /* TL_SHIFT controls the precision of the RD optimizations in trellis
735     * valid range is [10..16]. The bigger, the more trellis is vulnerable
736     * to overflows in cost formulas.
737     *  - 10 allows ac values up to 2^11 == 2048
738     *  - 16 allows ac values up to 2^8 == 256
739     */
740    #define TL_SHIFT 11
741    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
742    
743  static const int Trellis_Lambda_Tabs[31] = {  static const int Trellis_Lambda_Tabs[31] = {
744           TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),           TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),
# Line 743  Line 748 
748  };  };
749  #undef TL  #undef TL
750    
751  static inline int Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)  static int __inline
752    Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)
753  {  {
754    while(i>=0)    while(i>=0)
755      if (C[Zigzag[i]])      if (C[Zigzag[i]])
# Line 752  Line 758 
758    return -1;    return -1;
759  }  }
760    
761  //////////////////////////////////////////////////////////  /* this routine has been strippen of all debug code */
762    static int
763    dct_quantize_trellis_c(int16_t *const Out,
764                                               const int16_t *const In,
765                                               int Q,
766                                               const uint16_t * const Zigzag,
767                                               const uint16_t * const QuantMatrix,
768                                               int Non_Zero,
769                                               int Sum,
770                                               int Lambda_Mod)
771    {
772    
773            /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
774             * (In[]), not quantized one (Out[]). However, it only improves the result
775             * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
776             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
777             * helps. */
778            typedef struct { int16_t Run, Level; } NODE;
779    
780            NODE Nodes[65], Last = { 0, 0};
781            uint32_t Run_Costs0[64+1];
782            uint32_t * const Run_Costs = Run_Costs0 + 1;
783    
784            /* it's 1/lambda, actually */
785            const int Lambda = (Lambda_Mod*Trellis_Lambda_Tabs[Q-1])>>LAMBDA_EXP;
786    
787            int Run_Start = -1;
788            uint32_t Min_Cost = 2<<TL_SHIFT;
789    
790            int Last_Node = -1;
791            uint32_t Last_Cost = 0;
792    
793            int i, j;
794    
795            /* source (w/ CBP penalty) */
796            Run_Costs[-1] = 2<<TL_SHIFT;
797    
798            Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
799            if (Non_Zero<0)
800                    return 0; /* Sum is zero if there are only zero coeffs */
801    
802            for(i=0; i<=Non_Zero; i++) {
803                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
804                    const int Mult = 2*q;
805                    const int Bias = (q-1) | 1;
806                    const int Lev0 = Mult + Bias;
807    
808                    const int AC = In[Zigzag[i]];
809                    const int Level1 = Out[Zigzag[i]];
810                    const unsigned int Dist0 = Lambda* AC*AC;
811                    uint32_t Best_Cost = 0xf0000000;
812                    Last_Cost += Dist0;
813    
814                    /* very specialized loop for -1,0,+1 */
815                    if ((uint32_t)(Level1+1)<3) {
816                            int dQ;
817                            int Run;
818                            uint32_t Cost0;
819    
820                            if (AC<0) {
821                                    Nodes[i].Level = -1;
822                                    dQ = Lev0 + AC;
823                            } else {
824                                    Nodes[i].Level = 1;
825                                    dQ = Lev0 - AC;
826                            }
827                            Cost0 = Lambda*dQ*dQ;
828    
829                            Nodes[i].Run = 1;
830                            Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
831                            for(Run=i-Run_Start; Run>0; --Run) {
832                                    const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
833                                    const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
834                                    const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
835    
836                                    /* TODO: what about tie-breaks? Should we favor short runs or
837                                     * long runs? Although the error is the same, it would not be
838                                     * spread the same way along high and low frequencies... */
839    
840                                    /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
841    
842                                    if (Cost<Best_Cost) {
843                                            Best_Cost        = Cost;
844                                            Nodes[i].Run = Run;
845                                    }
846    
847                                    if (lCost<Last_Cost) {
848                                            Last_Cost  = lCost;
849                                            Last.Run   = Run;
850                                            Last_Node  = i;
851                                    }
852                            }
853                            if (Last_Node==i)
854                                    Last.Level = Nodes[i].Level;
855                    } else if (51U>(uint32_t)(Level1+25)) {
856                            /* "big" levels (not less than ESC3, though) */
857                            const uint8_t *Tbl_L1, *Tbl_L2, *Tbl_L1_Last, *Tbl_L2_Last;
858                            int Level2;
859                            int dQ1, dQ2;
860                            int Run;
861                            uint32_t Dist1,Dist2;
862                            int dDist21;
863    
864                            if (Level1>1) {
865                                    dQ1 = Level1*Mult-AC + Bias;
866                                    dQ2 = dQ1 - Mult;
867                                    Level2 = Level1-1;
868                                    Tbl_L1          = (Level1<=24) ? B16_17_Code_Len[Level1-1]         : Code_Len0;
869                                    Tbl_L2          = (Level2<=24) ? B16_17_Code_Len[Level2-1]         : Code_Len0;
870                                    Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;
871                                    Tbl_L2_Last = (Level2<=6) ? B16_17_Code_Len_Last[Level2-1] : Code_Len0;
872                            } else { /* Level1<-1 */
873                                    dQ1 = Level1*Mult-AC - Bias;
874                                    dQ2 = dQ1 + Mult;
875                                    Level2 = Level1 + 1;
876                                    Tbl_L1          = (Level1>=-24) ? B16_17_Code_Len[Level1^-1]      : Code_Len0;
877                                    Tbl_L2          = (Level2>=-24) ? B16_17_Code_Len[Level2^-1]      : Code_Len0;
878                                    Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;
879                                    Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;
880                            }
881    
882                            Dist1 = Lambda*dQ1*dQ1;
883                            Dist2 = Lambda*dQ2*dQ2;
884                            dDist21 = Dist2-Dist1;
885    
886                            for(Run=i-Run_Start; Run>0; --Run)
887                            {
888                                    const uint32_t Cost_Base = Dist1 + Run_Costs[i-Run];
889                                    uint32_t Cost1, Cost2;
890                                    int bLevel;
891    
892                                    /* for sub-optimal (but slightly worth it, speed-wise) search,
893                                     * uncomment the following:
894                                     *              if (Cost_Base>=Best_Cost) continue;
895                                     * (? doesn't seem to have any effect -- gruel ) */
896    
897                                    Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
898                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
899    
900                                    if (Cost2<Cost1) {
901                                            Cost1 = Cost2;
902                                            bLevel = Level2;
903                                    } else {
904                                            bLevel = Level1;
905                                    }
906    
907                                    if (Cost1<Best_Cost) {
908                                            Best_Cost = Cost1;
909                                            Nodes[i].Run   = Run;
910                                            Nodes[i].Level = bLevel;
911                                    }
912    
913                                    Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
914                                    Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
915    
916                                    if (Cost2<Cost1) {
917                                            Cost1 = Cost2;
918                                            bLevel = Level2;
919                                    } else {
920                                            bLevel = Level1;
921                                    }
922    
923                                    if (Cost1<Last_Cost) {
924                                            Last_Cost  = Cost1;
925                                            Last.Run   = Run;
926                                            Last.Level = bLevel;
927                                            Last_Node  = i;
928                                    }
929                            } /* end of "for Run" */
930                    } else {
931                            /* Very very high levels, with no chance of being optimizable
932                             * => Simply pick best Run. */
933                            int Run;
934                            for(Run=i-Run_Start; Run>0; --Run) {
935                                    /* 30 bits + no distortion */
936                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
937                                    if (Cost<Best_Cost) {
938                                            Best_Cost = Cost;
939                                            Nodes[i].Run   = Run;
940                                            Nodes[i].Level = Level1;
941                                    }
942    
943                                    if (Cost<Last_Cost) {
944                                            Last_Cost  = Cost;
945                                            Last.Run   = Run;
946                                            Last.Level = Level1;
947                                            Last_Node  = i;
948                                    }
949                            }
950                    }
951    
952    
953                    Run_Costs[i] = Best_Cost;
954    
955                    if (Best_Cost < Min_Cost + Dist0) {
956                            Min_Cost = Best_Cost;
957                            Run_Start = i;
958                    } else {
959                            /* as noticed by Michael Niedermayer (michaelni at gmx.at),
960                             * there's a code shorter by 1 bit for a larger run (!), same
961                             * level. We give it a chance by not moving the left barrier too
962                             * much. */
963                            while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
964                                    Run_Start++;
965    
966                            /* spread on preceding coeffs the cost incurred by skipping this
967                             * one */
968                            for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
969                            Min_Cost += Dist0;
970                    }
971            }
972    
973            /* It seems trellis doesn't give good results... just leave the block untouched
974             * and return the original sum value */
975            if (Last_Node<0)
976                    return Sum;
977    
978            /* reconstruct optimal sequence backward with surviving paths */
979            memset(Out, 0x00, 64*sizeof(*Out));
980            Out[Zigzag[Last_Node]] = Last.Level;
981            i = Last_Node - Last.Run;
982            Sum = abs(Last.Level);
983            while(i>=0) {
984                    Out[Zigzag[i]] = Nodes[i].Level;
985                    Sum += abs(Nodes[i].Level);
986                    i -= Nodes[i].Run;
987            }
988    
989            return Sum;
990    }
991    
992    /* original version including heavy debugging info */
993    
994    #ifdef DBGTRELL
995    
996  #define DBG 0  #define DBG 0
997    
998  static uint32_t Evaluate_Cost(const int16_t *C, int Mult, int Bias,  static __inline uint32_t Evaluate_Cost(const int16_t *C, int Mult, int Bias,
999                                  const uint16_t * Zigzag, int Max, int Lambda)                                  const uint16_t * Zigzag, int Max, int Lambda)
1000  {  {
1001  #if (DBG>0)  #if (DBG>0)
1002    const int16_t * const Ref = C + 6*64;    const int16_t * const Ref = C + 6*64;
1003    int Last = Max;    int Last = Max;
   while(Last>=0 && C[Zigzag[Last]]==0) Last--;  
1004    int Bits = 0;    int Bits = 0;
1005            int Dist = 0;
1006            int i;
1007            uint32_t Cost;
1008    
1009            while(Last>=0 && C[Zigzag[Last]]==0)
1010                    Last--;
1011    
1012    if (Last>=0) {    if (Last>=0) {
     Bits = 2;   // CBP  
1013      int j=0, j0=0;      int j=0, j0=0;
1014      int Run, Level;      int Run, Level;
1015    
1016                    Bits = 2;   /* CBP */
1017      while(j<Last) {      while(j<Last) {
1018        while(!C[Zigzag[j]]) j++;                          while(!C[Zigzag[j]])
1019        if (j==Last) break;                                  j++;
1020                            if (j==Last)
1021                                    break;
1022        Level=C[Zigzag[j]];        Level=C[Zigzag[j]];
1023        Run = j - j0;        Run = j - j0;
1024        j0 = ++j;        j0 = ++j;
1025        if (Level>=-24 && Level<=24) Bits += B16_17_Code_Len[(Level<0) ? -Level-1 : Level-1][Run];                          if (Level>=-24 && Level<=24)
1026        else Bits += 30;                                  Bits += B16_17_Code_Len[(Level<0) ? -Level-1 : Level-1][Run];
1027                            else
1028                                    Bits += 30;
1029      }      }
1030      Level = C[Zigzag[Last]];      Level = C[Zigzag[Last]];
1031      Run = j - j0;      Run = j - j0;
1032      if (Level>=-6 && Level<=6) Bits += B16_17_Code_Len_Last[(Level<0) ? -Level-1 : Level-1][Run];                  if (Level>=-6 && Level<=6)
1033      else Bits += 30;                          Bits += B16_17_Code_Len_Last[(Level<0) ? -Level-1 : Level-1][Run];
1034                    else
1035                            Bits += 30;
1036    }    }
1037    
   int Dist = 0;  
   int i;  
1038    for(i=0; i<=Last; ++i) {    for(i=0; i<=Last; ++i) {
1039      int V = C[Zigzag[i]]*Mult;      int V = C[Zigzag[i]]*Mult;
1040      if      (V>0) V += Bias;                  if (V>0)
1041      else if (V<0) V -= Bias;                          V += Bias;
1042                    else
1043                            if (V<0)
1044                                    V -= Bias;
1045      V -= Ref[Zigzag[i]];      V -= Ref[Zigzag[i]];
1046      Dist += V*V;      Dist += V*V;
1047    }    }
1048    uint32_t Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1049    if (DBG==1)    if (DBG==1)
1050      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 );
1051    return Cost;    return Cost;
# Line 807  Line 1060 
1060  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)
1061  {  {
1062    
1063      // Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),      /*
1064      // 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[]),
1065      // slightly (~0.01dB), whereas speed drops to crawling level :)           * not quantized one (Out[]). However, it only improves the result *very*
1066      // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,           * slightly (~0.01dB), whereas speed drops to crawling level :)
1067             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.
1068             */
1069    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
1070    
1071    NODE Nodes[65], Last;    NODE Nodes[65], Last;
1072    uint32_t Run_Costs0[64+1], * const Run_Costs = Run_Costs0 + 1;          uint32_t Run_Costs0[64+1];
1073            uint32_t * const Run_Costs = Run_Costs0 + 1;
1074    const int Mult = 2*Q;    const int Mult = 2*Q;
1075    const int Bias = (Q-1) | 1;    const int Bias = (Q-1) | 1;
1076    const int Lev0 = Mult + Bias;    const int Lev0 = Mult + Bias;
1077    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 */
1078    
1079    int Run_Start = -1;    int Run_Start = -1;
1080    Run_Costs[-1] = 2<<16;                          // source (w/ CBP penalty)          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1081    uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1082    
1083    int Last_Node = -1;    int Last_Node = -1;
1084    uint32_t Last_Cost = 0;    uint32_t Last_Cost = 0;
1085    
1086            int i, j;
1087    
1088  #if (DBG>0)  #if (DBG>0)
1089    Last.Level = 0; Last.Run = -1; // just initialize to smthg          Last.Level = 0; Last.Run = -1; /* just initialize to smthg */
1090  #endif  #endif
1091    
   int i, j;  
   
1092    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
1093    if (Non_Zero<0)    if (Non_Zero<0)
1094        return -1;        return -1;
# Line 847  Line 1101 
1101      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
1102      Last_Cost += Dist0;      Last_Cost += Dist0;
1103    
1104      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 */
1105      {      {
1106        int dQ;        int dQ;
1107            int Run;            int Run;
1108                            uint32_t Cost0;
1109    
1110        if (AC<0) {        if (AC<0) {
1111          Nodes[i].Level = -1;          Nodes[i].Level = -1;
# Line 859  Line 1114 
1114          Nodes[i].Level = 1;          Nodes[i].Level = 1;
1115          dQ = Lev0 - AC;          dQ = Lev0 - AC;
1116        }        }
1117        const uint32_t Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
1118    
1119        Nodes[i].Run = 1;        Nodes[i].Run = 1;
1120        Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1121        for(Run=i-Run_Start; Run>0; --Run)        for(Run=i-Run_Start; Run>0; --Run)
1122        {        {
1123          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1124          const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1125            // TODO: what about tie-breaks? Should we favor short runs or                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1126            // long runs? Although the error is the same, it would not be  
1127            // spread the same way along high and low frequencies...                                  /*
1128          if (Cost<Best_Cost)                                   * TODO: what about tie-breaks? Should we favor short runs or
1129          {                                   * long runs? Although the error is the same, it would not be
1130                                     * spread the same way along high and low frequencies...
1131                                     */
1132                                    if (Cost<Best_Cost) {
1133            Best_Cost    = Cost;            Best_Cost    = Cost;
1134            Nodes[i].Run = Run;            Nodes[i].Run = Run;
1135          }          }
1136          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);  
1137          if (lCost<Last_Cost)                                  if (lCost<Last_Cost) {
         {  
1138            Last_Cost  = lCost;            Last_Cost  = lCost;
1139            Last.Run   = Run;            Last.Run   = Run;
1140            Last_Node  = i;            Last_Node  = i;
1141          }          }
1142        }        }
1143        if (Last_Node==i) Last.Level = Nodes[i].Level;                          if (Last_Node==i)
1144                                    Last.Level = Nodes[i].Level;
1145    
1146        if (DBG==1) {        if (DBG==1) {
1147          Run_Costs[i] = Best_Cost;          Run_Costs[i] = Best_Cost;
# Line 901  Line 1158 
1158          printf( "\n" );          printf( "\n" );
1159        }        }
1160      }      }
1161      else                      // "big" levels                  else                      /* "big" levels */
1162      {      {
1163        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;
1164        int Level2;        int Level2;
1165        int dQ1, dQ2;        int dQ1, dQ2;
1166        int Run;        int Run;
1167                            uint32_t Dist1,Dist2;
1168                            int dDist21;
1169    
1170            if (Level1>1) {            if (Level1>1) {
1171          dQ1 = Level1*Mult-AC + Bias;          dQ1 = Level1*Mult-AC + Bias;
# Line 916  Line 1175 
1175          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
1176          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;
1177          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;
1178        }                          } else { /* Level1<-1 */
       else { // Level1<-1  
1179          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
1180          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
1181          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 926  Line 1184 
1184          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;
1185          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;
1186        }        }
1187        const uint32_t Dist1 = Lambda*dQ1*dQ1;                          Dist1 = Lambda*dQ1*dQ1;
1188        const uint32_t Dist2 = Lambda*dQ2*dQ2;                          Dist2 = Lambda*dQ2*dQ2;
1189        const int dDist21 = Dist2-Dist1;                          dDist21 = Dist2-Dist1;
1190    
1191        for(Run=i-Run_Start; Run>0; --Run)        for(Run=i-Run_Start; Run>0; --Run)
1192        {        {
1193          const uint32_t Cost_Base = Dist1 + Run_Costs[i-Run];          const uint32_t Cost_Base = Dist1 + Run_Costs[i-Run];
   
 // for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:  
 //        if (Cost_Base>=Best_Cost) continue;  
   
1194          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
1195          int bLevel;          int bLevel;
1196    
1197          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);  /*
1198          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1199     *        if (Cost_Base>=Best_Cost) continue;
1200     */
1201                                    Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1202                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1203    
1204          if (Cost2<Cost1) { Cost1 = Cost2; bLevel = Level2; }                                  if (Cost2<Cost1) {
1205          else bLevel = Level1;                                          Cost1 = Cost2;
1206                                            bLevel = Level2;
1207                                    } else
1208                                            bLevel = Level1;
1209    
1210          if (Cost1<Best_Cost)                                  if (Cost1<Best_Cost) {
         {  
1211            Best_Cost = Cost1;            Best_Cost = Cost1;
1212            Nodes[i].Run   = Run;            Nodes[i].Run   = Run;
1213            Nodes[i].Level = bLevel;            Nodes[i].Level = bLevel;
1214          }          }
1215    
1216          Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1217          Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1218    
1219          if (Cost2<Cost1) { Cost1 = Cost2; bLevel = Level2; }                                  if (Cost2<Cost1) {
1220          else bLevel = Level1;                                          Cost1 = Cost2;
1221          if (Cost1<Last_Cost)                                          bLevel = Level2;
1222          {                                  } else
1223                                            bLevel = Level1;
1224    
1225                                    if (Cost1<Last_Cost) {
1226            Last_Cost  = Cost1;            Last_Cost  = Cost1;
1227            Last.Run   = Run;            Last.Run   = Run;
1228            Last.Level = bLevel;            Last.Level = bLevel;
1229            Last_Node  = i;            Last_Node  = i;
1230          }          }
1231        }                          } /* end of "for Run" */
1232    
1233        if (DBG==1) {        if (DBG==1) {
1234          Run_Costs[i] = Best_Cost;          Run_Costs[i] = Best_Cost;
# Line 991  Line 1254 
1254      }      }
1255      else      else
1256      {      {
1257          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                          /*
1258          // 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
1259          // 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
1260        while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                           * it a chance by not moving the left barrier too much.
1261                             */
1262    
1263                            while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1264          Run_Start++;          Run_Start++;
1265    
1266          // spread on preceding coeffs the cost incurred by skipping this one                          /* spread on preceding coeffs the cost incurred by skipping this one */
1267        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1268        Min_Cost += Dist0;        Min_Cost += Dist0;
1269      }      }
# Line 1015  Line 1281 
1281    if (Last_Node<0)    if (Last_Node<0)
1282      return -1;      return -1;
1283    
1284         // reconstruct optimal sequence backward with surviving paths          /* reconstruct optimal sequence backward with surviving paths */
1285    bzero(Out, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
1286    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
1287    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;
1288    while(i>=0) {    while(i>=0) {
# Line 1037  Line 1303 
1303  }  }
1304    
1305  #undef DBG  #undef DBG
1306    
1307    #endif

Legend:
Removed from v.1.21.2.10  
changed lines
  Added in v.1.30

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