[svn] / trunk / xvidcore / src / motion / estimation_rd_based_bvop.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/estimation_rd_based_bvop.c

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

revision 1508, Sun Jul 18 12:22:31 2004 UTC revision 1660, Fri Dec 9 04:45:35 2005 UTC
# Line 1  Line 1 
1    /*****************************************************************************
2     *
3     *  XVID MPEG-4 VIDEO CODEC
4     *  - Rate-Distortion Based Motion Estimation for B- VOPs  -
5     *
6     *  Copyright(C) 2004 Radoslaw Czyz <xvid@syskin.cjb.net>
7     *
8     *  This program is free software ; you can redistribute it and/or modify
9     *  it under the terms of the GNU General Public License as published by
10     *  the Free Software Foundation ; either version 2 of the License, or
11     *  (at your option) any later version.
12     *
13     *  This program is distributed in the hope that it will be useful,
14     *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
15     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     *  GNU General Public License for more details.
17     *
18     *  You should have received a copy of the GNU General Public License
19     *  along with this program ; if not, write to the Free Software
20     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21     *
22     * $Id: estimation_rd_based_bvop.c,v 1.10 2005-12-09 04:45:35 syskin Exp $
23     *
24     ****************************************************************************/
25    
26  #include <assert.h>  #include <assert.h>
27  #include <stdio.h>  #include <stdio.h>
# Line 31  Line 55 
55                                  const int block,                                  const int block,
56                                  const uint16_t * scan_table,                                  const uint16_t * scan_table,
57                                  const unsigned int lambda,                                  const unsigned int lambda,
58                                  const uint16_t * mpeg_quant_matrices)                                  const uint16_t * mpeg_quant_matrices,
59                                    const unsigned int quant_sq,
60                                    int * const cbpcost)
61  {  {
62          int sum;          int sum;
63          int bits;          int bits;
64          int distortion = 0;          int distortion = 0;
65    
66          fdct(data);          fdct((short * const)data);
67    
68          if (quant_type) sum = quant_h263_inter(coeff, data, quant, mpeg_quant_matrices);          if (quant_type) sum = quant_h263_inter(coeff, data, quant, mpeg_quant_matrices);
69          else sum = quant_mpeg_inter(coeff, data, quant, mpeg_quant_matrices);          else sum = quant_mpeg_inter(coeff, data, quant, mpeg_quant_matrices);
# Line 45  Line 71 
71          if ((sum >= 3) || (coeff[1] != 0) || (coeff[8] != 0) || (coeff[0] != 0)) {          if ((sum >= 3) || (coeff[1] != 0) || (coeff[8] != 0) || (coeff[0] != 0)) {
72                  *cbp |= 1 << (5 - block);                  *cbp |= 1 << (5 - block);
73                  bits = BITS_MULT * CodeCoeffInter_CalcBits(coeff, scan_table);                  bits = BITS_MULT * CodeCoeffInter_CalcBits(coeff, scan_table);
74                    bits += *cbpcost;
75                    *cbpcost = 0; /* don't add cbp cost second time */
76    
77                  if (quant_type) dequant_h263_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);                  if (quant_type) dequant_h263_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);
78                  else dequant_mpeg_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);                  else dequant_mpeg_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);
# Line 66  Line 94 
94                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));
95          }          }
96    
97          return bits + (lambda*distortion)/(quant*quant);          return bits + (lambda*distortion)/quant_sq;
98  }  }
99    
100    
# Line 79  Line 107 
107                                  const int block,                                  const int block,
108                                  const uint16_t * scan_table,                                  const uint16_t * scan_table,
109                                  const unsigned int lambda,                                  const unsigned int lambda,
110                                  const uint16_t * mpeg_quant_matrices)                                  const uint16_t * mpeg_quant_matrices,
111                                    const unsigned int quant_sq,
112                                    int * const cbpcost)
113  {  {
114          int sum;          int sum;
115          int bits;          int bits;
116          int distortion = 0;          int distortion = 0;
117    
118          fdct(data);          fdct((short * const)data);
119    
120          if (quant_type) sum = quant_h263_inter(coeff, data, quant, mpeg_quant_matrices);          if (quant_type) sum = quant_h263_inter(coeff, data, quant, mpeg_quant_matrices);
121          else sum = quant_mpeg_inter(coeff, data, quant, mpeg_quant_matrices);          else sum = quant_mpeg_inter(coeff, data, quant, mpeg_quant_matrices);
# Line 93  Line 123 
123          if ((sum >= 3) || (coeff[1] != 0) || (coeff[8] != 0) || (coeff[0] > 0) || (coeff[0] < -1)) {          if ((sum >= 3) || (coeff[1] != 0) || (coeff[8] != 0) || (coeff[0] > 0) || (coeff[0] < -1)) {
124                  *cbp |= 1 << (5 - block);                  *cbp |= 1 << (5 - block);
125                  bits = BITS_MULT * CodeCoeffInter_CalcBits(coeff, scan_table);                  bits = BITS_MULT * CodeCoeffInter_CalcBits(coeff, scan_table);
126                    bits += *cbpcost;
127                    *cbpcost = 0;
128    
129                  if (quant_type) dequant_h263_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);                  if (quant_type) dequant_h263_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);
130                  else dequant_mpeg_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);                  else dequant_mpeg_inter(dqcoeff, coeff, quant, mpeg_quant_matrices);
# Line 114  Line 146 
146                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));
147          }          }
148    
149          return bits + (lambda*distortion)/(quant*quant);          return bits + (lambda*distortion)/quant_sq;
 }  
   
   
 static void  
 transfer_8to16sub2ro(int16_t * const dct,  
                                          const uint8_t * const cur,  
                                          const uint8_t * ref1,  
                                          const uint8_t * ref2,  
                                          const uint32_t stride)  
 {  
         uint32_t i, j;  
   
         for (j = 0; j < 8; j++) {  
                 for (i = 0; i < 8; i++) {  
                         uint8_t c = cur[j * stride + i];  
                         int r = (ref1[j * stride + i] + ref2[j * stride + i] + 1) / 2;  
                         dct[j * 8 + i] = (int16_t) c - (int16_t) r;  
                 }  
         }  
150  }  }
151    
152  static void  static void
# Line 141  Line 154 
154  {  {
155    
156          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;
157          int32_t rd = 3*BITS_MULT; /* note to self: 3 bits minimum, but maybe 4 if it's forward mode */          int32_t rd = (3+2)*BITS_MULT; /* 3 bits for mode + 2 for vector (minimum) */
158          VECTOR * current;          VECTOR * current;
159          const uint8_t * ptr;          const uint8_t * ptr;
160          int i, xc, yc;          int i, xc, yc;
161          unsigned cbp = 0;          unsigned cbp = 0;
162            int cbpcost = 7*BITS_MULT; /* how much to add if cbp turns out to be non-zero */
163    
164          if ( (x > data->max_dx) || (x < data->min_dx)          if ( (x > data->max_dx) || (x < data->min_dx)
165                  || (y > data->max_dy) || (y < data->min_dy) ) return;                  || (y > data->max_dy) || (y < data->min_dy) ) return;
# Line 160  Line 174 
174                  xc = x/2; yc = y/2;                  xc = x/2; yc = y/2;
175          }          }
176    
177          rd += BITS_MULT*d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);          rd += BITS_MULT*(d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision)-2);
178    
179          for(i = 0; i < 4; i++) {          for(i = 0; i < 4; i++) {
180                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);
181                  transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);                  transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);
182                  rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices);                  rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type,
183                                                                    &cbp, i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices,
184                                                                    data->quant_sq, &cbpcost);
185                  if (rd >= data->iMinSAD[0]) return;                  if (rd >= data->iMinSAD[0]) return;
186          }          }
187    
# Line 176  Line 192 
192          /* chroma U */          /* chroma U */
193          ptr = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xc, yc, data->iEdgedWidth/2, data->rounding);          ptr = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xc, yc, data->iEdgedWidth/2, data->rounding);
194          transfer_8to16subro(in, data->CurU, ptr, data->iEdgedWidth/2);          transfer_8to16subro(in, data->CurU, ptr, data->iEdgedWidth/2);
195          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices);          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type,
196                                                                    &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices,
197                                                                    data->quant_sq, &cbpcost);
198          if (rd >= data->iMinSAD[0]) return;          if (rd >= data->iMinSAD[0]) return;
199    
200          /* chroma V */          /* chroma V */
201          ptr = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xc, yc, data->iEdgedWidth/2, data->rounding);          ptr = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xc, yc, data->iEdgedWidth/2, data->rounding);
202          transfer_8to16subro(in, data->CurV, ptr, data->iEdgedWidth/2);          transfer_8to16subro(in, data->CurV, ptr, data->iEdgedWidth/2);
203          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices);          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type,
204                                                                    &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices,
205          if (cbp) rd += BITS_MULT * 7;                                                                  data->quant_sq, &cbpcost);
206    
207          if (rd < data->iMinSAD[0]) {          if (rd < data->iMinSAD[0]) {
208                  data->iMinSAD[0] = rd;                  data->iMinSAD[0] = rd;
# Line 194  Line 212 
212          }          }
213  }  }
214    
   
