[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.12, Thu Sep 5 21:44:11 2002 UTC revision 1.23, Mon Mar 22 22:36:24 2004 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /*****************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - MacroBlock transfer and quantization -   *  - MB Transfert/Quantization functions -
5   *   *
6   *  Copyright(C) 2002-2001 Michael Militzer <isibaar@xvid.org>   *  Copyright(C) 2001-2003  Peter Ross <pross@xvid.org>
7   *               2002-2001 Peter Ross <pross@cs.rmit.edu.au>   *               2001-2003  Michael Militzer <isibaar@xvid.org>
8   *   *               2003       Edouard Gomez <ed.gomez@free.fr>
  *  This program is an implementation of a part of one or more MPEG-4  
  *  Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  
  *  to use this software module in hardware or software products are  
  *  advised that its use may infringe existing patents or copyrights, and  
  *  any such use would be at such party's own risk.  The original  
  *  developer of this software module and his/her company, and subsequent  
  *  editors and their companies, will have no liability for use of this  
  *  software or modifications or derivatives thereof.  
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
11   *  it under the terms of the GNU General Public License as published by   *  it under the terms of the GNU General Public License as published by
# Line 33  Line 25 
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
28    #include <stdio.h>
29    #include <stdlib.h>
30  #include <string.h>  #include <string.h>
31    
32  #include "../portab.h"  #include "../portab.h"
# Line 41  Line 35 
35  #include "../global.h"  #include "../global.h"
36  #include "mem_transfer.h"  #include "mem_transfer.h"
37  #include "timer.h"  #include "timer.h"
38    #include "../bitstream/mbcoding.h"
39    #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  #define MIN(X, Y) ((X)<(Y)?(X):(Y))  #include "../image/reduced.h"
46  #define MAX(X, Y) ((X)>(Y)?(X):(Y))  #include  "../quant/quant_matrix.h"
47    
48  #define TOOSMALL_LIMIT 3                /* skip blocks having a coefficient sum below this value */  MBFIELDTEST_PTR MBFieldTest;
49    
50  /* this isnt pretty, but its better than 20 ifdefs */  /*
51     * Skip blocks having a coefficient sum below this value. This value will be
52     * corrected according to the MB quantizer to avoid artifacts for quant==1
53     */
54    #define PVOP_TOOSMALL_LIMIT 1
55    #define BVOP_TOOSMALL_LIMIT 3
56    
57  void  /*****************************************************************************
58  MBTransQuantIntra(const MBParam * pParam,   * Local functions
59                                    FRAMEINFO * frame,   ****************************************************************************/
                                   MACROBLOCK * pMB,  
                                   const uint32_t x_pos,  
                                   const uint32_t y_pos,  
                                   int16_t data[6 * 64],  
                                   int16_t qcoeff[6 * 64])  
 {  
60    
61          uint32_t stride = pParam->edged_width;  /* permute block and return field dct choice */
62          uint32_t stride2 = stride / 2;  static __inline uint32_t
63          uint32_t next_block = stride * 8;  MBDecideFieldDCT(int16_t data[6 * 64])
64          uint32_t i;  {
65          uint32_t iQuant = frame->quant;          uint32_t field = MBFieldTest(data);
         uint8_t *pY_Cur, *pU_Cur, *pV_Cur;  
         IMAGE *pCurrent = &frame->image;  
66    
67          pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);          if (field)
68          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  MBFrameToField(data);
         pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);  
69    
70          start_timer();          return field;
71          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);  }
         transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);  
         transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);  
         transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);  
         transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);  
         transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);  
         stop_transfer_timer();  
72    
73    /* Performs Forward DCT on all blocks */
74    static __inline void
75    MBfDCT(const MBParam * const pParam,
76               const FRAMEINFO * const frame,
77               MACROBLOCK * const pMB,
78               uint32_t x_pos,
79               uint32_t y_pos,
80               int16_t data[6 * 64])
81    {
82            /* Handles interlacing */
83          start_timer();          start_timer();
84          pMB->field_dct = 0;          pMB->field_dct = 0;
85          if ((frame->global_flags & XVID_INTERLACING) &&          if ((frame->vol_flags & XVID_VOL_INTERLACING) &&
86                  (x_pos>0) && (x_pos<pParam->mb_width-1) &&                  (x_pos>0) && (x_pos<pParam->mb_width-1) &&
87                  (y_pos>0) && (y_pos<pParam->mb_height-1)) {                  (y_pos>0) && (y_pos<pParam->mb_height-1)) {
88                  pMB->field_dct = MBDecideFieldDCT(data);                  pMB->field_dct = MBDecideFieldDCT(data);
89          }          }
90          stop_interlacing_timer();          stop_interlacing_timer();
91    
92          for (i = 0; i < 6; i++) {          /* Perform DCT */
                 uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);  
   
93                  start_timer();                  start_timer();
94                  fdct(&data[i * 64]);          fdct(&data[0 * 64]);
95            fdct(&data[1 * 64]);
96            fdct(&data[2 * 64]);
97            fdct(&data[3 * 64]);
98            fdct(&data[4 * 64]);
99            fdct(&data[5 * 64]);
100                  stop_dct_timer();                  stop_dct_timer();
   
                 if (pParam->m_quant_type == H263_QUANT) {  
                         start_timer();  
                         quant_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);  
                         stop_quant_timer();  
   
                         start_timer();  
                         dequant_intra(&data[i * 64], &qcoeff[i * 64], iQuant, iDcScaler);  
                         stop_iquant_timer();  
                 } else {  
                         start_timer();  
                         quant4_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);  
                         stop_quant_timer();  
   
                         start_timer();  
                         dequant4_intra(&data[i * 64], &qcoeff[i * 64], iQuant, iDcScaler);  
                         stop_iquant_timer();  
