[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.33, Sun Nov 28 15:18:21 2010 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /*****************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - MB Transfert/Quantization functions -   *  - MB Transfer/Quantization functions -
5   *   *
6   *  Copyright(C) 2001-2003  Peter Ross <pross@xvid.org>   *  Copyright(C) 2001-2010  Peter Ross <pross@xvid.org>
7   *               2001-2003  Michael Militzer <isibaar@xvid.org>   *               2001-2010  Michael Militzer <michael@xvid.org>
8   *               2003       Edouard Gomez <ed.gomez@free.fr>   *               2003       Edouard Gomez <ed.gomez@free.fr>
9   *   *
10   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
# 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"
43  #include "../quant/quant_h263.h"  #include "../motion/sad.h"
44  #include "../encoder.h"  #include "../encoder.h"
45    
46  #include "../image/reduced.h"  #include  "../quant/quant_matrix.h"
47    
48  MBFIELDTEST_PTR MBFieldTest;  MBFIELDTEST_PTR MBFieldTest;
49    
# Line 91  Line 91 
91    
92          /* Perform DCT */          /* Perform DCT */
93          start_timer();          start_timer();
94          fdct(&data[0 * 64]);          fdct((short * const)&data[0 * 64]);
95          fdct(&data[1 * 64]);          fdct((short * const)&data[1 * 64]);
96          fdct(&data[2 * 64]);          fdct((short * const)&data[2 * 64]);
97          fdct(&data[3 * 64]);          fdct((short * const)&data[3 * 64]);
98          fdct(&data[4 * 64]);          fdct((short * const)&data[4 * 64]);
99          fdct(&data[5 * 64]);          fdct((short * const)&data[5 * 64]);
100          stop_dct_timer();          stop_dct_timer();
101  }  }
102    
# Line 106  Line 106 
106             const uint8_t cbp)             const uint8_t cbp)
107  {  {
108          start_timer();          start_timer();
109          if(cbp & (1 << (5 - 0))) idct(&data[0 * 64]);          if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]);
110          if(cbp & (1 << (5 - 1))) idct(&data[1 * 64]);          if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]);
111          if(cbp & (1 << (5 - 2))) idct(&data[2 * 64]);          if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]);
112          if(cbp & (1 << (5 - 3))) idct(&data[3 * 64]);          if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]);
113          if(cbp & (1 << (5 - 4))) idct(&data[4 * 64]);          if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]);
114          if(cbp & (1 << (5 - 5))) idct(&data[5 * 64]);          if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]);
115          stop_idct_timer();          stop_idct_timer();
116  }  }
117    
# Line 123  Line 123 
123                           int16_t qcoeff[6 * 64],                           int16_t qcoeff[6 * 64],
124                           int16_t data[6*64])                           int16_t data[6*64])
125  {  {
126          int i;          int scaler_lum, scaler_chr;
127            quant_intraFuncPtr quant;
128    
129          for (i = 0; i < 6; i++) {          /* check if quant matrices need to be re-initialized with new quant */
130                  uint32_t iDcScaler = get_dc_scaler(pMB->quant, i < 4);          if (pParam->vol_flags & XVID_VOL_MPEGQUANT) {
131                    if (pParam->last_quant_initialized_intra != pMB->quant) {
132                            init_intra_matrix(pParam->mpeg_quant_matrices, pMB->quant);
133                    }
134                    quant = quant_mpeg_intra;
135            } else {
136                    quant = quant_h263_intra;
137            }
138    
139            scaler_lum = get_dc_scaler(pMB->quant, 1);
140            scaler_chr = get_dc_scaler(pMB->quant, 0);
141    
142                  /* Quantize the block */                  /* Quantize the block */
143                  start_timer();                  start_timer();
144                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT)) {          quant(&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145                          quant_intra(&data[i * 64], &qcoeff[i * 64], pMB->quant, iDcScaler);          quant(&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
146                  } else {          quant(&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
147                          quant4_intra(&data[i * 64], &qcoeff[i * 64], pMB->quant, iDcScaler);          quant(&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
148                  }          quant(&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
149            quant(&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
150                  stop_quant_timer();                  stop_quant_timer();
151          }          }
 }  
152    
153  /* DeQuantize all blocks -- Intra mode */  /* DeQuantize all blocks -- Intra mode */
154  static __inline void  static __inline void
# Line 146  Line 157 
157                             int16_t qcoeff[6 * 64],                             int16_t qcoeff[6 * 64],
158                             int16_t data[6*64])                             int16_t data[6*64])
159  {  {
160          int i;          int mpeg;
161            int scaler_lum, scaler_chr;
162    
163          for (i = 0; i < 6; i++) {          quant_intraFuncPtr const dequant[2] =
164                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);                  {
165                            dequant_h263_intra,
166                            dequant_mpeg_intra
167                    };
168    
169            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
170            scaler_lum = get_dc_scaler(iQuant, 1);
171            scaler_chr = get_dc_scaler(iQuant, 0);
172    
173                  start_timer();                  start_timer();
174                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT))          dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
175                          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);
176                  else          dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
177                          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);
178            dequant[mpeg](&qcoeff[4 * 64], &data[4 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
179            dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
180                  stop_iquant_timer();                  stop_iquant_timer();
181          }          }
 }  
   
   
 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);  