215  static void  static void
216  CheckCandidateRDDirect(const int x, const int y, SearchData * const data, const unsigned int Direction)  CheckCandidateRDDirect(const int x, const int y, SearchData * const data, const unsigned int Direction)
217  {  {
# Line 204  Line 221 
221          unsigned int cbp = 0;          unsigned int cbp = 0;
222          unsigned int k;          unsigned int k;
223          VECTOR mvs, b_mvs;          VECTOR mvs, b_mvs;
224            int cbpcost = 6*BITS_MULT; /* how much to add if cbp turns out to be non-zero */
225    
226          const uint8_t *ReferenceF, *ReferenceB;          const uint8_t *ReferenceF, *ReferenceB;
227    
# Line 241  Line 259 
259                  }                  }
260    
261                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF, ReferenceB, data->iEdgedWidth);                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF, ReferenceB, data->iEdgedWidth);
262                  rd += Block_CalcBits_BVOP_direct(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, k, data->scan_table, data->lambda[k], data->mpeg_quant_matrices);                  rd += Block_CalcBits_BVOP_direct(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type,
263                                                                                    &cbp, k, data->scan_table, data->lambda[k], data->mpeg_quant_matrices,
264                                                                                    data->quant_sq, &cbpcost);
265                  if (rd > *(data->iMinSAD)) return;                  if (rd > *(data->iMinSAD)) return;
266          }          }
267    
# Line 255  Line 275 
275          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);
276          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[4], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[4], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);
277          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);
278          rd += Block_CalcBits_BVOP_direct(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices);          rd += Block_CalcBits_BVOP_direct(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type,
279                                                                            &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices,
280                                                                            data->quant_sq, &cbpcost);
281          if (rd >= data->iMinSAD[0]) return;          if (rd >= data->iMinSAD[0]) return;
282    
283          /* chroma V */          /* chroma V */
284          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);
285          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[5], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[5], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);
286          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);
287          rd += Block_CalcBits_BVOP_direct(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices);          rd += Block_CalcBits_BVOP_direct(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type,
288                                                                            &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices,
289                                                                            data->quant_sq, &cbpcost);
290    
         if (cbp)  
                 rd += BITS_MULT * 6;  
