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

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

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