101                  }                  }
102    
103    /* Performs Inverse DCT on all blocks */
104    static __inline void
105    MBiDCT(int16_t data[6 * 64],
106               const uint8_t cbp)
107    {
108                  start_timer();                  start_timer();
109                  idct(&data[i * 64]);          if(cbp & (1 << (5 - 0))) idct(&data[0 * 64]);
110            if(cbp & (1 << (5 - 1))) idct(&data[1 * 64]);
111            if(cbp & (1 << (5 - 2))) idct(&data[2 * 64]);
112            if(cbp & (1 << (5 - 3))) idct(&data[3 * 64]);
113            if(cbp & (1 << (5 - 4))) idct(&data[4 * 64]);
114            if(cbp & (1 << (5 - 5))) idct(&data[5 * 64]);
115                  stop_idct_timer();                  stop_idct_timer();
116          }          }
117    
118          if (pMB->field_dct) {  /* Quantize all blocks -- Intra mode */
119                  next_block = stride;  static __inline void
120                  stride *= 2;  MBQuantIntra(const MBParam * pParam,
121                             const FRAMEINFO * const frame,
122                             const MACROBLOCK * pMB,
123                             int16_t qcoeff[6 * 64],
124                             int16_t data[6*64])
125    {
126            int mpeg;
127            int scaler_lum, scaler_chr;
128    
129            quant_intraFuncPtr const quant[2] =
130                    {
131                            quant_h263_intra,
132                            quant_mpeg_intra
133                    };
134    
135            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
136            scaler_lum = get_dc_scaler(pMB->quant, 1);
137            scaler_chr = get_dc_scaler(pMB->quant, 0);
138    
139            /* Quantize the block */
140            start_timer();
141            quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
142            quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
143            quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
144            quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);
145            quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
146            quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);
147            stop_quant_timer();
148          }          }
149    
150          start_timer();  /* DeQuantize all blocks -- Intra mode */
151          transfer_16to8copy(pY_Cur, &data[0 * 64], stride);  static __inline void
152          transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);  MBDeQuantIntra(const MBParam * pParam,
153          transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);                             const int iQuant,
154          transfer_16to8copy(pY_Cur + next_block + 8, &data[3 * 64], stride);                             int16_t qcoeff[6 * 64],
155          transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);                             int16_t data[6*64])
156          transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);  {
157          stop_transfer_timer();          int mpeg;
158            int scaler_lum, scaler_chr;
159    
160            quant_intraFuncPtr const dequant[2] =
161                    {
162                            dequant_h263_intra,
163                            dequant_mpeg_intra
164                    };
165    
166            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
167            scaler_lum = get_dc_scaler(iQuant, 1);
168            scaler_chr = get_dc_scaler(iQuant, 0);
169    
170            start_timer();
171            dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
172            dequant[mpeg](&qcoeff[1 * 64], &data[1 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
173            dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
174            dequant[mpeg](&qcoeff[3 * 64], &data[3 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);
175            dequant[mpeg](&qcoeff[4 * 64], &data[4 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
176            dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
177            stop_iquant_timer();
178  }  }
179    
180    static int
181    dct_quantize_trellis_c(int16_t *const Out,
182                                               const int16_t *const In,
183                                               int Q,
184                                               const uint16_t * const Zigzag,
185                                               const uint16_t * const QuantMatrix,
186                                               int Non_Zero);
187    
188  uint8_t  /* Quantize all blocks -- Inter mode */
189  MBTransQuantInter(const MBParam * pParam,  static __inline uint8_t
190                                    FRAMEINFO * frame,  MBQuantInter(const MBParam * pParam,
191                                    MACROBLOCK * pMB,                           const FRAMEINFO * const frame,
192                                    const uint32_t x_pos,                           const MACROBLOCK * pMB,
                                   const uint32_t y_pos,  
193                                    int16_t data[6 * 64],                                    int16_t data[6 * 64],
194                                    int16_t qcoeff[6 * 64])                           int16_t qcoeff[6 * 64],
195                             int bvop,
196                             int limit)
197  {  {
198    
199          uint32_t stride = pParam->edged_width;          int i;
         uint32_t stride2 = stride / 2;  
         uint32_t next_block = stride * 8;  
         uint32_t i;  
         uint32_t iQuant = frame->quant;  
         uint8_t *pY_Cur, *pU_Cur, *pV_Cur;  
200          uint8_t cbp = 0;          uint8_t cbp = 0;
201          uint32_t sum;          int sum;
202          IMAGE *pCurrent = &frame->image;          int code_block, mpeg;
203    
204          pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);          quant_interFuncPtr const quant[2] =
205          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  {
206          pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);                          quant_h263_inter,
207                            quant_mpeg_inter
208                    };
209    
210          start_timer();          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
         pMB->field_dct = 0;  
         if ((frame->global_flags & XVID_INTERLACING) &&  
                 (x_pos>0) && (x_pos<pParam->mb_width-1) &&  
                 (y_pos>0) && (y_pos<pParam->mb_height-1)) {  
                 pMB->field_dct = MBDecideFieldDCT(data);  
         }  
         stop_interlacing_timer();  
211    
212          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
                 /*  
                  *  no need to transfer 8->16-bit  
                  * (this is performed already in motion compensation)  
                  */  
                 start_timer();  
                 fdct(&data[i * 64]);  
                 stop_dct_timer();  
213    
214                  if (pParam->m_quant_type == 0) {                  /* Quantize the block */
                         start_timer();  
                         sum = quant_inter(&qcoeff[i * 64], &data[i * 64], iQuant);  
                         stop_quant_timer();  
                 } else {  
215                          start_timer();                          start_timer();
                         sum = quant4_inter(&qcoeff[i * 64], &data[i * 64], iQuant);  
                         stop_quant_timer();  
                 }  
216    
217                  if ((sum >= TOOSMALL_LIMIT) || (qcoeff[i*64] != 0) ||                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);
                         (qcoeff[i*64+1] != 0) || (qcoeff[i*64+8] != 0)) {  
218    
219                          if (pParam->m_quant_type == H263_QUANT) {                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
220                                  start_timer();                          const uint16_t *matrix;
221                                  dequant_inter(&data[i * 64], &qcoeff[i * 64], iQuant);                          const static uint16_t h263matrix[] =
222                                  stop_iquant_timer();                                  {
223                          } else {                                          16, 16, 16, 16, 16, 16, 16, 16,
224                                  start_timer();                                          16, 16, 16, 16, 16, 16, 16, 16,
225                                  dequant4_inter(&data[i * 64], &qcoeff[i * 64], iQuant);                                          16, 16, 16, 16, 16, 16, 16, 16,
226                                  stop_iquant_timer();                                          16, 16, 16, 16, 16, 16, 16, 16,
227                                            16, 16, 16, 16, 16, 16, 16, 16,
228                                            16, 16, 16, 16, 16, 16, 16, 16,
229                                            16, 16, 16, 16, 16, 16, 16, 16,
230                                            16, 16, 16, 16, 16, 16, 16, 16
231                                    };
232    
233                            matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;
234                            sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],
235                                                                                     pMB->quant, &scan_tables[0][0],
236                                                                                     matrix,
237                                                                                     63);
238                          }                          }
239                    stop_quant_timer();
240    
241                          cbp |= 1 << (5 - i);                  /*
242                     * We code the block if the sum is higher than the limit and if the first
243                     * two AC coefficients in zig zag order are not zero.
244                     */
245                    code_block = 0;
246                    if ((sum >= limit) || (qcoeff[i*64+1] != 0) || (qcoeff[i*64+8] != 0)) {
247                            code_block = 1;
248                    } else {
249    
250                          start_timer();                          if (bvop && (pMB->mode == MODE_DIRECT || pMB->mode == MODE_DIRECT_NO4V)) {
251                          idct(&data[i * 64]);                                  /* dark blocks prevention for direct mode */
252                          stop_idct_timer();                                  if ((qcoeff[i*64] < -1) || (qcoeff[i*64] > 0))
253                                            code_block = 1;
254                            } else {
255                                    /* not direct mode */
256                                    if (qcoeff[i*64] != 0)
257                                            code_block = 1;
258                  }                  }
259          }          }
260    
261          if (pMB->field_dct) {                  /* Set the corresponding cbp bit */
262                  next_block = stride;                  cbp |= code_block << (5 - i);
                 stride *= 2;  
263          }          }
264    
265          start_timer();          return(cbp);
         if (cbp & 32)  
                 transfer_16to8add(pY_Cur, &data[0 * 64], stride);  
         if (cbp & 16)  
                 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);  
         if (cbp & 8)  
                 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);  
         if (cbp & 4)  
                 transfer_16to8add(pY_Cur + next_block + 8, &data[3 * 64], stride);  
         if (cbp & 2)  
                 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);  
         if (cbp & 1)  
                 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);  
         stop_transfer_timer();  
   
         return cbp;  
   
266  }  }
267    
268  void  /* DeQuantize all blocks -- Inter mode */
269  MBTransQuantIntra2(const MBParam * pParam,  static __inline void
270                                    FRAMEINFO * frame,  MBDeQuantInter(const MBParam * pParam,
271                                    MACROBLOCK * pMB,                             const int iQuant,
                                   const uint32_t x_pos,  
                                   const uint32_t y_pos,  
272                                    int16_t data[6 * 64],                                    int16_t data[6 * 64],
273                                    int16_t qcoeff[6 * 64])                             int16_t qcoeff[6 * 64],
274                               const uint8_t cbp)
275  {  {
276          MBTrans(pParam,frame,pMB,x_pos,y_pos,data);          int mpeg;
         MBfDCT(pParam,frame,pMB,data);  
         MBQuantIntra(pParam,frame,pMB,data,qcoeff);  
         MBDeQuantIntra(pParam,frame->quant,data,qcoeff);  
         MBiDCT(data,0x3F);  
         MBTransAdd(pParam,frame,pMB,x_pos,y_pos,data,0x3F);  
 }  
   
277    
278  uint8_t          quant_interFuncPtr const dequant[2] =
 MBTransQuantInter2(const MBParam * pParam,  
                                   FRAMEINFO * frame,  
                                   MACROBLOCK * pMB,  
                                   const uint32_t x_pos,  
                                   const uint32_t y_pos,  
                                   int16_t data[6 * 64],  
                                   int16_t qcoeff[6 * 64])  
279  {  {
280          uint8_t cbp;                          dequant_h263_inter,
281                            dequant_mpeg_inter
282                    };
283    
284            mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
285    
286  /* there is no MBTrans for Inter block, that's done in motion compensation already */          start_timer();
287            if(cbp & (1 << (5 - 0))) dequant[mpeg](&data[0 * 64], &qcoeff[0 * 64], iQuant, pParam->mpeg_quant_matrices);
288          MBfDCT(pParam,frame,pMB,data);          if(cbp & (1 << (5 - 1))) dequant[mpeg](&data[1 * 64], &qcoeff[1 * 64], iQuant, pParam->mpeg_quant_matrices);
289          cbp = MBQuantInter(pParam,frame->quant,data,qcoeff);          if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant, pParam->mpeg_quant_matrices);
290          MBDeQuantInter(pParam,frame->quant,data,qcoeff,cbp);          if(cbp & (1 << (5 - 3))) dequant[mpeg](&data[3 * 64], &qcoeff[3 * 64], iQuant, pParam->mpeg_quant_matrices);
291          MBiDCT(data,cbp);          if(cbp & (1 << (5 - 4))) dequant[mpeg](&data[4 * 64], &qcoeff[4 * 64], iQuant, pParam->mpeg_quant_matrices);
292          MBTransAdd(pParam,frame,pMB,x_pos,y_pos,data,cbp);          if(cbp & (1 << (5 - 5))) dequant[mpeg](&data[5 * 64], &qcoeff[5 * 64], iQuant, pParam->mpeg_quant_matrices);
293            stop_iquant_timer();
         return cbp;  
294  }  }
295    
296  uint8_t  typedef void (transfer_operation_8to16_t) (int16_t *Dst, const uint8_t *Src, int BpS);
297  MBTransQuantInterBVOP(const MBParam * pParam,  typedef void (transfer_operation_16to8_t) (uint8_t *Dst, const int16_t *Src, int BpS);
                                   FRAMEINFO * frame,  
                                   MACROBLOCK * pMB,  
                                   int16_t data[6 * 64],  
                                   int16_t qcoeff[6 * 64])  
 {  
         uint8_t cbp;  
   
 /* there is no MBTrans for Inter block, that's done in motion compensation already */  
298    
         MBfDCT(pParam,frame,pMB,data);  
         cbp = MBQuantInter(pParam,frame->quant,data,qcoeff);  
   
 /* we don't have to DeQuant, iDCT and Transfer back data for B-frames */  
   
         return cbp;  
 }  