182    
183  static int  static int
184  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,
185                                               const int16_t *const In,
186                                               int Q,
187                                               const uint16_t * const Zigzag,
188                                               const uint16_t * const QuantMatrix,
189                                               int Non_Zero,
190                                               int Sum,
191                                               int Lambda_Mod,
192                                               const uint32_t rel_var8,
193                                               const int Metric);
194    
195  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
196  static __inline uint8_t  static __inline uint8_t
# Line 182  Line 206 
206          int i;          int i;
207          uint8_t cbp = 0;          uint8_t cbp = 0;
208          int sum;          int sum;
209          int code_block;          int code_block, mpeg;
210    
211            quant_interFuncPtr const quant[2] =
212                    {
213                            quant_h263_inter,
214                            quant_mpeg_inter
215                    };
216    
217            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
218    
219          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
220    
221                  /* Quantize the block */                  /* Quantize the block */
222                  start_timer();                  start_timer();
223                  if (!(pParam->vol_flags & XVID_VOL_MPEGQUANT)) {  
224                          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);
225                          if ( (sum) && (frame->vop_flags & XVID_VOP_TRELLISQUANT) ) {  
226                                  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)) {
227                                  limit = 1;                          const uint16_t *matrix;
228                          }                          const static uint16_t h263matrix[] =
229                  } else {                                  {
230                          sum = quant4_inter(&qcoeff[i * 64], &data[i * 64], pMB->quant);                                          16, 16, 16, 16, 16, 16, 16, 16,
231  //                      if ( (sum) && (frame->vop_flags & XVID_VOP_TRELLISQUANT) )                                          16, 16, 16, 16, 16, 16, 16, 16,
232  //                              sum = dct_quantize_trellis_mpeg_c (&qcoeff[i*64], &data[i*64], pMB->quant)+1;                                          16, 16, 16, 16, 16, 16, 16, 16,
233                                            16, 16, 16, 16, 16, 16, 16, 16,
234                                            16, 16, 16, 16, 16, 16, 16, 16,
235                                            16, 16, 16, 16, 16, 16, 16, 16,
236                                            16, 16, 16, 16, 16, 16, 16, 16,
237                                            16, 16, 16, 16, 16, 16, 16, 16
238                                    };
239    
240                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
241                            sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
242                                                                                     pMB->quant, &scan_tables[0][0],
243                                                                                     matrix,
244                                                                                     63,
245                                                                                     sum,
246                                                                                     pMB->lambda[i],
247                                                                                     pMB->rel_var8[i],
248                                                                                     !!(frame->vop_flags & XVID_VOP_RD_PSNRHVSM));
249                  }                  }
250                  stop_quant_timer();                  stop_quant_timer();
251    
# Line 236  Line 284 
284                             int16_t qcoeff[6 * 64],                             int16_t qcoeff[6 * 64],
285                             const uint8_t cbp)                             const uint8_t cbp)
286  {  {
287          int i;          int mpeg;
288    
289            quant_interFuncPtr const dequant[2] =
290                    {
291                            dequant_h263_inter,
292                            dequant_mpeg_inter
293                    };
294    
295            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
296    
         for (i = 0; i < 6; i++) {  
                 if (cbp & (1 << (5 - i))) {  
297                          start_timer();                          start_timer();
298                          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);
299                                  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);
300                          else          if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant, pParam->mpeg_quant_matrices);
301                                  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);
302            if(cbp & (1 << (5 - 4))) dequant[mpeg](&data[4 * 64], &qcoeff[4 * 64], iQuant, pParam->mpeg_quant_matrices);
303            if(cbp & (1 << (5 - 5))) dequant[mpeg](&data[5 * 64], &qcoeff[5 * 64], iQuant, pParam->mpeg_quant_matrices);
304                          stop_iquant_timer();                          stop_iquant_timer();
305                  }                  }
         }  
 }  
306    
307  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);
308  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 319 
319          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
320          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
321          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         int32_t cst;  
322          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
323          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 {  
324    
325                  /* Image pointers */                  /* Image pointers */
326                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
327                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
328                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
329    
                 /* Block size */  
                 cst = 8;  
   
                 /* Operation function */  
                 transfer_op = (transfer_operation_8to16_t*)transfer_8to16copy;  
         }  
   
