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

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.21.2.20

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