[cvs] / xvidcore / src / utils / mbtransquant.c Repository:
ViewVC logotype

Diff of /xvidcore/src/utils/mbtransquant.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.21.2.12, Mon May 12 12:33:16 2003 UTC revision 1.31, Sat Dec 10 05:20:35 2005 UTC
# Line 39  Line 39 
39  #include "../bitstream/zigzag.h"  #include "../bitstream/zigzag.h"
40  #include "../dct/fdct.h"  #include "../dct/fdct.h"
41  #include "../dct/idct.h"  #include "../dct/idct.h"
42  #include "../quant/quant_mpeg4.h"  #include "../quant/quant.h"
 #include "../quant/quant_h263.h"  
43  #include "../encoder.h"  #include "../encoder.h"
44    
45  #include "../image/reduced.h"  #include  "../quant/quant_matrix.h"
46    
47  MBFIELDTEST_PTR MBFieldTest;  MBFIELDTEST_PTR MBFieldTest;
48    
# Line 91  Line 90 
90    
91          /* Perform DCT */          /* Perform DCT */
92          start_timer();          start_timer();
93          fdct(&data[0 * 64]);          fdct((short * const)&data[0 * 64]);
94          fdct(&data[1 * 64]);          fdct((short * const)&data[1 * 64]);
95          fdct(&data[2 * 64]);          fdct((short * const)&data[2 * 64]);
96          fdct(&data[3 * 64]);          fdct((short * const)&data[3 * 64]);
97          fdct(&data[4 * 64]);          fdct((short * const)&data[4 * 64]);
98          fdct(&data[5 * 64]);          fdct((short * const)&data[5 * 64]);
99          stop_dct_timer();          stop_dct_timer();
100  }  }
101    
# Line 106  Line 105 
105             const uint8_t cbp)             const uint8_t cbp)
106  {  {
107          start_timer();          start_timer();
108          if(cbp & (1 << (5 - 0))) idct(&data[0 * 64]);          if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]);
109          if(cbp & (1 << (5 - 1))) idct(&data[1 * 64]);          if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]);
110          if(cbp & (1 << (5 - 2))) idct(&data[2 * 64]);          if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]);
111          if(cbp & (1 << (5 - 3))) idct(&data[3 * 64]);          if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]);
112          if(cbp & (1 << (5 - 4))) idct(&data[4 * 64]);          if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]);
113          if(cbp & (1 << (5 - 5))) idct(&data[5 * 64]);          if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]);
114          stop_idct_timer();          stop_idct_timer();
115  }  }
116    
# Line 123  Line 122 
122                           int16_t qcoeff[6 * 64],                           int16_t qcoeff[6 * 64],
123                           int16_t data[6*64])                           int16_t data[6*64])
124  {  {
125          int i;          int 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 146  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 182  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 236  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 265  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 314  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;  
348    
349          if (pMB->field_dct) {          /* Array of function pointers, indexed by [add] */
350                  next_block = stride;          transfer_operation_16to8_t  * const functions[2] =
351                  stride *= 2;                  {
352          }                          (transfer_operation_16to8_t*)transfer_16to8copy,
353                            (transfer_operation_16to8_t*)transfer_16to8add,
354          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;  
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 419  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 430  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 457  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 468  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 475  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 546  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 574  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 601  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_mpeg_c(int16_t *const Out, const int16_t *const In, int Q,  
                 const uint16_t * const Zigzag, int Non_Zero)  
 { return 63; }  
   
   
 //////////////////////////////////////////////////////////  
 //  
 //        Trellis-Based quantization  
 //  
 // So far I understand this paper:  
 //  
 //  "Trellis-Based R-D Optimal Quantization in H.263+"  
 //    J.Wen, M.Luttrell, J.Villasenor  
 //    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.  
 //  
 // we are at stake with a simplified Bellmand-Ford / Dijkstra Single  
 // Source Shorted Path algo. But due to the underlying graph structure  
 // ("Trellis"), it can be turned into a dynamic programming algo,  
 // partially saving the explicit graph's nodes representation. And  
 // without using a heap, since the open frontier of the DAG is always  
 // known, and of fixed sized.  
 //  
 //////////////////////////////////////////////////////////  
   
   
 //////////////////////////////////////////////////////////  
 // Codes lengths for relevant levels.  
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 707  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 722  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 731  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 745  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 754  Line 758 
758    return -1;    return -1;
759  }  }
760    
761  //////////////////////////////////////////////////////////  #define TRELLIS_MIN_EFFORT      3
 // this routine has been strippen of all debug code  
 //////////////////////////////////////////////////////////  
762    
763    /* this routine has been strippen of all debug code */
764  static int  static int
765  dct_quantize_trellis_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)  dct_quantize_trellis_c(int16_t *const Out,
766                                               const int16_t *const In,
767                                               int Q,
768                                               const uint16_t * const Zigzag,
769                                               const uint16_t * const QuantMatrix,
770                                               int Non_Zero,
771                                               int Sum,
772                                               int Lambda_Mod)
773  {  {
774    
775      // Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),          /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
776      // not quantized one (Out[]). However, it only improves the result *very*           * (In[]), not quantized one (Out[]). However, it only improves the result
777      // slightly (~0.01dB), whereas speed drops to crawling level :)           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
778      // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
779             * helps. */
780    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
781    
782    NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
783    uint32_t Run_Costs0[64+1];    uint32_t Run_Costs0[64+1];
784    uint32_t * const Run_Costs = Run_Costs0 + 1;    uint32_t * const Run_Costs = Run_Costs0 + 1;
785    const int Mult = 2*Q;  
786    const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
787    const int Lev0 = Mult + Bias;          const int Lambda = (Lambda_Mod*Trellis_Lambda_Tabs[Q-1])>>LAMBDA_EXP;
   const int Lambda = Trellis_Lambda_Tabs[Q-1];    // it's 1/lambda, actually  
788    
789    int Run_Start = -1;    int Run_Start = -1;
790    uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
791    
792    int Last_Node = -1;    int Last_Node = -1;
793    uint32_t Last_Cost = 0;    uint32_t Last_Cost = 0;
794    
795    int i, j;    int i, j;
796    Run_Costs[-1] = 2<<16;                          // source (w/ CBP penalty)  
797            /* source (w/ CBP penalty) */
798            Run_Costs[-1] = 2<<TL_SHIFT;
799    
800    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
801    if (Non_Zero<0)          if (Non_Zero < TRELLIS_MIN_EFFORT)
802        return -1;                  Non_Zero = TRELLIS_MIN_EFFORT;
803    
804            for(i=0; i<=Non_Zero; i++) {
805                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
806                    const int Mult = 2*q;
807                    const int Bias = (q-1) | 1;
808                    const int Lev0 = Mult + Bias;
809    
   for(i=0; i<=Non_Zero; i++)  
   {  
810      const int AC = In[Zigzag[i]];      const int AC = In[Zigzag[i]];
811      const int Level1 = Out[Zigzag[i]];      const int Level1 = Out[Zigzag[i]];
812      const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = Lambda* AC*AC;
813      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
814      Last_Cost += Dist0;      Last_Cost += Dist0;
815    
816      if ((uint32_t)(Level1+1)<3)                 // very specialized loop for -1,0,+1                  /* very specialized loop for -1,0,+1 */
817      {                  if ((uint32_t)(Level1+1)<3) {
818          int dQ;          int dQ;
819                  int Run;                  int Run;
820        uint32_t Cost0;        uint32_t Cost0;
# Line 814  Line 829 
829                  Cost0 = Lambda*dQ*dQ;                  Cost0 = Lambda*dQ*dQ;
830    
831        Nodes[i].Run = 1;        Nodes[i].Run = 1;
832        Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
833        for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run) {
       {  
834          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
835          const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
836          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
837    
838            // TODO: what about tie-breaks? Should we favor short runs or                                  /* TODO: what about tie-breaks? Should we favor short runs or
839            // long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
840            // spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
841    
842                          // (I'd say: favour short runs => hifreq errors (HVS) -- gruel )                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
843    
844          if (Cost<Best_Cost) {          if (Cost<Best_Cost) {
845            Best_Cost    = Cost;            Best_Cost    = Cost;
# Line 840  Line 854 
854        }        }
855        if (Last_Node==i)        if (Last_Node==i)
856                          Last.Level = Nodes[i].Level;                          Last.Level = Nodes[i].Level;
857      }                  } else if (51U>(uint32_t)(Level1+25)) {
858      else                      // "big" levels                          /* "big" levels (not less than ESC3, though) */
     {  
859        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;
860        int Level2;        int Level2;
861        int dQ1, dQ2;        int dQ1, dQ2;
# Line 858  Line 871 
871          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
872          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;
873          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;
874        } else { // Level1<-1                          } else { /* Level1<-1 */
875          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
876          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
877          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 867  Line 880 
880          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;
881          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;
882        }        }
883    
884        Dist1 = Lambda*dQ1*dQ1;        Dist1 = Lambda*dQ1*dQ1;
885        Dist2 = Lambda*dQ2*dQ2;        Dist2 = Lambda*dQ2*dQ2;
886        dDist21 = Dist2-Dist1;        dDist21 = Dist2-Dist1;
# Line 877  Line 891 
891          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
892          int bLevel;          int bLevel;
893    
894  // for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
895  //        if (Cost_Base>=Best_Cost) continue;                                   * uncomment the following:
896  // (? doesn't seem to have any effect -- gruel )                                   *              if (Cost_Base>=Best_Cost) continue;
897                                     * (? doesn't seem to have any effect -- gruel ) */
898    
899          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
900          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
901    
902          if (Cost2<Cost1) {          if (Cost2<Cost1) {
903                           Cost1 = Cost2;                           Cost1 = Cost2;
904                           bLevel = Level2;                           bLevel = Level2;
905                    } else                                  } else {
906                           bLevel = Level1;                           bLevel = Level1;
907                                    }
908    
909          if (Cost1<Best_Cost) {          if (Cost1<Best_Cost) {
910            Best_Cost = Cost1;            Best_Cost = Cost1;
# Line 896  Line 912 
912            Nodes[i].Level = bLevel;            Nodes[i].Level = bLevel;
913          }          }
914    
915          Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
916          Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
917    
918          if (Cost2<Cost1) {          if (Cost2<Cost1) {
919                           Cost1 = Cost2;                           Cost1 = Cost2;
920                           bLevel = Level2;                           bLevel = Level2;
921                    } else                                  } else {
922                           bLevel = Level1;                           bLevel = Level1;
923                                    }
924    
925          if (Cost1<Last_Cost) {          if (Cost1<Last_Cost) {
926            Last_Cost  = Cost1;            Last_Cost  = Cost1;
# Line 911  Line 928 
928            Last.Level = bLevel;            Last.Level = bLevel;
929            Last_Node  = i;            Last_Node  = i;
930          }          }
931        } //end of "for Run"                          } /* end of "for Run" */
932                    } else {
933                            /* Very very high levels, with no chance of being optimizable
934                             * => Simply pick best Run. */
935                            int Run;
936                            for(Run=i-Run_Start; Run>0; --Run) {
937                                    /* 30 bits + no distortion */
938                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
939                                    if (Cost<Best_Cost) {
940                                            Best_Cost = Cost;
941                                            Nodes[i].Run   = Run;
942                                            Nodes[i].Level = Level1;
943                                    }
944    
945                                    if (Cost<Last_Cost) {
946                                            Last_Cost  = Cost;
947                                            Last.Run   = Run;
948                                            Last.Level = Level1;
949                                            Last_Node  = i;
950                                    }
951      }      }
952                    }
953    
954    
955      Run_Costs[i] = Best_Cost;      Run_Costs[i] = Best_Cost;
956    
957      if (Best_Cost < Min_Cost + Dist0) {      if (Best_Cost < Min_Cost + Dist0) {
958        Min_Cost = Best_Cost;        Min_Cost = Best_Cost;
959        Run_Start = i;        Run_Start = i;
960      }                  } else {
961      else                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
962      {                           * there's a code shorter by 1 bit for a larger run (!), same
963          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * level. We give it a chance by not moving the left barrier too
964          // a code shorter by 1 bit for a larger run (!), same level. We give                           * much. */
965          // it a chance by not moving the left barrier too much.                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
   
       while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
966          Run_Start++;          Run_Start++;
967    
968          // spread on preceding coeffs the cost incurred by skipping this one                          /* spread on preceding coeffs the cost incurred by skipping this
969                             * one */
970        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
971        Min_Cost += Dist0;        Min_Cost += Dist0;
972      }      }
973    }    }
974    
975            /* It seems trellis doesn't give good results... just leave the block untouched
976             * and return the original sum value */
977    if (Last_Node<0)    if (Last_Node<0)
978      return -1;                  return Sum;
979    
980         // reconstruct optimal sequence backward with surviving paths          /* reconstruct optimal sequence backward with surviving paths */
981    memset(Out, 0x00, 64*sizeof(*Out));    memset(Out, 0x00, 64*sizeof(*Out));
982    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
983    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;
984            Sum = abs(Last.Level);
985    while(i>=0) {    while(i>=0) {
986      Out[Zigzag[i]] = Nodes[i].Level;      Out[Zigzag[i]] = Nodes[i].Level;
987                    Sum += abs(Nodes[i].Level);
988      i -= Nodes[i].Run;      i -= Nodes[i].Run;
989    }    }
   return Last_Node;  
 }  
   
   