330          /* Do the transfer */          /* Do the transfer */
331          start_timer();          start_timer();
332          transfer_op(&data[0 * 64], pY_Cur, stride);          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);
333          transfer_op(&data[1 * 64], pY_Cur + cst, stride);          transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);
334          transfer_op(&data[2 * 64], pY_Cur + next_block, stride);          transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);
335          transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);          transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);
336          transfer_op(&data[4 * 64], pU_Cur, stride2);          transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);
337          transfer_op(&data[5 * 64], pV_Cur, stride2);          transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);
338          stop_transfer_timer();          stop_transfer_timer();
339  }  }
340    
# Line 314  Line 345 
345                           const uint32_t x_pos,                           const uint32_t x_pos,
346                           const uint32_t y_pos,                           const uint32_t y_pos,
347                           int16_t data[6 * 64],                           int16_t data[6 * 64],
348                           const uint32_t add,                           const uint32_t add, /* Must be 1 or 0 */
349                           const uint8_t cbp)                           const uint8_t cbp)
350  {  {
351          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
352          uint32_t stride = pParam->edged_width;          uint32_t stride = pParam->edged_width;
353          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
354          uint32_t next_block = stride * 8;          uint32_t next_block = stride * 8;
         uint32_t cst;  
355          const IMAGE * const pCurrent = &frame->image;          const IMAGE * const pCurrent = &frame->image;
         transfer_operation_16to8_t *transfer_op = NULL;  
356    
357          if (pMB->field_dct) {          /* Array of function pointers, indexed by [add] */
358                  next_block = stride;          transfer_operation_16to8_t  * const functions[2] =
359                  stride *= 2;                  {
360          }                          (transfer_operation_16to8_t*)transfer_16to8copy,
361                            (transfer_operation_16to8_t*)transfer_16to8add,
362          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;  
363    
364                  /* 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 {  
365    
366                  /* Image pointers */                  /* Image pointers */
367                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);                  pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);
368                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
369                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
370    
371                  /* Block size */          if (pMB->field_dct) {
372                  cst = 8;                  next_block = stride;
373                    stride *= 2;
374            }
375    
376                  /* Operation function */                  /* Operation function */
377                  if(add)          transfer_op = functions[add];
                         transfer_op = (transfer_operation_16to8_t*)transfer_16to8add;  
                 else  
                         transfer_op = (transfer_operation_16to8_t*)transfer_16to8copy;  
         }  
378    
379          /* Do the operation */          /* Do the operation */
380          start_timer();          start_timer();
381          if (cbp&32) transfer_op(pY_Cur, &data[0 * 64], stride);          if (cbp&32) transfer_op(pY_Cur, &data[0 * 64], stride);
382          if (cbp&16) transfer_op(pY_Cur + cst, &data[1 * 64], stride);          if (cbp&16) transfer_op(pY_Cur + 8,                                     &data[1 * 64], stride);
383          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);
384          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);
385          if (cbp& 2) transfer_op(pU_Cur, &data[4 * 64], stride2);          if (cbp& 2) transfer_op(pU_Cur, &data[4 * 64], stride2);
386          if (cbp& 1) transfer_op(pV_Cur, &data[5 * 64], stride2);          if (cbp& 1) transfer_op(pV_Cur, &data[5 * 64], stride2);
387          stop_transfer_timer();          stop_transfer_timer();
# Line 419  Line 433 
433          uint8_t cbp;          uint8_t cbp;
434          uint32_t limit;          uint32_t limit;
435    
436          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
437           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
438    
439          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
440          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 430  Line 442 
442          /* Set the limit threshold */          /* Set the limit threshold */
443          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);
444    
445            if (frame->vop_flags & XVID_VOP_CARTOON)
446                    limit *= 3;
447    
448          /* Quantize the block */          /* Quantize the block */
449          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);
450    
# Line 457  Line 472 
472          uint8_t cbp;          uint8_t cbp;
473          uint32_t limit;          uint32_t limit;
474    
475          /*          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
476           * There is no MBTrans8to16 for Inter block, that's done in motion compensation           * already */
          * already  
          */  
