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

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

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

revision 1.21.2.18, Tue Oct 7 13:02:35 2003 UTC revision 1.23.2.1, Wed Apr 14 19:51:06 2004 UTC
# Line 43  Line 43 
43  #include "../encoder.h"  #include "../encoder.h"
44    
45  #include "../image/reduced.h"  #include "../image/reduced.h"
46    #include  "../quant/quant_matrix.h"
47    
48  MBFIELDTEST_PTR MBFieldTest;  MBFIELDTEST_PTR MBFieldTest;
49    
# Line 137  Line 138 
138    
139          /* Quantize the block */          /* Quantize the block */
140          start_timer();          start_timer();
141          quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum);          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);          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);          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);          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);          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);          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    
# Line 167  Line 168 
168          scaler_chr = get_dc_scaler(iQuant, 0);          scaler_chr = get_dc_scaler(iQuant, 0);
169    
170          start_timer();          start_timer();
171          dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum);          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);          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);          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);          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);          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);          dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);
177          stop_iquant_timer();          stop_iquant_timer();
178  }  }
179    
   
 typedef int (*trellis_func_ptr_t)(int16_t *const Out,  
                                                                   const int16_t *const In,  
                                                                   int Q,  
                                                                   const uint16_t * const Zigzag,  
                                                                   int Non_Zero);  
   
180  static int  static int
181  dct_quantize_trellis_h263_c(int16_t *const Out,  dct_quantize_trellis_c(int16_t *const Out,
182                                                          const int16_t *const In,                                                          const int16_t *const In,
183                                                          int Q,                                                          int Q,
184                                                          const uint16_t * const Zigzag,                                                          const uint16_t * const Zigzag,
185                                                          int Non_Zero);                                             const uint16_t * const QuantMatrix,
186                                               int Non_Zero,
187  static int                                             int Sum);
 dct_quantize_trellis_mpeg_c(int16_t *const Out,  
                                                         const int16_t *const In,  
                                                         int Q,  
                                                         const uint16_t * const Zigzag,  
                                                         int Non_Zero);  
188    
189  /* Quantize all blocks -- Inter mode */  /* Quantize all blocks -- Inter mode */
190  static __inline uint8_t  static __inline uint8_t
# Line 219  Line 208 
208                          quant_mpeg_inter                          quant_mpeg_inter
209                  };                  };
210    
         trellis_func_ptr_t const trellis[2] =  
                 {  
                         dct_quantize_trellis_h263_c,  
                         dct_quantize_trellis_mpeg_c  
                 };  
   
211          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
212    
213          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
# Line 232  Line 215 
215                  /* Quantize the block */                  /* Quantize the block */
216                  start_timer();                  start_timer();
217    
218                  sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant);                  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)) {                  if(sum && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {
221                          sum = trellis[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, &scan_tables[0][0], 63);                          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    
# Line 285  Line 286 
286          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);          mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
287    
288          start_timer();          start_timer();
289          if(cbp & (1 << (5 - 0))) dequant[mpeg](&data[0 * 64], &qcoeff[0 * 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);          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);          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);          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);          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);          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  }  }
297    
# Line 373  Line 374 
374    
375          transfer_operation_16to8_t *transfer_op = NULL;          transfer_operation_16to8_t *transfer_op = NULL;
376    
         if (pMB->field_dct) {  
                 next_block = stride;  
                 stride *= 2;  
         }  
   