299    
300    static __inline void
301  void  MBTrans8to16(const MBParam * const pParam,
302  MBfDCT(const MBParam * pParam,                           const FRAMEINFO * const frame,
303                                    FRAMEINFO * frame,                           const MACROBLOCK * const pMB,
304                                    MACROBLOCK * pMB,                           const uint32_t x_pos,
305                             const uint32_t y_pos,
306                                    int16_t data[6 * 64])                                    int16_t data[6 * 64])
307  {  {
308          int i;          uint32_t stride = pParam->edged_width;
309            uint32_t stride2 = stride / 2;
310          start_timer();          uint32_t next_block = stride * 8;
311          pMB->field_dct = 0;          int32_t cst;
312          if ((frame->global_flags & XVID_INTERLACING)) {          int vop_reduced;
313                  pMB->field_dct = MBDecideFieldDCT(data);          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
314            const IMAGE * const pCurrent = &frame->image;
315            transfer_operation_8to16_t * const functions[2] =
316                    {
317                            (transfer_operation_8to16_t *)transfer_8to16copy,
318                            (transfer_operation_8to16_t *)filter_18x18_to_8x8
319                    };
320            transfer_operation_8to16_t *transfer_op = NULL;
321    
322            vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);
323    
324            /* Image pointers */
325            pY_Cur = pCurrent->y + (y_pos << (4+vop_reduced)) * stride  + (x_pos << (4+vop_reduced));
326            pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));
327            pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));
328    
329            /* Block size */
330            cst = 8<<vop_reduced;
331    
332            /* Operation function */
333            transfer_op = functions[vop_reduced];
334    
335            /* Do the transfer */
336            start_timer();
337            transfer_op(&data[0 * 64], pY_Cur, stride);
338            transfer_op(&data[1 * 64], pY_Cur + cst, stride);
339            transfer_op(&data[2 * 64], pY_Cur + next_block, stride);
340            transfer_op(&data[3 * 64], pY_Cur + next_block + cst, stride);
341            transfer_op(&data[4 * 64], pU_Cur, stride2);
342            transfer_op(&data[5 * 64], pV_Cur, stride2);
343            stop_transfer_timer();
344          }          }
         stop_interlacing_timer();  
345    
346          for (i = 0; i < 6; i++) {  static __inline void
347                  start_timer();  MBTrans16to8(const MBParam * const pParam,
348                  fdct(&data[i * 64]);                           const FRAMEINFO * const frame,
349                  stop_dct_timer();                           const MACROBLOCK * const pMB,
350          }                           const uint32_t x_pos,
351  }                           const uint32_t y_pos,
352                             int16_t data[6 * 64],
353                             const uint32_t add, /* Must be 1 or 0 */
354                             const uint8_t cbp)
355    {
356            uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
357            uint32_t stride = pParam->edged_width;
358            uint32_t stride2 = stride / 2;
359            uint32_t next_block = stride * 8;
360            uint32_t cst;
361            int vop_reduced;
362            const IMAGE * const pCurrent = &frame->image;
363    
364  void          /* Array of function pointers, indexed by [vop_reduced<<1+add] */
365  MBQuantDeQuantIntra(const MBParam * pParam,          transfer_operation_16to8_t  * const functions[4] =
                                         FRAMEINFO * frame,  
                                         MACROBLOCK * pMB,  
                                         int16_t qcoeff[6 * 64],  
                                         int16_t data[6*64])  
366  {  {
367          int i;                          (transfer_operation_16to8_t*)transfer_16to8copy,
368          int iQuant = frame->quant;                          (transfer_operation_16to8_t*)transfer_16to8add,
369                            (transfer_operation_16to8_t*)copy_upsampled_8x8_16to8,
370                            (transfer_operation_16to8_t*)add_upsampled_8x8_16to8
371                    };
372    
373            transfer_operation_16to8_t *transfer_op = NULL;
374    
375            /* Makes this vars booleans */
376            vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);
377    
378            /* Image pointers */
379            pY_Cur = pCurrent->y + (y_pos << (4+vop_reduced)) * stride  + (x_pos << (4+vop_reduced));
380            pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));
381            pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));
382    
383          start_timer();          if (pMB->field_dct) {
384          pMB->field_dct = 0;                  next_block = stride;
385          if ((frame->global_flags & XVID_INTERLACING)) {                  stride *= 2;
                 pMB->field_dct = MBDecideFieldDCT(data);  
386          }          }
         stop_interlacing_timer();  
387    
388          for (i = 0; i < 6; i++) {          /* Block size */
389                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);          cst = 8<<vop_reduced;
390    
391                  if (pParam->m_quant_type == H263_QUANT) {          /* Operation function */
392                          start_timer();          transfer_op = functions[(vop_reduced<<1) + add];
                         quant_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);  
                         stop_quant_timer();  
393    
394            /* Do the operation */
395                          start_timer();                          start_timer();
396                          dequant_intra(&data[i * 64], &qcoeff[i * 64], iQuant, iDcScaler);          if (cbp&32) transfer_op(pY_Cur,                    &data[0 * 64], stride);
397                          stop_iquant_timer();          if (cbp&16) transfer_op(pY_Cur + cst,              &data[1 * 64], stride);
398                  } else {          if (cbp& 8) transfer_op(pY_Cur + next_block,       &data[2 * 64], stride);
399                          start_timer();          if (cbp& 4) transfer_op(pY_Cur + next_block + cst, &data[3 * 64], stride);
400                          quant4_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);          if (cbp& 2) transfer_op(pU_Cur,                    &data[4 * 64], stride2);
401                          stop_quant_timer();          if (cbp& 1) transfer_op(pV_Cur,                    &data[5 * 64], stride2);
402            stop_transfer_timer();
                         start_timer();  
                         dequant4_intra(&data[i * 64], &qcoeff[i * 64], iQuant, iDcScaler);  
                         stop_iquant_timer();  
                 }  
         }  
403  }  }
404    
405    /*****************************************************************************
406     * Module functions
407     ****************************************************************************/
408    
409  void  void
410  MBQuantIntra(const MBParam * pParam,  MBTransQuantIntra(const MBParam * const pParam,
411                           FRAMEINFO * frame,                                    const FRAMEINFO * const frame,
412                           MACROBLOCK *pMB,                                    MACROBLOCK * const pMB,
413                       int16_t qcoeff[6 * 64],                                    const uint32_t x_pos,
414                           int16_t data[6*64])                                    const uint32_t y_pos,
415                                      int16_t data[6 * 64],
416                                      int16_t qcoeff[6 * 64])
417  {  {
         int i;  
         int iQuant = frame->quant;  
418    
419          start_timer();          /* Transfer data */
420          pMB->field_dct = 0;          MBTrans8to16(pParam, frame, pMB, x_pos, y_pos, data);
         if ((frame->global_flags & XVID_INTERLACING)) {  
                 pMB->field_dct = MBDecideFieldDCT(data);  
         }  
         stop_interlacing_timer();  
421    
422          for (i = 0; i < 6; i++) {          /* Perform DCT (and field decision) */
423                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
424    
425                  if (pParam->m_quant_type == H263_QUANT) {          /* Quantize the block */
426                          start_timer();          MBQuantIntra(pParam, frame, pMB, data, qcoeff);
                         quant_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);  
                         stop_quant_timer();  
                 } else {  
                         start_timer();  
                         quant4_intra(&qcoeff[i * 64], &data[i * 64], iQuant, iDcScaler);  
                         stop_quant_timer();  
                 }  
         }  
 }  