990    
991            return Sum;
992    }
993    
994    /* original version including heavy debugging info */
   
   
   
   
   
   
 //////////////////////////////////////////////////////////  
 // original version including heavy debugging info  
 //////////////////////////////////////////////////////////  
   
995    
996  #ifdef DBGTRELL  #ifdef DBGTRELL
997    
# Line 987  Line 1015 
1015      int j=0, j0=0;      int j=0, j0=0;
1016      int Run, Level;      int Run, Level;
1017    
1018      Bits = 2;   // CBP                  Bits = 2;   /* CBP */
1019      while(j<Last) {      while(j<Last) {
1020        while(!C[Zigzag[j]])        while(!C[Zigzag[j]])
1021                          j++;                          j++;
# Line 1019  Line 1047 
1047      V -= Ref[Zigzag[i]];      V -= Ref[Zigzag[i]];
1048      Dist += V*V;      Dist += V*V;
1049    }    }
1050    Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1051    if (DBG==1)    if (DBG==1)
1052      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 );
1053    return Cost;    return Cost;
# Line 1034  Line 1062 
1062  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)
1063  {  {
1064    
1065      // Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),      /*
1066      // 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[]),
1067      // slightly (~0.01dB), whereas speed drops to crawling level :)           * not quantized one (Out[]). However, it only improves the result *very*
1068      // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,           * slightly (~0.01dB), whereas speed drops to crawling level :)
1069             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.
1070             */
1071    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
1072    
1073    NODE Nodes[65], Last;    NODE Nodes[65], Last;
# Line 1047  Line 1076 
1076    const int Mult = 2*Q;    const int Mult = 2*Q;
1077    const int Bias = (Q-1) | 1;    const int Bias = (Q-1) | 1;
1078    const int Lev0 = Mult + Bias;    const int Lev0 = Mult + Bias;
1079    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 */
1080    
1081    int Run_Start = -1;    int Run_Start = -1;
1082    Run_Costs[-1] = 2<<16;                          // source (w/ CBP penalty)          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1083    uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1084    
1085    int Last_Node = -1;    int Last_Node = -1;
1086    uint32_t Last_Cost = 0;    uint32_t Last_Cost = 0;
# Line 1059  Line 1088 
1088    int i, j;    int i, j;
1089    
1090  #if (DBG>0)  #if (DBG>0)
1091    Last.Level = 0; Last.Run = -1; // just initialize to smthg          Last.Level = 0; Last.Run = -1; /* just initialize to smthg */
1092  #endif  #endif
1093    
1094    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
# Line 1074  Line 1103 
1103      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
1104      Last_Cost += Dist0;      Last_Cost += Dist0;
1105    
1106      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 */
1107      {      {
1108          int dQ;          int dQ;
1109                  int Run;                  int Run;
# Line 1090  Line 1119 
1119                  Cost0 = Lambda*dQ*dQ;                  Cost0 = Lambda*dQ*dQ;
1120    
1121        Nodes[i].Run = 1;        Nodes[i].Run = 1;
1122        Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1123        for(Run=i-Run_Start; Run>0; --Run)        for(Run=i-Run_Start; Run>0; --Run)
1124        {        {
1125          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1126          const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1127          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1128    
1129            // TODO: what about tie-breaks? Should we favor short runs or                                  /*
1130            // long runs? Although the error is the same, it would not be                                   * TODO: what about tie-breaks? Should we favor short runs or
1131            // spread the same way along high and low frequencies...                                   * long runs? Although the error is the same, it would not be
1132                                     * spread the same way along high and low frequencies...
1133                                     */
1134          if (Cost<Best_Cost) {          if (Cost<Best_Cost) {
1135            Best_Cost    = Cost;            Best_Cost    = Cost;
1136            Nodes[i].Run = Run;            Nodes[i].Run = Run;
# Line 1129  Line 1160 
1160          printf( "\n" );          printf( "\n" );
1161        }        }
1162      }      }
1163      else                      // "big" levels                  else                      /* "big" levels */
1164      {      {
1165        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;
1166        int Level2;        int Level2;
# Line 1146  Line 1177 
1177          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
1178          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;
1179          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;
1180        } else { // Level1<-1                          } else { /* Level1<-1 */
1181          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
1182          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
1183          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 1165  Line 1196 
1196          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
1197          int bLevel;          int bLevel;
1198    
1199  // for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:  /*
1200  //        if (Cost_Base>=Best_Cost) continue;   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1201     *        if (Cost_Base>=Best_Cost) continue;
1202          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);   */
1203          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1204                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1205    
1206          if (Cost2<Cost1) {          if (Cost2<Cost1) {
1207                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1183  Line 1215 
1215            Nodes[i].Level = bLevel;            Nodes[i].Level = bLevel;
1216          }          }
1217    
1218          Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1219          Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1220    
1221          if (Cost2<Cost1) {          if (Cost2<Cost1) {
1222                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1198  Line 1230 
1230            Last.Level = bLevel;            Last.Level = bLevel;
1231            Last_Node  = i;            Last_Node  = i;
1232          }          }
1233        } //end of "for Run"                          } /* end of "for Run" */
1234    
1235        if (DBG==1) {        if (DBG==1) {
1236          Run_Costs[i] = Best_Cost;          Run_Costs[i] = Best_Cost;
# Line 1224  Line 1256 
1256      }      }
1257      else      else
1258      {      {
1259          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                          /*
1260          // 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
1261          // 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
1262                             * it a chance by not moving the left barrier too much.
1263                             */
1264    
1265        while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1266          Run_Start++;          Run_Start++;
1267    
1268          // spread on preceding coeffs the cost incurred by skipping this one                          /* spread on preceding coeffs the cost incurred by skipping this one */
1269        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1270        Min_Cost += Dist0;        Min_Cost += Dist0;
1271      }      }
# Line 1249  Line 1283 
1283    if (Last_Node<0)    if (Last_Node<0)
1284      return -1;      return -1;
1285    
1286         // reconstruct optimal sequence backward with surviving paths          /* reconstruct optimal sequence backward with surviving paths */
1287    memset(Out, 0x00, 64*sizeof(*Out));    memset(Out, 0x00, 64*sizeof(*Out));
1288    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
1289    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;

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

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