377          /* Makes this vars booleans */          /* Makes this vars booleans */
378          vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);          vop_reduced = !!(frame->vop_flags & XVID_VOP_REDUCED);
379    
# Line 386  Line 382 
382          pU_Cur = pCurrent->u + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));          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));          pV_Cur = pCurrent->v + (y_pos << (3+vop_reduced)) * stride2 + (x_pos << (3+vop_reduced));
384    
385            if (pMB->field_dct) {
386                    next_block = stride;
387                    stride *= 2;
388            }
389    
390          /* Block size */          /* Block size */
391          cst = 8<<vop_reduced;          cst = 8<<vop_reduced;
392    
# Line 651  Line 652 
652   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.   *    IEEE Transactions on Image Processing, Vol.9, No.8, Aug. 2000.
653   *   *
654   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single   * we are at stake with a simplified Bellmand-Ford / Dijkstra Single
655   * Source Shorted Path algo. But due to the underlying graph structure   * Source Shortest Path algo. But due to the underlying graph structure
656   * ("Trellis"), it can be turned into a dynamic programming algo,   * ("Trellis"), it can be turned into a dynamic programming algo,
657   * partially saving the explicit graph's nodes representation. And   * partially saving the explicit graph's nodes representation. And
658   * without using a heap, since the open frontier of the DAG is always   * without using a heap, since the open frontier of the DAG is always
659   * known, and of fixed sized.   * known, and of fixed size.
660   *--------------------------------------------------------------------------*/   *--------------------------------------------------------------------------*/
661    
662    
# Line 755  Line 756 
756          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,          Code_Len24,Code_Len23,Code_Len22,Code_Len21, Code_Len3, Code_Len1,
757  };  };
758    
759  #define TL(q) 0xfe00/(q*q)  /* 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] = {  static const int Trellis_Lambda_Tabs[31] = {
769          TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),          TL( 1),TL( 2),TL( 3),TL( 4),TL( 5),TL( 6), TL( 7),
# Line 775  Line 783 
783          return -1;          return -1;
784  }  }
785    
 static int __inline  
 Compute_Sum(const int16_t *C, int last)  
 {  
         int sum = 0;  
   
         while(last--)  
                 sum += abs(C[last]);  
   
         return(sum);  
 }  
786  /* this routine has been strippen of all debug code */  /* this routine has been strippen of all debug code */
   
787  static int  static int
788  dct_quantize_trellis_h263_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)  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           * Note: We should search last non-zero coeffs on *real* DCT input coeffs (In[]),           * (In[]), not quantized one (Out[]). However, it only improves the result
799           * not quantized one (Out[]). However, it only improves the result *very*           * *very* slightly (~0.01dB), whereas speed drops to crawling level :)
800           * slightly (~0.01dB), whereas speed drops to crawling level :)           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes
801           * Well, actually, taking 1 more coeff past Non_Zero into account sometimes helps.           * helps. */
          */  
802          typedef struct { int16_t Run, Level; } NODE;          typedef struct { int16_t Run, Level; } NODE;
803    
804          NODE Nodes[65], Last;          NODE Nodes[65], Last;
805          uint32_t Run_Costs0[64+1];          uint32_t Run_Costs0[64+1];
806          uint32_t * const Run_Costs = Run_Costs0 + 1;          uint32_t * const Run_Costs = Run_Costs0 + 1;
807          const int Mult = 2*Q;  
808          const int Bias = (Q-1) | 1;          /* it's 1/lambda, actually */
809          const int Lev0 = Mult + Bias;          const int Lambda = Trellis_Lambda_Tabs[Q-1];
         const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */  