477    
478          /* Perform DCT (and field decision) */          /* Perform DCT (and field decision) */
479          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
# Line 468  Line 481 
481          /* Set the limit threshold */          /* Set the limit threshold */
482          limit = BVOP_TOOSMALL_LIMIT;          limit = BVOP_TOOSMALL_LIMIT;
483    
484            if (frame->vop_flags & XVID_VOP_CARTOON)
485                    limit *= 2;
486    
487          /* Quantize the block */          /* Quantize the block */
488          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);
489    
# Line 475  Line 491 
491           * History comment:           * History comment:
492           * 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.
493           *           *
494           * 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
495           * to take care of that here           * have to take care of that here
496           */           */
497          if((pParam->plugin_flags & XVID_REQORIGINAL)) {          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
498    
# Line 546  Line 562 
562    
563          /* left blocks */          /* left blocks */
564    
565          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
566          MOVLINE(tmp, LINE(0, 1));          MOVLINE(tmp, LINE(0, 1));
567          MOVLINE(LINE(0, 1), LINE(0, 2));          MOVLINE(LINE(0, 1), LINE(0, 2));
568          MOVLINE(LINE(0, 2), LINE(0, 4));          MOVLINE(LINE(0, 2), LINE(0, 4));
569          MOVLINE(LINE(0, 4), LINE(2, 0));          MOVLINE(LINE(0, 4), LINE(2, 0));
570          MOVLINE(LINE(2, 0), tmp);          MOVLINE(LINE(2, 0), tmp);
571    
572          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
573          MOVLINE(tmp, LINE(0, 3));          MOVLINE(tmp, LINE(0, 3));
574          MOVLINE(LINE(0, 3), LINE(0, 6));          MOVLINE(LINE(0, 3), LINE(0, 6));
575          MOVLINE(LINE(0, 6), LINE(2, 4));          MOVLINE(LINE(0, 6), LINE(2, 4));
576          MOVLINE(LINE(2, 4), LINE(2, 1));          MOVLINE(LINE(2, 4), LINE(2, 1));
577          MOVLINE(LINE(2, 1), tmp);          MOVLINE(LINE(2, 1), tmp);
578    
579          // 5=10, 10=5          /* 5=10, 10=5 */
580          MOVLINE(tmp, LINE(0, 5));          MOVLINE(tmp, LINE(0, 5));
581          MOVLINE(LINE(0, 5), LINE(2, 2));          MOVLINE(LINE(0, 5), LINE(2, 2));
582          MOVLINE(LINE(2, 2), tmp);          MOVLINE(LINE(2, 2), tmp);
583    
584          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
585          MOVLINE(tmp, LINE(0, 7));          MOVLINE(tmp, LINE(0, 7));
586          MOVLINE(LINE(0, 7), LINE(2, 6));          MOVLINE(LINE(0, 7), LINE(2, 6));
587          MOVLINE(LINE(2, 6), LINE(2, 5));          MOVLINE(LINE(2, 6), LINE(2, 5));
# Line 574  Line 590 
590    
591          /* right blocks */          /* right blocks */
592    
593          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
594          MOVLINE(tmp, LINE(1, 1));          MOVLINE(tmp, LINE(1, 1));
595          MOVLINE(LINE(1, 1), LINE(1, 2));          MOVLINE(LINE(1, 1), LINE(1, 2));
596          MOVLINE(LINE(1, 2), LINE(1, 4));          MOVLINE(LINE(1, 2), LINE(1, 4));
597          MOVLINE(LINE(1, 4), LINE(3, 0));          MOVLINE(LINE(1, 4), LINE(3, 0));
598          MOVLINE(LINE(3, 0), tmp);          MOVLINE(LINE(3, 0), tmp);
599    
600          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
601          MOVLINE(tmp, LINE(1, 3));          MOVLINE(tmp, LINE(1, 3));
602          MOVLINE(LINE(1, 3), LINE(1, 6));          MOVLINE(LINE(1, 3), LINE(1, 6));
603          MOVLINE(LINE(1, 6), LINE(3, 4));          MOVLINE(LINE(1, 6), LINE(3, 4));
604          MOVLINE(LINE(3, 4), LINE(3, 1));          MOVLINE(LINE(3, 4), LINE(3, 1));
605          MOVLINE(LINE(3, 1), tmp);          MOVLINE(LINE(3, 1), tmp);
606    
607          // 5=10, 10=5          /* 5=10, 10=5 */
608          MOVLINE(tmp, LINE(1, 5));          MOVLINE(tmp, LINE(1, 5));
609          MOVLINE(LINE(1, 5), LINE(3, 2));          MOVLINE(LINE(1, 5), LINE(3, 2));
610          MOVLINE(LINE(3, 2), tmp);          MOVLINE(LINE(3, 2), tmp);
611    
612          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
613          MOVLINE(tmp, LINE(1, 7));          MOVLINE(tmp, LINE(1, 7));
614          MOVLINE(LINE(1, 7), LINE(3, 6));          MOVLINE(LINE(1, 7), LINE(3, 6));
615          MOVLINE(LINE(3, 6), LINE(3, 5));          MOVLINE(LINE(3, 6), LINE(3, 5));
# Line 601  Line 617 
617          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
618  }  }
619    
620    /*****************************************************************************
621     *               Trellis based R-D optimal quantization
622     *
623     *   Trellis Quant code (C) 2003 Pascal Massimino skal(at)planet-d.net
624     *
625     ****************************************************************************/
626    
627    /*----------------------------------------------------------------------------
628     *
629     *        Trellis-Based quantization
630     *
631     * So far I understand this paper:
632     *
633     *  "Trellis-Based R-D Optimal Quantization in H.263+"
634     *    J.Wen, M.Luttrell, J.Villasenor
635     *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
636     *
637     * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
638     * Source Shortest Path algo. But due to the underlying graph structure
639     * ("Trellis"), it can be turned into a dynamic programming algo,
640     * partially saving the explicit graph's nodes representation. And
641     * without using a heap, since the open frontier of the DAG is always
642     * known, and of fixed size.
643     *--------------------------------------------------------------------------*/
644    
645    
646    
647  /************************************************************************  /* 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.  
648    
649    // let's factorize:  /* let's factorize: */
650  static const uint8_t Code_Len0[64] = {  static const uint8_t Code_Len0[64] = {
651    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
652    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };    30,30,30,30,30,30,30,30,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 711 
711     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,
712    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 };
713    
714    // a few more table for LAST table:  /* a few more table for LAST table: */
715  static const uint8_t Code_Len21[64] = {  static const uint8_t Code_Len21[64] = {
716    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,
717    30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};    30,30,30,30,30,30,30,30,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 726 
726    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};
727    
728    
729  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] */
730    Code_Len20,Code_Len19,Code_Len18,Code_Len17,    Code_Len20,Code_Len19,Code_Len18,Code_Len17,
731    Code_Len16,Code_Len15,Code_Len14,Code_Len13,    Code_Len16,Code_Len15,Code_Len14,Code_Len13,
732    Code_Len12,Code_Len11,Code_Len10,Code_Len9,    Code_Len12,Code_Len11,Code_Len10,Code_Len9,
# Line 731  Line 735 
735    Code_Len2, Code_Len1, Code_Len1, Code_Len1,    Code_Len2, Code_Len1, Code_Len1, Code_Len1,
736  };  };
737    
738  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] */
739    Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,    Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
740  };  };
741    
742  #define TL(q) 0xfe00/(q*q)  /* TL_SHIFT controls the precision of the RD optimizations in trellis
743     * valid range is [10..16]. The bigger, the more trellis is vulnerable
744     * to overflows in cost formulas.
745     *  - 10 allows ac values up to 2^11 == 2048
746     *  - 16 allows ac values up to 2^8 == 256
747     */
748    #define TL_SHIFT 11
749    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
750    
751  static const int Trellis_Lambda_Tabs[31] = {  static const int Trellis_Lambda_Tabs[31] = {
752           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 756 
756  };  };
757  #undef TL  #undef TL
758    
759  static __inline int Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)  static int __inline
760    Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)
761  {  {
762    while(i>=0)    while(i>=0)
763      if (C[Zigzag[i]])      if (C[Zigzag[i]])
# Line 754  Line 766 
766    return -1;    return -1;
767  }  }
768    
769  //////////////////////////////////////////////////////////  #define TRELLIS_MIN_EFFORT      3
 // this routine has been strippen of all debug code  
 //////////////////////////////////////////////////////////  