427    
428  void          /* DeQuantize the block */
429  MBDeQuantIntra(const MBParam * pParam,          MBDeQuantIntra(pParam, pMB->quant, data, qcoeff);
                            const int iQuant,  
                                   int16_t qcoeff[6 * 64],  
                                   int16_t data[6*64])  
 {  
         int i;  
430    
431          for (i = 0; i < 6; i++) {          /* Perform inverse DCT*/
432                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);          MBiDCT(data, 0x3F);
433    
434                  if (pParam->m_quant_type == H263_QUANT) {          /* Transfer back the data -- Don't add data */
435                          start_timer();          MBTrans16to8(pParam, frame, pMB, x_pos, y_pos, data, 0, 0x3F);
                         dequant_intra(&data[i * 64], &qcoeff[i * 64], iQuant, iDcScaler);  
                         stop_iquant_timer();  
                 } else {  
                         start_timer();  
                         dequant4_intra(&data[i * 64], &qcoeff[i * 64], iQuant, iDcScaler);  
                         stop_iquant_timer();  
                 }  
         }  
436  }  }
437    
438    
439  uint8_t  uint8_t
440  MBQuantInter(const MBParam * pParam,  MBTransQuantInter(const MBParam * const pParam,
441                           const int iQuant,                                    const FRAMEINFO * const frame,
442                                      MACROBLOCK * const pMB,
443                                      const uint32_t x_pos,
444                                      const uint32_t y_pos,
445                                    int16_t data[6 * 64],                                    int16_t data[6 * 64],
446                                    int16_t qcoeff[6 * 64])                                    int16_t qcoeff[6 * 64])
447  {  {
448            uint8_t cbp;
449            uint32_t limit;
450    
451          int i;          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
452          uint8_t cbp = 0;           * already */
         int sum;  
453    
454          for (i = 0; i < 6; i++) {          /* Perform DCT (and field decision) */
455            MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
456    
457                  if (pParam->m_quant_type == 0) {          /* Set the limit threshold */
458                          start_timer();          limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);
                         sum = quant_inter(&qcoeff[i * 64], &data[i * 64], iQuant);  
                         stop_quant_timer();  
                 } else {  
                         start_timer();  
                         sum = quant4_inter(&qcoeff[i * 64], &data[i * 64], iQuant);  
                         stop_quant_timer();  
                 }  
459    
460                  if (sum >= TOOSMALL_LIMIT) {    // skip block ?          if (frame->vop_flags & XVID_VOP_CARTOON)
461                          cbp |= 1 << (5 - i);                  limit *= 3;
                 }  
         }  
         return cbp;  
 }  
462    
463  void          /* Quantize the block */
464  MBDeQuantInter( const MBParam * pParam,          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 0, limit);
                                 const int iQuant,  
                                   int16_t data[6 * 64],  
                                   int16_t qcoeff[6 * 64],  
                                   const uint8_t cbp)  
 {  
         int i;  
465    
466          for (i = 0; i < 6; i++) {          /* DeQuantize the block */
467                  if (cbp & (1 << (5 - i)))          MBDeQuantInter(pParam, pMB->quant, data, qcoeff, cbp);
                 {  
                         if (pParam->m_quant_type == H263_QUANT) {  
                                 start_timer();  
                                 dequant_inter(&data[i * 64], &qcoeff[i * 64], iQuant);  
                                 stop_iquant_timer();  
                         } else {  
                                 start_timer();  
                                 dequant4_inter(&data[i * 64], &qcoeff[i * 64], iQuant);  
                                 stop_iquant_timer();  
                         }  
                 }  
         }  
 }  
468    
469  void          /* Perform inverse DCT*/
470  MBiDCT( int16_t data[6 * 64],          MBiDCT(data, cbp);
                 const uint8_t cbp)  
 {  
         int i;  
471    
472          for (i = 0; i < 6; i++) {          /* Transfer back the data -- Add the data */
473                  if (cbp & (1 << (5 - i)))          MBTrans16to8(pParam, frame, pMB, x_pos, y_pos, data, 1, cbp);
                 {  
                         start_timer();  
                         idct(&data[i * 64]);  
                         stop_idct_timer();  
474    
475            return(cbp);
476                  }                  }
         }  
 }  
   
477    
478  void  uint8_t
479  MBTrans(const MBParam * pParam,  MBTransQuantInterBVOP(const MBParam * pParam,
480                                    FRAMEINFO * frame,                                    FRAMEINFO * frame,
481                                    MACROBLOCK * pMB,                                    MACROBLOCK * pMB,
482                                    const uint32_t x_pos,                                    const uint32_t x_pos,
483                                    const uint32_t y_pos,                                    const uint32_t y_pos,
484                                    int16_t data[6 * 64])                                            int16_t data[6 * 64],
485                                              int16_t qcoeff[6 * 64])
486  {  {
487          uint32_t stride = pParam->edged_width;          uint8_t cbp;
488          uint32_t stride2 = stride / 2;          uint32_t limit;
         uint32_t next_block = stride * 8;  
         uint8_t *pY_Cur, *pU_Cur, *pV_Cur;  
         IMAGE *pCurrent = &frame->image;  
489    
490          pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);          /* There is no MBTrans8to16 for Inter block, that's done in motion compensation
491          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);           * already */
         pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);  
492    
493          start_timer();          /* Perform DCT (and field decision) */
494          transfer_8to16copy(&data[0 * 64], pY_Cur, stride);          MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);
         transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);  
         transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);  
         transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);  
         transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);  
         transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);  
         stop_transfer_timer();  
 }  
495    
496  void          /* Set the limit threshold */
497  MBTransAdd(const MBParam * pParam,          limit = BVOP_TOOSMALL_LIMIT;
                                   FRAMEINFO * frame,  
                                   MACROBLOCK * pMB,  
                                   const uint32_t x_pos,  
                                   const uint32_t y_pos,  
                                   int16_t data[6 * 64],  
                                   const uint8_t cbp)  
 {  
         uint8_t *pY_Cur, *pU_Cur, *pV_Cur;  
         uint32_t stride = pParam->edged_width;  
         uint32_t stride2 = stride / 2;  
         uint32_t next_block = stride * 8;  
         IMAGE *pCurrent = &frame->image;  
498    
499          pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);          if (frame->vop_flags & XVID_VOP_CARTOON)
500          pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);                  limit *= 2;
         pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);  
501    
502          if (pMB->field_dct) {          /* Quantize the block */
503                  next_block = stride;          cbp = MBQuantInter(pParam, frame, pMB, data, qcoeff, 1, limit);
                 stride *= 2;  
         }  
504    
505          start_timer();          /*
506          if (cbp & 32)           * History comment:
507                  transfer_16to8add(pY_Cur, &data[0 * 64], stride);           * We don't have to DeQuant, iDCT and Transfer back data for B-frames.
508          if (cbp & 16)           *
509                  transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);           * BUT some plugins require the rebuilt original frame to be passed so we
510          if (cbp & 8)           * have to take care of that here
511                  transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);           */
512          if (cbp & 4)          if((pParam->plugin_flags & XVID_REQORIGINAL)) {
                 transfer_16to8add(pY_Cur + next_block + 8, &data[3 * 64], stride);  
         if (cbp & 2)  
                 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);  
         if (cbp & 1)  
                 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);  
         stop_transfer_timer();  
 }  
