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

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

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