770    
771  static int  static __inline uint32_t calc_mseh(int16_t dQ, uint16_t mask,
772  dct_quantize_trellis_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)                                     const int index, const int Lambda)
773  {  {
774            uint32_t t = (mask * Inv_iMask_Coeff[index] + 32) >> 7;
775            uint16_t u = abs(dQ) << 4;
776            uint16_t thresh = (t < 65536) ? t : 65535;
777    
778            if (u <= thresh)
779                    u = 0; /* The error is not perceivable */
780            else
781                    u -= thresh;
782    
783      // Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),          u = ((u + iCSF_Round[index]) * iCSF_Coeff[index]) >> 16;
     // not quantized one (Out[]). However, it only improves the result *very*  
     // slightly (~0.01dB), whereas speed drops to crawling level :)  
     // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,  
784    
785            return (((Lambda*u*u)>>4) + 4*Lambda*dQ*dQ) / 5;
786    }
787    
788    /* this routine has been strippen of all debug code */
789    static int
790    dct_quantize_trellis_c(int16_t *const Out,
791                                               const int16_t *const In,
792                                               int Q,
793                                               const uint16_t * const Zigzag,
794                                               const uint16_t * const QuantMatrix,
795                                               int Non_Zero,
796                                               int Sum,
797                                               int Lambda_Mod,
798                                               const uint32_t rel_var8,
799                                               const int Metric)
800    {
801    
802            /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
803             * (In[]), not quantized one (Out[]). However, it only improves the result
804             * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
805             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
806             * helps. */
807    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
808    
809    NODE Nodes[65], Last;          NODE Nodes[65], Last = { 0, 0};
810    uint32_t Run_Costs0[64+1];    uint32_t Run_Costs0[64+1];
811    uint32_t * const Run_Costs = Run_Costs0 + 1;    uint32_t * const Run_Costs = Run_Costs0 + 1;
812    const int Mult = 2*Q;  
813    const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
814    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  
815    
816    int Run_Start = -1;    int Run_Start = -1;
817    uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
818    
819    int Last_Node = -1;    int Last_Node = -1;
820    uint32_t Last_Cost = 0;    uint32_t Last_Cost = 0;
821    
822    int i, j;    int i, j;
823    Run_Costs[-1] = 2<<16;                          // source (w/ CBP penalty)  
824            uint32_t mask = (Metric) ? ((isqrt(2*coeff8_energy(In)*rel_var8) + 48) >> 6) : 0;
825    
826            /* source (w/ CBP penalty) */
827            Run_Costs[-1] = 2<<TL_SHIFT;
828    
829    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
830    if (Non_Zero<0)          if (Non_Zero < TRELLIS_MIN_EFFORT)
831        return -1;                  Non_Zero = TRELLIS_MIN_EFFORT;
832    
833            for(i=0; i<=Non_Zero; i++) {
834                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
835                    const int Mult = 2*q;
836                    const int Bias = (q-1) | 1;
837                    const int Lev0 = Mult + Bias;
838    
   for(i=0; i<=Non_Zero; i++)  
   {  
839      const int AC = In[Zigzag[i]];      const int AC = In[Zigzag[i]];
840      const int Level1 = Out[Zigzag[i]];      const int Level1 = Out[Zigzag[i]];
841      const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = (Metric) ? (calc_mseh(AC, mask, Zigzag[i], Lambda)) : (Lambda* AC*AC);
842      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
843      Last_Cost += Dist0;      Last_Cost += Dist0;
844    
845      if ((uint32_t)(Level1+1)<3)                 // very specialized loop for -1,0,+1                  /* very specialized loop for -1,0,+1 */
846      {                  if ((uint32_t)(Level1+1)<3) {
847          int dQ;          int dQ;
848                  int Run;                  int Run;
849        uint32_t Cost0;        uint32_t Cost0;
# Line 811  Line 855 
855          Nodes[i].Level = 1;          Nodes[i].Level = 1;
856          dQ = Lev0 - AC;          dQ = Lev0 - AC;
857        }        }
858                  Cost0 = Lambda*dQ*dQ;                          Cost0 = (Metric) ? (calc_mseh(dQ, mask, Zigzag[i], Lambda)) : (Lambda*dQ*dQ);
859    
860        Nodes[i].Run = 1;        Nodes[i].Run = 1;
861        Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
862        for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run) {
       {  
863          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
864          const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
865          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
866    
867            // TODO: what about tie-breaks? Should we favor short runs or                                  /* TODO: what about tie-breaks? Should we favor short runs or
868            // long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
869            // spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
870    
871                          // (I'd say: favour short runs => hifreq errors (HVS) -- gruel )                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
872    
873          if (Cost<Best_Cost) {          if (Cost<Best_Cost) {
874            Best_Cost    = Cost;            Best_Cost    = Cost;
# Line 840  Line 883 
883        }        }
884        if (Last_Node==i)        if (Last_Node==i)
885                          Last.Level = Nodes[i].Level;                          Last.Level = Nodes[i].Level;
886      }                  } else if (51U>(uint32_t)(Level1+25)) {
887      else                      // "big" levels                          /* "big" levels (not less than ESC3, though) */
     {  
888        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;
889        int Level2;        int Level2;
890        int dQ1, dQ2;        int dQ1, dQ2;
# Line 858  Line 900 
900          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
901          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;
902          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;
903        } else { // Level1<-1                          } else { /* Level1<-1 */
904          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
905          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
906          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 867  Line 909 
909          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;
910          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;
911        }        }
912    
913                            if (Metric) {
914                                    Dist1 = calc_mseh(dQ1, mask, Zigzag[i], Lambda);
915                                    Dist2 = calc_mseh(dQ2, mask, Zigzag[i], Lambda);
916                            }
917                            else {
918        Dist1 = Lambda*dQ1*dQ1;        Dist1 = Lambda*dQ1*dQ1;
919        Dist2 = Lambda*dQ2*dQ2;        Dist2 = Lambda*dQ2*dQ2;
920                            }
921        dDist21 = Dist2-Dist1;        dDist21 = Dist2-Dist1;
922    
923        for(Run=i-Run_Start; Run>0; --Run)        for(Run=i-Run_Start; Run>0; --Run)
# Line 877  Line 926 
926          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
927          int bLevel;          int bLevel;
928    
929  // for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
930  //        if (Cost_Base>=Best_Cost) continue;                                   * uncomment the following:
931  // (? doesn't seem to have any effect -- gruel )                                   *              if (Cost_Base>=Best_Cost) continue;
932                                     * (? doesn't seem to have any effect -- gruel ) */
933    
934          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
935          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
936    
937          if (Cost2<Cost1) {          if (Cost2<Cost1) {
938                           Cost1 = Cost2;                           Cost1 = Cost2;
939                           bLevel = Level2;                           bLevel = Level2;
940                    } else                                  } else {
941                           bLevel = Level1;                           bLevel = Level1;
942                                    }
943    
944          if (Cost1<Best_Cost) {          if (Cost1<Best_Cost) {
945            Best_Cost = Cost1;            Best_Cost = Cost1;
# Line 896  Line 947 
947            Nodes[i].Level = bLevel;            Nodes[i].Level = bLevel;
948          }          }
949    
950          Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
951          Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
952    
953          if (Cost2<Cost1) {          if (Cost2<Cost1) {
954                           Cost1 = Cost2;                           Cost1 = Cost2;
955                           bLevel = Level2;                           bLevel = Level2;
956                    } else                                  } else {
957                           bLevel = Level1;                           bLevel = Level1;
958                                    }
959    
960          if (Cost1<Last_Cost) {          if (Cost1<Last_Cost) {
961            Last_Cost  = Cost1;            Last_Cost  = Cost1;
# Line 911  Line 963 
963            Last.Level = bLevel;            Last.Level = bLevel;
964            Last_Node  = i;            Last_Node  = i;
965          }          }
966        } //end of "for Run"                          } /* end of "for Run" */
967                    } else {
968                            /* Very very high levels, with no chance of being optimizable
969                             * => Simply pick best Run. */
970                            int Run;
971                            for(Run=i-Run_Start; Run>0; --Run) {
972                                    /* 30 bits + no distortion */
973                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
974                                    if (Cost<Best_Cost) {
975                                            Best_Cost = Cost;
976                                            Nodes[i].Run   = Run;
977                                            Nodes[i].Level = Level1;
978                                    }
979    
980                                    if (Cost<Last_Cost) {
981                                            Last_Cost  = Cost;
982                                            Last.Run   = Run;
983                                            Last.Level = Level1;
984                                            Last_Node  = i;
985                                    }
986                            }
987      }      }
988    
989    
990      Run_Costs[i] = Best_Cost;      Run_Costs[i] = Best_Cost;
991    
992      if (Best_Cost < Min_Cost + Dist0) {      if (Best_Cost < Min_Cost + Dist0) {
993        Min_Cost = Best_Cost;        Min_Cost = Best_Cost;
994        Run_Start = i;        Run_Start = i;
995      }                  } else {
996      else                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
997      {                           * there's a code shorter by 1 bit for a larger run (!), same
998          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * level. We give it a chance by not moving the left barrier too
999          // a code shorter by 1 bit for a larger run (!), same level. We give                           * much. */
1000          // 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) )  
1001          Run_Start++;          Run_Start++;
1002    
1003          // spread on preceding coeffs the cost incurred by skipping this one                          /* spread on preceding coeffs the cost incurred by skipping this
1004                             * one */
1005        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1006        Min_Cost += Dist0;        Min_Cost += Dist0;
1007      }      }
1008    }    }
1009    
1010            /* It seems trellis doesn't give good results... just leave the block untouched
1011             * and return the original sum value */
1012    if (Last_Node<0)    if (Last_Node<0)
1013      return -1;                  return Sum;
1014    
1015         // reconstruct optimal sequence backward with surviving paths          /* reconstruct optimal sequence backward with surviving paths */
1016    memset(Out, 0x00, 64*sizeof(*Out));    memset(Out, 0x00, 64*sizeof(*Out));
1017    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
1018    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;
1019            Sum = abs(Last.Level);
1020    while(i>=0) {    while(i>=0) {
1021      Out[Zigzag[i]] = Nodes[i].Level;      Out[Zigzag[i]] = Nodes[i].Level;
1022                    Sum += abs(Nodes[i].Level);
1023      i -= Nodes[i].Run;      i -= Nodes[i].Run;
1024    }    }
   return Last_Node;  
 }  
   
