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

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

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