810    
811          int Run_Start = -1;          int Run_Start = -1;
812          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
813    
814          int Last_Node = -1;          int Last_Node = -1;
815          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
816    
817          int i, j, sum;          int i, j;
818          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */  
819            /* source (w/ CBP penalty) */
820            Run_Costs[-1] = 2<<TL_SHIFT;
821    
822          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);          Non_Zero = Find_Last(Out, Zigzag, Non_Zero);
823          if (Non_Zero<0)          if (Non_Zero<0)
824                  return 0; /* Sum is zero if there are only zero coeffs */                  return 0; /* Sum is zero if there are only zero coeffs */
825    
826          for(i=0; i<=Non_Zero; i++) {          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]];                  const int AC = In[Zigzag[i]];
833                  const int Level1 = Out[Zigzag[i]];                  const int Level1 = Out[Zigzag[i]];
834                  const int Dist0 = Lambda* AC*AC;                  const unsigned int Dist0 = Lambda* AC*AC;
835                  uint32_t Best_Cost = 0xf0000000;                  uint32_t Best_Cost = 0xf0000000;
836                  Last_Cost += Dist0;                  Last_Cost += Dist0;
837    
# Line 843  Line 851 
851                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
852    
853                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
854                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
855                          for(Run=i-Run_Start; Run>0; --Run) {                          for(Run=i-Run_Start; Run>0; --Run) {
856                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
857                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
858                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  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
                                  * TODO: what about tie-breaks? Should we favor short runs or  
861                                   * long runs? Although the error is the same, it would not be                                   * long runs? Although the error is the same, it would not be
862                                   * spread the same way along high and low frequencies...                                   * spread the same way along high and low frequencies... */
                                  */  
863    
864                                  /* (I'd say: favour short runs => hifreq errors (HVS) -- gruel ) */                                  /* Gruel: I'd say, favour short runs => hifreq errors (HVS) */
865    
866                                  if (Cost<Best_Cost) {                                  if (Cost<Best_Cost) {
867                                          Best_Cost    = Cost;                                          Best_Cost    = Cost;
# Line 870  Line 876 
876                          }                          }
877                          if (Last_Node==i)                          if (Last_Node==i)
878                                  Last.Level = Nodes[i].Level;                                  Last.Level = Nodes[i].Level;
879                  } else { /* "big" levels */                  } 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;                          const uint8_t *Tbl_L1, *Tbl_L2, *Tbl_L1_Last, *Tbl_L2_Last;
882                          int Level2;                          int Level2;
883                          int dQ1, dQ2;                          int dQ1, dQ2;
# Line 906  Line 913 
913                                  uint32_t Cost1, Cost2;                                  uint32_t Cost1, Cost2;
914                                  int bLevel;                                  int bLevel;
915    
916                                  /*                                  /* for sub-optimal (but slightly worth it, speed-wise) search,
917                                   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:                                   * uncomment the following:
918                                   *      if (Cost_Base>=Best_Cost) continue;                                   *      if (Cost_Base>=Best_Cost) continue;
919                                   * (? doesn't seem to have any effect -- gruel )                                   * (? doesn't seem to have any effect -- gruel ) */
                                  */  
920    
921                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
922                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
923    
924                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
925                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 928  Line 934 
934                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
935                                  }                                  }
936    
937                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
938                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
939    
940                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
941                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 945  Line 951 
951                                          Last_Node  = i;                                          Last_Node  = i;
952                                  }                                  }
953                          } /* end of "for Run" */                          } /* 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;                  Run_Costs[i] = Best_Cost;
978    
979                  if (Best_Cost < Min_Cost + Dist0) {                  if (Best_Cost < Min_Cost + Dist0) {
980                          Min_Cost = Best_Cost;                          Min_Cost = Best_Cost;
981                          Run_Start = i;                          Run_Start = i;
982                  } else {                  } else {
983                          /*                          /* as noticed by Michael Niedermayer (michaelni at gmx.at),
984                           * as noticed by Michael Niedermayer (michaelni at gmx.at), there's                           * there's a code shorter by 1 bit for a larger run (!), same
985                           * a code shorter by 1 bit for a larger run (!), same level. We give                           * level. We give it a chance by not moving the left barrier too
986                           * it a chance by not moving the left barrier too much.                           * much. */
987                           */                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
   
                         while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )  
