[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.15, Thu Jul 24 13:09:14 2003 UTC revision 1.27, Sun Dec 19 12:49:05 2004 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 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          }          }
 }  
   
178    
179  static int  static int
180  dct_quantize_trellis_h263_c(int16_t *const Out,  dct_quantize_trellis_c(int16_t *const Out,
181                                                          const int16_t *const In,                                                          const int16_t *const In,
182                                                          int Q,                                                          int Q,
183                                                          const uint16_t * const Zigzag,                                                          const uint16_t * const Zigzag,
184                                                          int Non_Zero);                                             const uint16_t * const QuantMatrix,
185                                               int Non_Zero,
186  #if 0                                             int Sum);
 static int  
 dct_quantize_trellis_mpeg_c(int16_t *const Out,  
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero);  
 #endif  
187    
188  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
189  static __inline uint8_t  static __inline uint8_t
# Line 191  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; // Isibaar: why? deactivated so far - so please complain! ;-) */                          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 0                                          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  #endif                                          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 247  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 276  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 325  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;  
346    
347          if (pMB->field_dct) {          /* Array of function pointers, indexed by [add] */
348                  next_block = stride;          transfer_operation_16to8_t  * const functions[2] =
349                  stride *= 2;                  {
350          }                          (transfer_operation_16to8_t*)transfer_16to8copy,
351                            (transfer_operation_16to8_t*)transfer_16to8add,
352          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;  
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 430  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 471  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 492  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 618  Line 607 
607          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
608  }  }
609    
   
   
   
   
610  /*****************************************************************************  /*****************************************************************************
611   *               Trellis based R-D optimal quantization   *               Trellis based R-D optimal quantization
612   *   *
# Line 629  Line 614 
614   *   *
615   ****************************************************************************/   ****************************************************************************/
616    
   
 #if 0  
 static int  
 dct_quantize_trellis_mpeg_c(int16_t *const Out,  
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero)  
 {  
         return 63;  
 }  
 #endif  
   
617  /*----------------------------------------------------------------------------  /*----------------------------------------------------------------------------
618   *   *
619   *        Trellis-Based quantization   *        Trellis-Based quantization
# Line 653  Line 625 
625   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
626   *   *
627   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
628   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
629   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
630   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
631   * without using a heap, since the open frontier of the DAG is always   * without using a heap, since the open frontier of the DAG is always
632   * known, and of fixed sized.   * known, and of fixed size.
633   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
634    
635    
# Line 757  Line 729 
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 767  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 777  Line 757 
757  }  }
758    
759  /* this routine has been strippen of all debug code */  /* this routine has been strippen of all debug code */
   
760  static int  static int
761  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,
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           * Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),           * (In[]), not quantized one (Out[]). However, it only improves the result
772           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
773           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
774           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
775    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
776    
777    NODE Nodes[65], Last;    NODE Nodes[65], Last;
778    uint32_t Run_Costs0[64+1];    uint32_t Run_Costs0[64+1];
779    uint32_t * const Run_Costs = Run_Costs0 + 1;    uint32_t * const Run_Costs = Run_Costs0 + 1;
780    const int Mult = 2*Q;  
781    const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
782    const int Lev0 = Mult + Bias;          const int Lambda = Trellis_Lambda_Tabs[Q-1];
   const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */  