291          if (cbp || x != 0 || y != 0)          if (cbp || x != 0 || y != 0)
292                  rd += BITS_MULT * d_mv_bits(x, y, zeroMV, 1, 0, 0);                  rd += BITS_MULT * d_mv_bits(x, y, zeroMV, 1, 0);
293    
294          if (rd < *(data->iMinSAD)) {          if (rd < *(data->iMinSAD)) {
295                  *data->iMinSAD = rd;                  *data->iMinSAD = rd;
# Line 277  Line 299 
299          }          }
300  }  }
301    
   
   
   
302  static void  static void
303  CheckCandidateRDInt(const int x, const int y, SearchData * const data, const unsigned int Direction)  CheckCandidateRDInt(const int x, const int y, SearchData * const data, const unsigned int Direction)
304  {  {
# Line 288  Line 307 
307          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;
308          unsigned int cbp = 0;          unsigned int cbp = 0;
309          unsigned int i;          unsigned int i;
310            int cbpcost = 7*BITS_MULT; /* how much to add if cbp turns out to be non-zero */
311    
312          const uint8_t *ReferenceF, *ReferenceB;          const uint8_t *ReferenceF, *ReferenceB;
313          VECTOR *current;          VECTOR *current;
# Line 322  Line 342 
342                  xcb = xb/2; ycb = yb/2;                  xcb = xb/2; ycb = yb/2;
343          }          }
344    
345          rd += BITS_MULT * (d_mv_bits(xf, yf, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0)          rd += BITS_MULT * (d_mv_bits(xf, yf, data->predMV, data->iFcode, data->qpel^data->qpel_precision)
346                                          + d_mv_bits(xb, yb, data->bpredMV, data->iFcode, data->qpel^data->qpel_precision, 0));                                          + d_mv_bits(xb, yb, data->bpredMV, data->iFcode, data->qpel^data->qpel_precision));
   