988                                  Run_Start++;                                  Run_Start++;
989    
990                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this
991                             * one */
992                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;                          for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;
993                          Min_Cost += Dist0;                          Min_Cost += Dist0;
994                  }                  }
995          }          }
996    
997          /* It seems trellis doesn't give good results... just compute the Out sum and          /* It seems trellis doesn't give good results... just leave the block untouched
998           * quit (even if we did not modify it, upperlayer relies on this data) */           * and return the original sum value */
999          if (Last_Node<0)          if (Last_Node<0)
1000                  return Compute_Sum(Out, Non_Zero);                  return Sum;
1001    
1002          /* reconstruct optimal sequence backward with surviving paths */          /* reconstruct optimal sequence backward with surviving paths */
1003          memset(Out, 0x00, 64*sizeof(*Out));          memset(Out, 0x00, 64*sizeof(*Out));
1004          Out[Zigzag[Last_Node]] = Last.Level;          Out[Zigzag[Last_Node]] = Last.Level;
1005          i = Last_Node - Last.Run;          i = Last_Node - Last.Run;
1006          sum = 0;          Sum = 0;
1007          while(i>=0) {          while(i>=0) {
1008                  Out[Zigzag[i]] = Nodes[i].Level;                  Out[Zigzag[i]] = Nodes[i].Level;
1009                  sum += abs(Nodes[i].Level);                  Sum += abs(Nodes[i].Level);
1010                  i -= Nodes[i].Run;                  i -= Nodes[i].Run;
1011          }          }
1012    
1013          return sum;          return Sum;
 }  
   
 static int  
 dct_quantize_trellis_mpeg_c(int16_t *const Out, const int16_t *const In, int Q, const uint16_t * const Zigzag, int Non_Zero)  
 {  
         /* ToDo: Ok ok it's just a place holder for Gruel -- damn write this one :-) */  
         return Compute_Sum(Out, 63);  
1014  }  }
1015    
1016  /* original version including heavy debugging info */  /* original version including heavy debugging info */
# Line 1051  Line 1069 
1069                  V -= Ref[Zigzag[i]];                  V -= Ref[Zigzag[i]];
1070                  Dist += V*V;                  Dist += V*V;
1071          }          }
1072          Cost = Lambda*Dist + (Bits<<16);          Cost = Lambda*Dist + (Bits<<TL_SHIFT);
1073          if (DBG==1)          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 );                  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;          return Cost;
# Line 1083  Line 1101 
1101          const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */          const int Lambda = Trellis_Lambda_Tabs[Q-1];    /* it's 1/lambda, actually */
1102    
1103          int Run_Start = -1;          int Run_Start = -1;
1104          Run_Costs[-1] = 2<<16;                          /* source (w/ CBP penalty) */          Run_Costs[-1] = 2<<TL_SHIFT;                          /* source (w/ CBP penalty) */
1105          uint32_t Min_Cost = 2<<16;          uint32_t Min_Cost = 2<<TL_SHIFT;
1106    
1107          int Last_Node = -1;          int Last_Node = -1;
1108          uint32_t Last_Cost = 0;          uint32_t Last_Cost = 0;
# Line 1123  Line 1141 
1141                          Cost0 = Lambda*dQ*dQ;                          Cost0 = Lambda*dQ*dQ;
1142    
1143                          Nodes[i].Run = 1;                          Nodes[i].Run = 1;
1144                          Best_Cost = (Code_Len20[0]<<16) + Run_Costs[i-1]+Cost0;                          Best_Cost = (Code_Len20[0]<<TL_SHIFT) + Run_Costs[i-1]+Cost0;
1145                          for(Run=i-Run_Start; Run>0; --Run)                          for(Run=i-Run_Start; Run>0; --Run)
1146                          {                          {
1147                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];                                  const uint32_t Cost_Base = Cost0 + Run_Costs[i-Run];
1148                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<16);                                  const uint32_t Cost = Cost_Base + (Code_Len20[Run-1]<<TL_SHIFT);
1149                                  const uint32_t lCost = Cost_Base + (Code_Len24[Run-1]<<16);                                  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                                   * TODO: what about tie-breaks? Should we favor short runs or
# Line 1204  Line 1222 
1222   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:   * for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following:
1223   *        if (Cost_Base>=Best_Cost) continue;   *        if (Cost_Base>=Best_Cost) continue;
1224   */   */
1225                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1[Run-1]<<TL_SHIFT);
1226                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2[Run-1]<<TL_SHIFT) + dDist21;
1227    
1228                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1229                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1219  Line 1237 
1237                                          Nodes[i].Level = bLevel;                                          Nodes[i].Level = bLevel;
1238                                  }                                  }
1239    
1240                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);                                  Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<TL_SHIFT);
1241                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;                                  Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<TL_SHIFT) + dDist21;
1242    
1243                                  if (Cost2<Cost1) {                                  if (Cost2<Cost1) {
1244                                          Cost1 = Cost2;                                          Cost1 = Cost2;
# Line 1266  Line 1284 
1284                           * it a chance by not moving the left barrier too much.                           * it a chance by not moving the left barrier too much.
1285                           */                           */
1286    
1287                          while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )                          while( Run_Costs[Run_Start]>Min_Cost+(1<<TL_SHIFT) )
1288                                  Run_Start++;                                  Run_Start++;
1289    
1290                          /* spread on preceding coeffs the cost incurred by skipping this one */                          /* spread on preceding coeffs the cost incurred by skipping this one */

Legend:
Removed from v.1.21.2.18  
changed lines
  Added in v.1.23.2.1

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