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

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

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

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

Legend:
Removed from v.69  
changed lines
  Added in v.1660

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