347    
348          for(i = 0; i < 4; i++) {          for(i = 0; i < 4; i++) {
349                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);
350                  if (rd >= *data->iMinSAD) return;                  if (rd >= *data->iMinSAD) return;
351                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF + s, ReferenceB + s, data->iEdgedWidth);                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF + s, ReferenceB + s, data->iEdgedWidth);
352                  rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices);                  rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp,
353                                                                    i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices,
354                                                                    data->quant_sq, &cbpcost);
355          }          }
356    
357          /* chroma */          /* chroma */
# Line 343  Line 364 
364          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[4], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);
365          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[4], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[4], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);
366          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);
367          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices);          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp,
368                                                                    4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices,
369                                                                    data->quant_sq, &cbpcost);
370          if (rd >= data->iMinSAD[0]) return;          if (rd >= data->iMinSAD[0]) return;
371    
372    
# Line 351  Line 374 
374          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);          ReferenceF = interpolate8x8_switch2(data->RefQ, data->RefP[5], 0, 0, xcf, ycf, data->iEdgedWidth/2, data->rounding);
375          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[5], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);          ReferenceB = interpolate8x8_switch2(data->RefQ + 16, data->b_RefP[5], 0, 0, xcb, ycb, data->iEdgedWidth/2, data->rounding);
376          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);
377          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices);          rd += Block_CalcBits_BVOP(coeff, in, data->dctSpace + 128, data->iQuant, data->quant_type, &cbp,
378                                                                    5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices,
379          if (cbp) rd += BITS_MULT * 7;                                                                  data->quant_sq, &cbpcost);
380    
381          if (rd < *(data->iMinSAD)) {          if (rd < *(data->iMinSAD)) {
382                  *data->iMinSAD = rd;                  *data->iMinSAD = rd;
# Line 375  Line 398 
398          Data->iMinSAD[0] = *best_sad;          Data->iMinSAD[0] = *best_sad;
399    
400          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,
401                  x, y, 4, pParam->width, pParam->height, Data->iFcode, 1 + Data->qpel, 0);                  x, y, 4, pParam->width, pParam->height, Data->iFcode, 1 + Data->qpel);
402    
403          Data->qpel_precision = Data->qpel;          Data->qpel_precision = Data->qpel;
404    
# Line 418  Line 441 
441          Data->iMinSAD[0] = *best_sad;          Data->iMinSAD[0] = *best_sad;
442    
443          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy,
444                  x, y, 4, pParam->width, pParam->height, Data->iFcode, 1 + Data->qpel, 0);                  x, y, 4, pParam->width, pParam->height, Data->iFcode, 1 + Data->qpel);
445    
446          Data->qpel_precision = Data->qpel;          Data->qpel_precision = Data->qpel;
447    
# Line 460  Line 483 
483                                           VECTOR * b_predMV,                                           VECTOR * b_predMV,
484                                           const uint32_t MotionFlags,                                           const uint32_t MotionFlags,
485                                           const MBParam * const pParam,                                           const MBParam * const pParam,
486                                           int x, int y)                                           int x, int y,
487                                             int best_sad)
488  {  {
489          int mode = MODE_DIRECT, k;          int mode = MODE_DIRECT, k;
490          int f_rd, b_rd, i_rd, d_rd, best_rd;          int f_rd, b_rd, i_rd, d_rd, best_rd;
# Line 468  Line 492 
492          const uint32_t iQuant = Data_d->iQuant;          const uint32_t iQuant = Data_d->iQuant;
493          int i;          int i;
494          int ref_quant = b_mb->quant;          int ref_quant = b_mb->quant;
495            int no_of_checks = 0;
496    
497          int order[4] = {MODE_DIRECT, MODE_FORWARD, MODE_BACKWARD, MODE_INTERPOLATE};          int order[4] = {MODE_DIRECT, MODE_FORWARD, MODE_BACKWARD, MODE_INTERPOLATE};
498    
499          Data_d->scan_table = Data_b->scan_table = Data_f->scan_table = Data_i->scan_table          Data_d->scan_table = Data_b->scan_table = Data_f->scan_table = Data_i->scan_table
500                  = /*VopFlags & XVID_VOP_ALTERNATESCAN ? scan_tables[2] : */scan_tables[0];                  = /*VopFlags & XVID_VOP_ALTERNATESCAN ? scan_tables[2] : */scan_tables[0];
501            *Data_f->cbp = *Data_b->cbp = *Data_i->cbp = *Data_d->cbp = 63;
502    
503          f_rd = b_rd = i_rd = d_rd = best_rd = 256*4096;          f_rd = b_rd = i_rd = d_rd = best_rd = 256*4096;
504    
505          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
506                  int lam = (LAMBDA*iQuant*iQuant)/(ref_quant*(ref_quant+1)); /* re-calculate as if it was p-frame's quant +.5 */                  /* re-calculate as if it was p-frame's quant +.5 */
507                    int lam = (pMB->lambda[i]*LAMBDA*iQuant*iQuant)/(ref_quant*(ref_quant+1));
508                    lam >>= LAMBDA_EXP;
509                  Data_d->lambda[i] = lam;                  Data_d->lambda[i] = lam;
510                  Data_b->lambda[i] = lam;                  Data_b->lambda[i] = lam;
511                  Data_f->lambda[i] = lam;                  Data_f->lambda[i] = lam;
# Line 500  Line 528 
528                  }                  }
529          }          }
530    
531            for(i = 0; i < 4; i++)
532                    if (get_sad_for_mode(order[i], Data_d, Data_b, Data_f, Data_i) < 2*best_sad)
533                            no_of_checks++;
534    
535            if (no_of_checks > 1) {
536          /* evaluate cost of all modes */          /* evaluate cost of all modes */
537          for (i = 0; i < 4; i++) {                  for (i = 0; i < no_of_checks; i++) {
538                  int rd;                  int rd;
539                            if (2*best_sad < get_sad_for_mode(order[i], Data_d, Data_b, Data_f, Data_i))
540                                    break; /* further SADs are too big */
541    
542                  switch (order[i]) {                  switch (order[i]) {
543                  case MODE_DIRECT:                  case MODE_DIRECT:
# Line 524  Line 559 
559                          best_rd = rd;                          best_rd = rd;
560                  }                  }
561          }          }
562            } else {
563                    /* only 1 mode is below the threshold */
564                    mode = order[0];
565                    best_rd = 0;
566            }
567    
568          pMB->sad16 = best_rd;          pMB->sad16 = best_rd;
569          pMB->mode = mode;          pMB->mode = mode;
# Line 576  Line 616 
616                  }                  }
617                  pMB->mvs[0] = *Data_f->currentMV;                  pMB->mvs[0] = *Data_f->currentMV;
618                  pMB->cbp = *Data_f->cbp;                  pMB->cbp = *Data_f->cbp;
619                    pMB->b_mvs[0] = *Data_b->currentMV; /* hint for future searches */
620                  break;                  break;
621    
622          case MODE_BACKWARD:          case MODE_BACKWARD:
# Line 591  Line 632 
632                  }                  }
633                  pMB->b_mvs[0] = *Data_b->currentMV;                  pMB->b_mvs[0] = *Data_b->currentMV;
634                  pMB->cbp = *Data_b->cbp;                  pMB->cbp = *Data_b->cbp;
635                    pMB->mvs[0] = *Data_f->currentMV; /* hint for future searches */
636                  break;                  break;
637    
638    

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

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