783    
784    int Run_Start = -1;    int Run_Start = -1;
785    uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
786    
787    int Last_Node = -1;    int Last_Node = -1;
788    uint32_t Last_Cost = 0;    uint32_t Last_Cost = 0;
789    
790    int i, j;    int i, j;
791    Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */  
792            /* source (w/ CBP penalty) */
793            Run_Costs[-1] = 2<<TL_SHIFT;
794    
795    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
796    if (Non_Zero<0)    if (Non_Zero<0)
797        return -1;                  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    
   for(i=0; i<=Non_Zero; i++)  
   {  
805      const int AC = In[Zigzag[i]];      const int AC = In[Zigzag[i]];
806      const int Level1 = Out[Zigzag[i]];      const int Level1 = Out[Zigzag[i]];
807      const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = Lambda* AC*AC;
808      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
809      Last_Cost += Dist0;      Last_Cost += Dist0;
810    
811      if ((uint32_t)(Level1+1)<3)                 /* very specialized loop for -1,0,+1 */                  /* very specialized loop for -1,0,+1 */
812      {                  if ((uint32_t)(Level1+1)<3) {
813          int dQ;          int dQ;
814                  int Run;                  int Run;
815        uint32_t Cost0;        uint32_t Cost0;
# Line 835  Line 824 
824                  Cost0 = Lambda*dQ*dQ;                  Cost0 = Lambda*dQ*dQ;
825    
826        Nodes[i].Run = 1;        Nodes[i].Run = 1;
827        Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
828        for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run) {
       {  
829          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
830          const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
831          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  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
                    * TODO: what about tie-breaks? Should we favor short runs or  
834                     * long runs? Although the error is the same, it would not be                     * long runs? Although the error is the same, it would not be
835                     * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                    */  
836    
837                          /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
838    
839          if (Cost<Best_Cost) {          if (Cost<Best_Cost) {
840            Best_Cost    = Cost;            Best_Cost    = Cost;
# Line 863  Line 849 
849        }        }
850        if (Last_Node==i)        if (Last_Node==i)
851                          Last.Level = Nodes[i].Level;                          Last.Level = Nodes[i].Level;
852      }                  } else if (51U>(uint32_t)(Level1+25)) {
853      else                      /* "big" levels */                          /* "big" levels (not less than ESC3, though) */
     {  
854        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;
855        int Level2;        int Level2;
856        int dQ1, dQ2;        int dQ1, dQ2;
# Line 890  Line 875 
875          Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;          Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;
876          Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;          Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;
877        }        }
878    
879        Dist1 = Lambda*dQ1*dQ1;        Dist1 = Lambda*dQ1*dQ1;
880        Dist2 = Lambda*dQ2*dQ2;        Dist2 = Lambda*dQ2*dQ2;
881        dDist21 = Dist2-Dist1;        dDist21 = Dist2-Dist1;
# Line 900  Line 886 
886          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
887          int bLevel;          int bLevel;
888    
889  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
890   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
891   *      if (Cost_Base>=Best_Cost) continue;   *      if (Cost_Base>=Best_Cost) continue;
892   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
  */  
893    
894          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
895          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
896    
897          if (Cost2<Cost1) {          if (Cost2<Cost1) {
898                           Cost1 = Cost2;                           Cost1 = Cost2;
899                           bLevel = Level2;                           bLevel = Level2;
900                    } else                                  } else {
901                           bLevel = Level1;                           bLevel = Level1;
902                                    }
903    
904          if (Cost1<Best_Cost) {          if (Cost1<Best_Cost) {
905            Best_Cost = Cost1;            Best_Cost = Cost1;
# Line 921  Line 907 
907            Nodes[i].Level = bLevel;            Nodes[i].Level = bLevel;
908          }          }
909    
910          Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
911          Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
912    
913          if (Cost2<Cost1) {          if (Cost2<Cost1) {
914                           Cost1 = Cost2;                           Cost1 = Cost2;
915                           bLevel = Level2;                           bLevel = Level2;
916                    } else                                  } else {
917                           bLevel = Level1;                           bLevel = Level1;
918                                    }
919    
920          if (Cost1<Last_Cost) {          if (Cost1<Last_Cost) {
921            Last_Cost  = Cost1;            Last_Cost  = Cost1;
# Line 937  Line 924 
924            Last_Node  = i;            Last_Node  = i;
925          }          }
926        } /* end of "for Run" */        } /* 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;      Run_Costs[i] = Best_Cost;
951    
952      if (Best_Cost < Min_Cost + Dist0) {      if (Best_Cost < Min_Cost + Dist0) {
953        Min_Cost = Best_Cost;        Min_Cost = Best_Cost;
954        Run_Start = i;        Run_Start = i;
955      }                  } else {
956      else                          /* 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                   * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * much. */
960                   * a code shorter by 1 bit for a larger run (!), same level. We give                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
                  * it a chance by not moving the left barrier too much.  
                  */  
   
       while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
961          Run_Start++;          Run_Start++;
962    
963          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
964                             * one */
965        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
966        Min_Cost += Dist0;        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)    if (Last_Node<0)
973      return -1;                  return Sum;
974    
975         /* reconstruct optimal sequence backward with surviving paths */         /* reconstruct optimal sequence backward with surviving paths */
976    memset(Out, 0x00, 64*sizeof(*Out));    memset(Out, 0x00, 64*sizeof(*Out));
977    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
978    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;
979            Sum = abs(Last.Level);
980    while(i>=0) {    while(i>=0) {
981      Out[Zigzag[i]] = Nodes[i].Level;      Out[Zigzag[i]] = Nodes[i].Level;
982                    Sum += abs(Nodes[i].Level);
983      i -= Nodes[i].Run;      i -= Nodes[i].Run;
984    }    }
   return Last_Node;  
 }  
   
   
   
   
   
   
   
   
   
985    
986            return Sum;
987    }
988    
989  /* original version including heavy debugging info */  /* original version including heavy debugging info */
990    
# Line 1043  Line 1042 
1042      V -= Ref[Zigzag[i]];      V -= Ref[Zigzag[i]];
1043      Dist += V*V;      Dist += V*V;
1044    }    }
1045    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 1075  Line 1074 
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;
# Line 1115  Line 1114 
1114                  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          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1123    
1124            /*            /*
1125                     * TODO: what about tie-breaks? Should we favor short runs or                     * TODO: what about tie-breaks? Should we favor short runs or
# Line 1196  Line 1195 
1195   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1196   *        if (Cost_Base>=Best_Cost) continue;   *        if (Cost_Base>=Best_Cost) continue;
1197   */   */
1198          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1199          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1200    
1201          if (Cost2<Cost1) {          if (Cost2<Cost1) {
1202                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1211  Line 1210 
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) {          if (Cost2<Cost1) {
1217                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1258  Line 1257 
1257                   * it a chance by not moving the left barrier too much.                   * it a chance by not moving the left barrier too much.
1258                   */                   */
1259    
1260        while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          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 */

Legend:
Removed from v.1.21.2.15  
changed lines
  Added in v.1.27

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