513    
514                    /* DeQuantize the block */
515                    MBDeQuantInter(pParam, pMB->quant, data, qcoeff, cbp);
516    
517                    /* Perform inverse DCT*/
518                    MBiDCT(data, cbp);
519    
520  /* if sum(diff between field lines) < sum(diff between frame lines), use field dct */                  /* Transfer back the data -- Add the data */
521                    MBTrans16to8(pParam, frame, pMB, x_pos, y_pos, data, 1, cbp);
522            }
523    
524            return(cbp);
525    }
526    
527    /* if sum(diff between field lines) < sum(diff between frame lines), use field dct */
528  uint32_t  uint32_t
529  MBDecideFieldDCT(int16_t data[6 * 64])  MBFieldTest_c(int16_t data[6 * 64])
530  {  {
   
531          const uint8_t blocks[] =          const uint8_t blocks[] =
532                  { 0 * 64, 0 * 64, 0 * 64, 0 * 64, 2 * 64, 2 * 64, 2 * 64, 2 * 64 };                  { 0 * 64, 0 * 64, 0 * 64, 0 * 64, 2 * 64, 2 * 64, 2 * 64, 2 * 64 };
533          const uint8_t lines[] = { 0, 16, 32, 48, 0, 16, 32, 48 };          const uint8_t lines[] = { 0, 16, 32, 48, 0, 16, 32, 48 };
# Line 575  Line 538 
538          for (i = 0; i < 7; ++i) {          for (i = 0; i < 7; ++i) {
539                  for (j = 0; j < 8; ++j) {                  for (j = 0; j < 8; ++j) {
540                          frame +=                          frame +=
541                                  ABS(data[0 * 64 + (i + 1) * 8 + j] - data[0 * 64 + i * 8 + j]);                                  abs(data[0 * 64 + (i + 1) * 8 + j] - data[0 * 64 + i * 8 + j]);
542                          frame +=                          frame +=
543                                  ABS(data[1 * 64 + (i + 1) * 8 + j] - data[1 * 64 + i * 8 + j]);                                  abs(data[1 * 64 + (i + 1) * 8 + j] - data[1 * 64 + i * 8 + j]);
544                          frame +=                          frame +=
545                                  ABS(data[2 * 64 + (i + 1) * 8 + j] - data[2 * 64 + i * 8 + j]);                                  abs(data[2 * 64 + (i + 1) * 8 + j] - data[2 * 64 + i * 8 + j]);
546                          frame +=                          frame +=
547                                  ABS(data[3 * 64 + (i + 1) * 8 + j] - data[3 * 64 + i * 8 + j]);                                  abs(data[3 * 64 + (i + 1) * 8 + j] - data[3 * 64 + i * 8 + j]);
548    
549                          field +=                          field +=
550                                  ABS(data[blocks[i + 1] + lines[i + 1] + j] -                                  abs(data[blocks[i + 1] + lines[i + 1] + j] -
551                                          data[blocks[i] + lines[i] + j]);                                          data[blocks[i] + lines[i] + j]);
552                          field +=                          field +=
553                                  ABS(data[blocks[i + 1] + lines[i + 1] + 8 + j] -                                  abs(data[blocks[i + 1] + lines[i + 1] + 8 + j] -
554                                          data[blocks[i] + lines[i] + 8 + j]);                                          data[blocks[i] + lines[i] + 8 + j]);
555                          field +=                          field +=
556                                  ABS(data[blocks[i + 1] + 64 + lines[i + 1] + j] -                                  abs(data[blocks[i + 1] + 64 + lines[i + 1] + j] -
557                                          data[blocks[i] + 64 + lines[i] + j]);                                          data[blocks[i] + 64 + lines[i] + j]);
558                          field +=                          field +=
559                                  ABS(data[blocks[i + 1] + 64 + lines[i + 1] + 8 + j] -                                  abs(data[blocks[i + 1] + 64 + lines[i + 1] + 8 + j] -
560                                          data[blocks[i] + 64 + lines[i] + 8 + j]);                                          data[blocks[i] + 64 + lines[i] + 8 + j]);
561                  }                  }
562          }          }
563    
564          if (frame > field) {          return (frame >= (field + 350));
                 MBFrameToField(data);  
         }  
   
         return (frame > field);  
565  }  }
566    
567    
# Line 618  Line 577 
577    
578          /* left blocks */          /* left blocks */
579    
580          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
581          MOVLINE(tmp, LINE(0, 1));          MOVLINE(tmp, LINE(0, 1));
582          MOVLINE(LINE(0, 1), LINE(0, 2));          MOVLINE(LINE(0, 1), LINE(0, 2));
583          MOVLINE(LINE(0, 2), LINE(0, 4));          MOVLINE(LINE(0, 2), LINE(0, 4));
584          MOVLINE(LINE(0, 4), LINE(2, 0));          MOVLINE(LINE(0, 4), LINE(2, 0));
585          MOVLINE(LINE(2, 0), tmp);          MOVLINE(LINE(2, 0), tmp);
586    
587          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
588          MOVLINE(tmp, LINE(0, 3));          MOVLINE(tmp, LINE(0, 3));
589          MOVLINE(LINE(0, 3), LINE(0, 6));          MOVLINE(LINE(0, 3), LINE(0, 6));
590          MOVLINE(LINE(0, 6), LINE(2, 4));          MOVLINE(LINE(0, 6), LINE(2, 4));
591          MOVLINE(LINE(2, 4), LINE(2, 1));          MOVLINE(LINE(2, 4), LINE(2, 1));
592          MOVLINE(LINE(2, 1), tmp);          MOVLINE(LINE(2, 1), tmp);
593    
594          // 5=10, 10=5          /* 5=10, 10=5 */
595          MOVLINE(tmp, LINE(0, 5));          MOVLINE(tmp, LINE(0, 5));
596          MOVLINE(LINE(0, 5), LINE(2, 2));          MOVLINE(LINE(0, 5), LINE(2, 2));
597          MOVLINE(LINE(2, 2), tmp);          MOVLINE(LINE(2, 2), tmp);
598    
599          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
600          MOVLINE(tmp, LINE(0, 7));          MOVLINE(tmp, LINE(0, 7));
601          MOVLINE(LINE(0, 7), LINE(2, 6));          MOVLINE(LINE(0, 7), LINE(2, 6));
602          MOVLINE(LINE(2, 6), LINE(2, 5));          MOVLINE(LINE(2, 6), LINE(2, 5));
# Line 646  Line 605 
605    
606          /* right blocks */          /* right blocks */
607    
608          // 1=2, 2=4, 4=8, 8=1          /* 1=2, 2=4, 4=8, 8=1 */
609          MOVLINE(tmp, LINE(1, 1));          MOVLINE(tmp, LINE(1, 1));
610          MOVLINE(LINE(1, 1), LINE(1, 2));          MOVLINE(LINE(1, 1), LINE(1, 2));
611          MOVLINE(LINE(1, 2), LINE(1, 4));          MOVLINE(LINE(1, 2), LINE(1, 4));
612          MOVLINE(LINE(1, 4), LINE(3, 0));          MOVLINE(LINE(1, 4), LINE(3, 0));
613          MOVLINE(LINE(3, 0), tmp);          MOVLINE(LINE(3, 0), tmp);
614    
615          // 3=6, 6=12, 12=9, 9=3          /* 3=6, 6=12, 12=9, 9=3 */
616          MOVLINE(tmp, LINE(1, 3));          MOVLINE(tmp, LINE(1, 3));
617          MOVLINE(LINE(1, 3), LINE(1, 6));          MOVLINE(LINE(1, 3), LINE(1, 6));
618          MOVLINE(LINE(1, 6), LINE(3, 4));          MOVLINE(LINE(1, 6), LINE(3, 4));
619          MOVLINE(LINE(3, 4), LINE(3, 1));          MOVLINE(LINE(3, 4), LINE(3, 1));
620          MOVLINE(LINE(3, 1), tmp);          MOVLINE(LINE(3, 1), tmp);
621    
622          // 5=10, 10=5          /* 5=10, 10=5 */
623          MOVLINE(tmp, LINE(1, 5));          MOVLINE(tmp, LINE(1, 5));
624          MOVLINE(LINE(1, 5), LINE(3, 2));          MOVLINE(LINE(1, 5), LINE(3, 2));
625          MOVLINE(LINE(3, 2), tmp);          MOVLINE(LINE(3, 2), tmp);
626    
627          // 7=14, 14=13, 13=11, 11=7          /* 7=14, 14=13, 13=11, 11=7 */
628          MOVLINE(tmp, LINE(1, 7));          MOVLINE(tmp, LINE(1, 7));
629          MOVLINE(LINE(1, 7), LINE(3, 6));          MOVLINE(LINE(1, 7), LINE(3, 6));
630          MOVLINE(LINE(3, 6), LINE(3, 5));          MOVLINE(LINE(3, 6), LINE(3, 5));
631          MOVLINE(LINE(3, 5), LINE(3, 3));          MOVLINE(LINE(3, 5), LINE(3, 3));
632          MOVLINE(LINE(3, 3), tmp);          MOVLINE(LINE(3, 3), tmp);
633  }  }
634    
635    /*****************************************************************************
636     *               Trellis based R-D optimal quantization
637     *
638     *   Trellis Quant code (C) 2003 Pascal Massimino skal(at)planet-d.net
639     *
640     ****************************************************************************/
641    
642    /*----------------------------------------------------------------------------
643     *
644     *        Trellis-Based quantization
645     *
646     * So far I understand this paper:
647     *
648     *  "Trellis-Based R-D Optimal Quantization in H.263+"
649     *    J.Wen, M.Luttrell, J.Villasenor
650     *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
651     *
652     * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
653     * Source Shortest Path algo. But due to the underlying graph structure
654     * ("Trellis"), it can be turned into a dynamic programming algo,
655     * partially saving the explicit graph's nodes representation. And
656     * without using a heap, since the open frontier of the DAG is always
657     * known, and of fixed size.
658     *--------------------------------------------------------------------------*/
659    
660    
661    
662    /* Codes lengths for relevant levels. */
663    
664    /* let's factorize: */
665    static const uint8_t Code_Len0[64] = {
666            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
667            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
668    static const uint8_t Code_Len1[64] = {
669            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,30,
670            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
671    static const uint8_t Code_Len2[64] = {
672            19,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
673            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
674    static const uint8_t Code_Len3[64] = {
675            18,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
676            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
677    static const uint8_t Code_Len4[64] = {
678            17,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
679            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
680    static const uint8_t Code_Len5[64] = {
681            16,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
682            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
683    static const uint8_t Code_Len6[64] = {
684            15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
685            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
686    static const uint8_t Code_Len7[64] = {
687            13,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
688            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
689    static const uint8_t Code_Len8[64] = {
690            11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
691            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
692    static const uint8_t Code_Len9[64] = {
693            12,21,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
694            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
695    static const uint8_t Code_Len10[64] = {
696            12,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,
697            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
698    static const uint8_t Code_Len11[64] = {
699            12,19,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
700            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
701    static const uint8_t Code_Len12[64] = {
702            11,17,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
703            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
704    static const uint8_t Code_Len13[64] = {
705            11,15,21,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
706            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
707    static const uint8_t Code_Len14[64] = {
708            10,12,19,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
709            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
710    static const uint8_t Code_Len15[64] = {
711            10,13,17,19,21,21,21,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
712            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
713    static const uint8_t Code_Len16[64] = {
714            9,12,13,18,18,19,19,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
715            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};
716    static const uint8_t Code_Len17[64] = {
717            8,11,13,14,14,14,15,19,19,19,21,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
718            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
719    static const uint8_t Code_Len18[64] = {
720            7, 9,11,11,13,13,13,15,15,15,16,22,22,22,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
721            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
722    static const uint8_t Code_Len19[64] = {
723            5, 7, 9,10,10,11,11,11,11,11,13,14,16,17,17,18,18,18,18,18,18,18,18,20,20,21,21,30,30,30,30,30,
724            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30 };
725    static const uint8_t Code_Len20[64] = {
726            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,
727            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 };
728    
729    /* a few more table for LAST table: */
730    static const uint8_t Code_Len21[64] = {
731            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,
732            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};
733    static const uint8_t Code_Len22[64] = {
734            12,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
735            30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};
736    static const uint8_t Code_Len23[64] = {
737            10,12,15,15,15,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,20,20,20,
738            20,21,21,21,21,21,21,21,21,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};
739    static const uint8_t Code_Len24[64] = {
740            5, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11,11,11,12,12,12,
741            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};
742    
743    
744    static const uint8_t * const B16_17_Code_Len[24] = { /* levels [1..24] */
745            Code_Len20,Code_Len19,Code_Len18,Code_Len17,
746            Code_Len16,Code_Len15,Code_Len14,Code_Len13,
747            Code_Len12,Code_Len11,Code_Len10,Code_Len9,
748            Code_Len8, Code_Len7 ,Code_Len6 ,Code_Len5,
749            Code_Len4, Code_Len3, Code_Len3 ,Code_Len2,
750            Code_Len2, Code_Len1, Code_Len1, Code_Len1,
751    };
752    
753    static const uint8_t * const B16_17_Code_Len_Last[6] = { /* levels [1..6] */
754            Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
755    };
756    
757    /* TL_SHIFT controls the precision of the RD optimizations in trellis
758     * valid range is [10..16]. The bigger, the more trellis is vulnerable
759     * to overflows in cost formulas.
760     *  - 10 allows ac values up to 2^11 == 2048
761     *  - 16 allows ac values up to 2^8 == 256
762     */
763    #define TL_SHIFT 11
764    #define TL(q) ((0xfe00>>(16-TL_SHIFT))/(q*q))
765    
766    static const int Trellis_Lambda_Tabs[31] = {
767            TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),
768            TL( 8),TL( 9),TL(10),TL(11),TL(12),TL(13),TL(14), TL(15),
769            TL(16),TL(17),TL(18),TL(19),TL(20),TL(21),TL(22), TL(23),
770            TL(24),TL(25),TL(26),TL(27),TL(28),TL(29),TL(30), TL(31)
771    };
772    #undef TL
773    
774    static int __inline
775    Find_Last(const int16_t *C, const uint16_t *Zigzag, int i)
776    {
777            while(i>=0)
778                    if (C[Zigzag[i]])
779                            return i;
780                    else i--;
781            return -1;
782    }
783    
784    static int __inline
785    Compute_Sum(const int16_t *C, int last)
786    {
787            int sum = 0;
788    
789            while(last--)
790                    sum += abs(C[last]);
791    
792            return(sum);
793    }
794    
795    /* this routine has been strippen of all debug code */
796    static int
797    dct_quantize_trellis_c(int16_t *const Out,
798                                               const int16_t *const In,
799                                               int Q,
800                                               const uint16_t * const Zigzag,
801                                               const uint16_t * const QuantMatrix,
802                                               int Non_Zero)
803    {
804    
805            /* Note: We should search last non-zero coeffs on *real* DCT input coeffs
806             * (In[]), not quantized one (Out[]). However, it only improves the result
807             * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
808             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
809             * helps. */
810            typedef struct { int16_t Run, Level; } NODE;
811    
812            NODE Nodes[65], Last;
813            uint32_t Run_Costs0[64+1];
814            uint32_t * const Run_Costs = Run_Costs0 + 1;
815    
816            /* it's 1/lambda, actually */
817            const int Lambda = Trellis_Lambda_Tabs[Q-1];
818    
819            int Run_Start = -1;
820            uint32_t Min_Cost = 2<<TL_SHIFT;
821    
822            int Last_Node = -1;
823            uint32_t Last_Cost = 0;
824    
825            int i, j, sum;
826    
827            /* source (w/ CBP penalty) */
828            Run_Costs[-1] = 2<<TL_SHIFT;
829    
830            Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
831            if (Non_Zero<0)
832                    return 0; /* Sum is zero if there are only zero coeffs */
833    
834            for(i=0; i<=Non_Zero; i++) {
835                    const int q = ((Q*QuantMatrix[Zigzag[i]])>>4);
836                    const int Mult = 2*q;
837                    const int Bias = (q-1) | 1;
838                    const int Lev0 = Mult + Bias;
839    
840                    const int AC = In[Zigzag[i]];
841                    const int Level1 = Out[Zigzag[i]];
842                    const unsigned int Dist0 = Lambda* AC*AC;
843                    uint32_t Best_Cost = 0xf0000000;
844                    Last_Cost += Dist0;
845    
846                    /* very specialized loop for -1,0,+1 */
847                    if ((uint32_t)(Level1+1)<3) {
848                            int dQ;
849                            int Run;
850                            uint32_t Cost0;
851    
852                            if (AC<0) {
853                                    Nodes[i].Level = -1;
854                                    dQ = Lev0 + AC;
855                            } else {
856                                    Nodes[i].Level = 1;
857                                    dQ = Lev0 - AC;
858                            }
859                            Cost0 = Lambda*dQ*dQ;
860    
861                            Nodes[i].Run = 1;
862                            Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
863                            for(Run=i-Run_Start; Run>0; --Run) {
864                                    const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
865                                    const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
866                                    const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
867    
868                                    /* TODO: what about tie-breaks? Should we favor short runs or
869                                     * long runs? Although the error is the same, it would not be
870                                     * spread the same way along high and low frequencies... */
871    
872                                    /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
873    
874                                    if (Cost<Best_Cost) {
875                                            Best_Cost        = Cost;
876                                            Nodes[i].Run = Run;
877                                    }
878    
879                                    if (lCost<Last_Cost) {
880                                            Last_Cost  = lCost;
881                                            Last.Run   = Run;
882                                            Last_Node  = i;
883                                    }
884                            }
885                            if (Last_Node==i)
886                                    Last.Level = Nodes[i].Level;
887                    } else if (51U>(uint32_t)(Level1+25)) {
888                            /* "big" levels (not less than ESC3, though) */
889                            const uint8_t *Tbl_L1, *Tbl_L2, *Tbl_L1_Last, *Tbl_L2_Last;
890                            int Level2;
891                            int dQ1, dQ2;
892                            int Run;
893                            uint32_t Dist1,Dist2;
894                            int dDist21;
895    
896                            if (Level1>1) {
897                                    dQ1 = Level1*Mult-AC + Bias;
898                                    dQ2 = dQ1 - Mult;
899                                    Level2 = Level1-1;
900                                    Tbl_L1          = (Level1<=24) ? B16_17_Code_Len[Level1-1]         : Code_Len0;
901                                    Tbl_L2          = (Level2<=24) ? B16_17_Code_Len[Level2-1]         : Code_Len0;
902                                    Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;
903                                    Tbl_L2_Last = (Level2<=6) ? B16_17_Code_Len_Last[Level2-1] : Code_Len0;
904                            } else { /* Level1<-1 */
905                                    dQ1 = Level1*Mult-AC - Bias;
906                                    dQ2 = dQ1 + Mult;
907                                    Level2 = Level1 + 1;
908                                    Tbl_L1          = (Level1>=-24) ? B16_17_Code_Len[Level1^-1]      : Code_Len0;
909                                    Tbl_L2          = (Level2>=-24) ? B16_17_Code_Len[Level2^-1]      : Code_Len0;
910                                    Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;
911                                    Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;
912                            }
913    
914                            Dist1 = Lambda*dQ1*dQ1;
915                            Dist2 = Lambda*dQ2*dQ2;
916                            dDist21 = Dist2-Dist1;
917    
918                            for(Run=i-Run_Start; Run>0; --Run)
919                            {
920                                    const uint32_t Cost_Base = Dist1 + Run_Costs[i-Run];
921                                    uint32_t Cost1, Cost2;
922                                    int bLevel;
923    
924                                    /* for sub-optimal (but slightly worth it, speed-wise) search,
925                                     * uncomment the following:
926                                     *              if (Cost_Base>=Best_Cost) continue;
927                                     * (? doesn't seem to have any effect -- gruel ) */
928    
929                                    Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
930                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
931    
932                                    if (Cost2<Cost1) {
933                                            Cost1 = Cost2;
934                                            bLevel = Level2;
935                                    } else {
936                                            bLevel = Level1;
937                                    }
938    
939                                    if (Cost1<Best_Cost) {
940                                            Best_Cost = Cost1;
941                                            Nodes[i].Run   = Run;
942                                            Nodes[i].Level = bLevel;
943                                    }
944    
945                                    Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
946                                    Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
947    
948                                    if (Cost2<Cost1) {
949                                            Cost1 = Cost2;
950                                            bLevel = Level2;
951                                    } else {
952                                            bLevel = Level1;
953                                    }
954    
955                                    if (Cost1<Last_Cost) {
956                                            Last_Cost  = Cost1;
957                                            Last.Run   = Run;
958                                            Last.Level = bLevel;
959                                            Last_Node  = i;
960                                    }
961                            } /* end of "for Run" */
962                    } else {
963                            /* Very very high levels, with no chance of being optimizable
964                             * => Simply pick best Run. */
965                            int Run;
966                            for(Run=i-Run_Start; Run>0; --Run) {
967                                    /* 30 bits + no distortion */
968                                    const uint32_t Cost = (30<<TL_SHIFT) + Run_Costs[i-Run];
969                                    if (Cost<Best_Cost) {
970                                            Best_Cost = Cost;
971                                            Nodes[i].Run   = Run;
972                                            Nodes[i].Level = Level1;
973                                    }
974    
975                                    if (Cost<Last_Cost) {
976                                            Last_Cost  = Cost;
977                                            Last.Run   = Run;
978                                            Last.Level = Level1;
979                                            Last_Node  = i;
980                                    }
981                            }
982                    }
983    
984    
985                    Run_Costs[i] = Best_Cost;
986    
987                    if (Best_Cost < Min_Cost + Dist0) {
988                            Min_Cost = Best_Cost;
989                            Run_Start = i;
990                    } else {
991                            /* as noticed by Michael Niedermayer (michaelni at gmx.at),
992                             * there's a code shorter by 1 bit for a larger run (!), same
993                             * level. We give it a chance by not moving the left barrier too
994                             * much. */
995                            while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
996                                    Run_Start++;
997    
998                            /* spread on preceding coeffs the cost incurred by skipping this
999                             * one */
1000                            for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1001                            Min_Cost += Dist0;
1002                    }
1003            }
1004    
1005            /* It seems trellis doesn't give good results... just compute the Out sum
1006             * and quit */
1007            if (Last_Node<0)
1008                    return Compute_Sum(Out, Non_Zero);
1009    
1010            /* reconstruct optimal sequence backward with surviving paths */
1011            memset(Out, 0x00, 64*sizeof(*Out));
1012            Out[Zigzag[Last_Node]] = Last.Level;
1013            i = Last_Node - Last.Run;
1014            sum = 0;
1015            while(i>=0) {
1016                    Out[Zigzag[i]] = Nodes[i].Level;
1017                    sum += abs(Nodes[i].Level);
1018                    i -= Nodes[i].Run;
1019            }
1020    
1021            return sum;
1022    }
1023    
1024    /* original version including heavy debugging info */
1025    
1026    #ifdef DBGTRELL
1027    
1028    #define DBG 0
1029    
1030    static __inline uint32_t Evaluate_Cost(const int16_t *C, int Mult, int Bias,
1031                                                                               const uint16_t * Zigzag, int Max, int Lambda)
1032    {
1033    #if (DBG>0)
1034            const int16_t * const Ref = C + 6*64;
1035            int Last = Max;
1036            int Bits = 0;
1037            int Dist = 0;
1038            int i;
1039            uint32_t Cost;
1040    
1041            while(Last>=0 && C[Zigzag[Last]]==0)
1042                    Last--;
1043    
1044            if (Last>=0) {
1045                    int j=0, j0=0;
1046                    int Run, Level;
1047    
1048                    Bits = 2;   /* CBP */
1049                    while(j<Last) {
1050                            while(!C[Zigzag[j]])
1051                                    j++;
1052                            if (j==Last)
1053                                    break;
1054                            Level=C[Zigzag[j]];
1055                            Run = j - j0;
1056                            j0 = ++j;
1057                            if (Level>=-24 && Level<=24)
1058                                    Bits += B16_17_Code_Len[(Level<0) ? -Level-1 : Level-1][Run];
1059                            else
1060                                    Bits += 30;
1061                    }
1062                    Level = C[Zigzag[Last]];
1063                    Run = j - j0;
1064                    if (Level>=-6 && Level<=6)
1065                            Bits += B16_17_Code_Len_Last[(Level<0) ? -Level-1 : Level-1][Run];
1066                    else
1067                            Bits += 30;
1068            }
1069    
1070            for(i=0; i<=Last; ++i) {
1071                    int V = C[Zigzag[i]]*Mult;
1072                    if (V>0)
1073                            V += Bias;
1074                    else
1075                            if (V<0)
1076                                    V -= Bias;
1077                    V -= Ref[Zigzag[i]];
1078                    Dist += V*V;
1079            }
1080            Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1081            if (DBG==1)
1082                    printf( " Last:%2d/%2d Cost = [(Bits=%5.0d) + Lambda*(Dist=%6.0d) = %d ] >>12= %d ", Last,Max, Bits, Dist, Cost, Cost>>12 );
1083            return Cost;
1084    
1085    #else
1086            return 0;
1087    #endif
1088    }
1089    
1090    
1091    static int
1092    dct_quantize_trellis_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)
1093    {
1094    
1095        /*
1096             * Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),
1097             * not quantized one (Out[]). However, it only improves the result *very*
1098             * slightly (~0.01dB), whereas speed drops to crawling level :)
1099             * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.
1100             */
1101            typedef struct { int16_t Run, Level; } NODE;
1102    
1103            NODE Nodes[65], Last;
1104            uint32_t Run_Costs0[64+1];
1105            uint32_t * const Run_Costs = Run_Costs0 + 1;
1106            const int Mult = 2*Q;
1107            const int Bias = (Q-1) | 1;
1108            const int Lev0 = Mult + Bias;
1109            const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */
1110    
1111            int Run_Start = -1;
1112            Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1113            uint32_t Min_Cost = 2<<TL_SHIFT;
1114    
1115            int Last_Node = -1;
1116            uint32_t Last_Cost = 0;
1117    
1118            int i, j;
1119    
1120    #if (DBG>0)
1121            Last.Level = 0; Last.Run = -1; /* just initialize to smthg */
1122    #endif
1123    
1124            Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
1125            if (Non_Zero<0)
1126                    return -1;
1127    
1128            for(i=0; i<=Non_Zero; i++)
1129            {
1130                    const int AC = In[Zigzag[i]];
1131                    const int Level1 = Out[Zigzag[i]];
1132                    const int Dist0 = Lambda* AC*AC;
1133                    uint32_t Best_Cost = 0xf0000000;
1134                    Last_Cost += Dist0;
1135    
1136                    if ((uint32_t)(Level1+1)<3)                 /* very specialized loop for -1,0,+1 */
1137                    {
1138                            int dQ;
1139                            int Run;
1140                            uint32_t Cost0;
1141    
1142                            if (AC<0) {
1143                                    Nodes[i].Level = -1;
1144                                    dQ = Lev0 + AC;
1145                            } else {
1146                                    Nodes[i].Level = 1;
1147                                    dQ = Lev0 - AC;
1148                            }
1149                            Cost0 = Lambda*dQ*dQ;
1150    
1151                            Nodes[i].Run = 1;
1152                            Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1153                            for(Run=i-Run_Start; Run>0; --Run)
1154                            {
1155                                    const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1156                                    const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1157                                    const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<TL_SHIFT);
1158    
1159                                    /*
1160                                     * TODO: what about tie-breaks? Should we favor short runs or
1161                                     * long runs? Although the error is the same, it would not be
1162                                     * spread the same way along high and low frequencies...
1163                                     */
1164                                    if (Cost<Best_Cost) {
1165                                            Best_Cost    = Cost;
1166                                            Nodes[i].Run = Run;
1167                                    }
1168    
1169                                    if (lCost<Last_Cost) {
1170                                            Last_Cost  = lCost;
1171                                            Last.Run   = Run;
1172                                            Last_Node  = i;
1173                                    }
1174                            }
1175                            if (Last_Node==i)
1176                                    Last.Level = Nodes[i].Level;
1177    
1178                            if (DBG==1) {
1179                                    Run_Costs[i] = Best_Cost;
1180                                    printf( "Costs #%2d: ", i);
1181                                    for(j=-1;j<=Non_Zero;++j) {
1182                                            if (j==Run_Start)            printf( " %3.0d|", Run_Costs[j]>>12 );
1183                                            else if (j>Run_Start && j<i) printf( " %3.0d|", Run_Costs[j]>>12 );
1184                                            else if (j==i)               printf( "(%3.0d)", Run_Costs[j]>>12 );
1185                                            else                         printf( "  - |" );
1186                                    }
1187                                    printf( "<%3.0d %2d %d>", Min_Cost>>12, Nodes[i].Level, Nodes[i].Run );
1188                                    printf( "  Last:#%2d {%3.0d %2d %d}", Last_Node, Last_Cost>>12, Last.Level, Last.Run );
1189                                    printf( " AC:%3.0d Dist0:%3d Dist(%d)=%d", AC, Dist0>>12, Nodes[i].Level, Cost0>>12 );
1190                                    printf( "\n" );
1191                            }
1192                    }
1193                    else                      /* "big" levels */
1194                    {
1195                            const uint8_t *Tbl_L1, *Tbl_L2, *Tbl_L1_Last, *Tbl_L2_Last;
1196                            int Level2;
1197                            int dQ1, dQ2;
1198                            int Run;
1199                            uint32_t Dist1,Dist2;
1200                            int dDist21;
1201    
1202                            if (Level1>1) {
1203                                    dQ1 = Level1*Mult-AC + Bias;
1204                                    dQ2 = dQ1 - Mult;
1205                                    Level2 = Level1-1;
1206                                    Tbl_L1      = (Level1<=24) ? B16_17_Code_Len[Level1-1]     : Code_Len0;
1207                                    Tbl_L2      = (Level2<=24) ? B16_17_Code_Len[Level2-1]     : Code_Len0;
1208                                    Tbl_L1_Last = (Level1<=6) ? B16_17_Code_Len_Last[Level1-1] : Code_Len0;
1209                                    Tbl_L2_Last = (Level2<=6) ? B16_17_Code_Len_Last[Level2-1] : Code_Len0;
1210                            } else { /* Level1<-1 */
1211                                    dQ1 = Level1*Mult-AC - Bias;
1212                                    dQ2 = dQ1 + Mult;
1213                                    Level2 = Level1 + 1;
1214                                    Tbl_L1      = (Level1>=-24) ? B16_17_Code_Len[Level1^-1]      : Code_Len0;
1215                                    Tbl_L2      = (Level2>=-24) ? B16_17_Code_Len[Level2^-1]      : Code_Len0;
1216                                    Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;
1217                                    Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;
1218                            }
1219                            Dist1 = Lambda*dQ1*dQ1;
1220                            Dist2 = Lambda*dQ2*dQ2;
1221                            dDist21 = Dist2-Dist1;
1222    
1223                            for(Run=i-Run_Start; Run>0; --Run)
1224                            {
1225                                    const uint32_t Cost_Base = Dist1 + Run_Costs[i-Run];
1226                                    uint32_t Cost1, Cost2;
1227                                    int bLevel;
1228    
1229    /*
1230     * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1231     *        if (Cost_Base>=Best_Cost) continue;
1232     */
1233                                    Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1234                                    Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1235    
1236                                    if (Cost2<Cost1) {
1237                                            Cost1 = Cost2;
1238                                            bLevel = Level2;
1239                                    } else
1240                                            bLevel = Level1;
1241    
1242                                    if (Cost1<Best_Cost) {
1243                                            Best_Cost = Cost1;
1244                                            Nodes[i].Run   = Run;
1245                                            Nodes[i].Level = bLevel;
1246                                    }
1247    
1248                                    Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1249                                    Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1250    
1251                                    if (Cost2<Cost1) {
1252                                            Cost1 = Cost2;
1253                                            bLevel = Level2;
1254                                    } else
1255                                            bLevel = Level1;
1256    
1257                                    if (Cost1<Last_Cost) {
1258                                            Last_Cost  = Cost1;
1259                                            Last.Run   = Run;
1260                                            Last.Level = bLevel;
1261                                            Last_Node  = i;
1262                                    }
1263                            } /* end of "for Run" */
1264    
1265                            if (DBG==1) {
1266                                    Run_Costs[i] = Best_Cost;
1267                                    printf( "Costs #%2d: ", i);
1268                                    for(j=-1;j<=Non_Zero;++j) {
1269                                            if (j==Run_Start)            printf( " %3.0d|", Run_Costs[j]>>12 );
1270                                            else if (j>Run_Start && j<i) printf( " %3.0d|", Run_Costs[j]>>12 );
1271                                            else if (j==i)               printf( "(%3.0d)", Run_Costs[j]>>12 );
1272                                            else                         printf( "  - |" );
1273                                    }
1274                                    printf( "<%3.0d %2d %d>", Min_Cost>>12, Nodes[i].Level, Nodes[i].Run );
1275                                    printf( "  Last:#%2d {%3.0d %2d %d}", Last_Node, Last_Cost>>12, Last.Level, Last.Run );
1276                                    printf( " AC:%3.0d Dist0:%3d Dist(%2d):%3d Dist(%2d):%3d", AC, Dist0>>12, Level1, Dist1>>12, Level2, Dist2>>12 );
1277                                    printf( "\n" );
1278                            }
1279                    }
1280    
1281                    Run_Costs[i] = Best_Cost;
1282    
1283                    if (Best_Cost < Min_Cost + Dist0) {
1284                            Min_Cost = Best_Cost;
1285                            Run_Start = i;
1286                    }
1287                    else
1288                    {
1289                            /*
1290                             * as noticed by Michael Niedermayer (michaelni at gmx.at), there's
1291                             * a code shorter by 1 bit for a larger run (!), same level. We give
1292                             * it a chance by not moving the left barrier too much.
1293                             */
1294    
1295                            while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1296                                    Run_Start++;
1297    
1298                            /* spread on preceding coeffs the cost incurred by skipping this one */
1299                            for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
1300                            Min_Cost += Dist0;
1301                    }
1302            }
1303    
1304            if (DBG) {
1305                    Last_Cost = Evaluate_Cost(Out,Mult,Bias, Zigzag,Non_Zero, Lambda);
1306                    if (DBG==1) {
1307                            printf( "=> " );
1308                            for(i=0; i<=Non_Zero; ++i) printf( "[%3.0d] ", Out[Zigzag[i]] );
1309                            printf( "\n" );
1310                    }
1311            }
1312    
1313            if (Last_Node<0)
1314                    return -1;
1315    
1316            /* reconstruct optimal sequence backward with surviving paths */
1317            memset(Out, 0x00, 64*sizeof(*Out));
1318            Out[Zigzag[Last_Node]] = Last.Level;
1319            i = Last_Node - Last.Run;
1320            while(i>=0) {
1321                    Out[Zigzag[i]] = Nodes[i].Level;
1322                    i -= Nodes[i].Run;
1323            }
1324    
1325            if (DBG) {
1326                    uint32_t Cost = Evaluate_Cost(Out,Mult,Bias, Zigzag,Non_Zero, Lambda);
1327                    if (DBG==1) {
1328                            printf( "<= " );
1329                            for(i=0; i<=Last_Node; ++i) printf( "[%3.0d] ", Out[Zigzag[i]] );
1330                            printf( "\n--------------------------------\n" );
1331                    }
1332                    if (Cost>Last_Cost) printf( "!!! %u > %u\n", Cost, Last_Cost );
1333            }
1334            return Last_Node;
1335    }
1336    
1337    #undef DBG
1338    
1339    #endif

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.23

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