1025    
1026            return Sum;
1027    }
1028    
1029    /* original version including heavy debugging info */
   
   
   
   
   
   
   
 //////////////////////////////////////////////////////////  
 // original version including heavy debugging info  
 //////////////////////////////////////////////////////////  
   
1030    
1031  #ifdef DBGTRELL  #ifdef DBGTRELL
1032    
# Line 987  Line 1050 
1050      int j=0, j0=0;      int j=0, j0=0;
1051      int Run, Level;      int Run, Level;
1052    
1053      Bits = 2;   // CBP                  Bits = 2;   /* CBP */
1054      while(j<Last) {      while(j<Last) {
1055        while(!C[Zigzag[j]])        while(!C[Zigzag[j]])
1056                          j++;                          j++;
# Line 1019  Line 1082 
1082      V -= Ref[Zigzag[i]];      V -= Ref[Zigzag[i]];
1083      Dist += V*V;      Dist += V*V;
1084    }    }
1085    Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1086    if (DBG==1)    if (DBG==1)
1087      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 );
1088    return Cost;    return Cost;
# Line 1034  Line 1097 
1097  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)
1098  {  {
1099    
1100      // Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),      /*
1101      // 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[]),
1102      // slightly (~0.01dB), whereas speed drops to crawling level :)           * not quantized one (Out[]). However, it only improves the result *very*
1103      // Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps,           * slightly (~0.01dB), whereas speed drops to crawling level :)
1104             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.
1105             */
1106    typedef struct { int16_t Run, Level; } NODE;    typedef struct { int16_t Run, Level; } NODE;
1107    
1108    NODE Nodes[65], Last;    NODE Nodes[65], Last;
# Line 1047  Line 1111 
1111    const int Mult = 2*Q;    const int Mult = 2*Q;
1112    const int Bias = (Q-1) | 1;    const int Bias = (Q-1) | 1;
1113    const int Lev0 = Mult + Bias;    const int Lev0 = Mult + Bias;
1114    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 */
1115    
1116    int Run_Start = -1;    int Run_Start = -1;
1117    Run_Costs[-1] = 2<<16;                          // source (w/ CBP penalty)          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1118    uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1119    
1120    int Last_Node = -1;    int Last_Node = -1;
1121    uint32_t Last_Cost = 0;    uint32_t Last_Cost = 0;
# Line 1059  Line 1123 
1123    int i, j;    int i, j;
1124    
1125  #if (DBG>0)  #if (DBG>0)
1126    Last.Level = 0; Last.Run = -1; // just initialize to smthg          Last.Level = 0; Last.Run = -1; /* just initialize to smthg */
1127  #endif  #endif
1128    
1129    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);    Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
# Line 1074  Line 1138 
1138      uint32_t Best_Cost = 0xf0000000;      uint32_t Best_Cost = 0xf0000000;
1139      Last_Cost += Dist0;      Last_Cost += Dist0;
1140    
1141      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 */
1142      {      {
1143          int dQ;          int dQ;
1144                  int Run;                  int Run;
# Line 1090  Line 1154 
1154                  Cost0 = Lambda*dQ*dQ;                  Cost0 = Lambda*dQ*dQ;
1155    
1156        Nodes[i].Run = 1;        Nodes[i].Run = 1;
1157        Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1158        for(Run=i-Run_Start; Run>0; --Run)        for(Run=i-Run_Start; Run>0; --Run)
1159        {        {
1160          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];          const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1161          const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1162          const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1163    
1164            // TODO: what about tie-breaks? Should we favor short runs or                                  /*
1165            // long runs? Although the error is the same, it would not be                                   * TODO: what about tie-breaks? Should we favor short runs or
1166            // spread the same way along high and low frequencies...                                   * long runs? Although the error is the same, it would not be
1167                                     * spread the same way along high and low frequencies...
1168                                     */
1169          if (Cost<Best_Cost) {          if (Cost<Best_Cost) {
1170            Best_Cost    = Cost;            Best_Cost    = Cost;
1171            Nodes[i].Run = Run;            Nodes[i].Run = Run;
# Line 1129  Line 1195 
1195          printf( "\n" );          printf( "\n" );
1196        }        }
1197      }      }
1198      else                      // "big" levels                  else                      /* "big" levels */
1199      {      {
1200        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;
1201        int Level2;        int Level2;
# Line 1146  Line 1212 
1212          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;          Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
1213          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;
1214          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;
1215        } else { // Level1<-1                          } else { /* Level1<-1 */
1216          dQ1 = Level1*Mult-AC - Bias;          dQ1 = Level1*Mult-AC - Bias;
1217          dQ2 = dQ1 + Mult;          dQ2 = dQ1 + Mult;
1218          Level2 = Level1 + 1;          Level2 = Level1 + 1;
# Line 1165  Line 1231 
1231          uint32_t Cost1, Cost2;          uint32_t Cost1, Cost2;
1232          int bLevel;          int bLevel;
1233    
1234  // for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:  /*
1235  //        if (Cost_Base>=Best_Cost) continue;   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1236     *        if (Cost_Base>=Best_Cost) continue;
1237          Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);   */
1238          Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1239                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1240    
1241          if (Cost2<Cost1) {          if (Cost2<Cost1) {
1242                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1183  Line 1250 
1250            Nodes[i].Level = bLevel;            Nodes[i].Level = bLevel;
1251          }          }
1252    
1253          Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1254          Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1255    
1256          if (Cost2<Cost1) {          if (Cost2<Cost1) {
1257                           Cost1 = Cost2;                           Cost1 = Cost2;
# Line 1198  Line 1265 
1265            Last.Level = bLevel;            Last.Level = bLevel;
1266            Last_Node  = i;            Last_Node  = i;
1267          }          }
1268        } //end of "for Run"                          } /* end of "for Run" */
1269    
1270        if (DBG==1) {        if (DBG==1) {
1271          Run_Costs[i] = Best_Cost;          Run_Costs[i] = Best_Cost;
# Line 1224  Line 1291 
1291      }      }
1292      else      else
1293      {      {
1294          // as noticed by Michael Niedermayer (michaelni at gmx.at), there's                          /*
1295          // 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
1296          // 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
1297                             * it a chance by not moving the left barrier too much.
1298                             */
1299    
1300        while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1301          Run_Start++;          Run_Start++;
1302    
1303          // spread on preceding coeffs the cost incurred by skipping this one                          /* spread on preceding coeffs the cost incurred by skipping this one */
1304        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;        for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1305        Min_Cost += Dist0;        Min_Cost += Dist0;
1306      }      }
# Line 1249  Line 1318 
1318    if (Last_Node<0)    if (Last_Node<0)
1319      return -1;      return -1;
1320    
1321         // reconstruct optimal sequence backward with surviving paths          /* reconstruct optimal sequence backward with surviving paths */
1322    memset(Out, 0x00, 64*sizeof(*Out));    memset(Out, 0x00, 64*sizeof(*Out));
1323    Out[Zigzag[Last_Node]] = Last.Level;    Out[Zigzag[Last_Node]] = Last.Level;
1324    i = Last_Node - Last.Run;    i = Last_Node - Last.Run;

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

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