[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 1584, Sun Dec 19 13:53:54 2004 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.7 2004-12-19 13:53:54 edgomez 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  {  {
61          int sum;          int sum;
62          int bits;          int bits;
# Line 66  Line 91 
91                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));
92          }          }
93    
94          return bits + (lambda*distortion)/(quant*quant);          return bits + (lambda*distortion)/quant_sq;
95  }  }
96    
97    
# Line 79  Line 104 
104                                  const int block,                                  const int block,
105                                  const uint16_t * scan_table,                                  const uint16_t * scan_table,
106                                  const unsigned int lambda,                                  const unsigned int lambda,
107                                  const uint16_t * mpeg_quant_matrices)                                  const uint16_t * mpeg_quant_matrices,
108                                    const unsigned int quant_sq)
109  {  {
110          int sum;          int sum;
111          int bits;          int bits;
# Line 114  Line 140 
140                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));                  distortion = sse8_16bit(data, zero_block, 8*sizeof(int16_t));
141          }          }
142    
143          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;  
                 }  
         }  
144  }  }
145    
146  static void  static void
# Line 141  Line 148 
148  {  {
149    
150          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;
151          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) */
152          VECTOR * current;          VECTOR * current;
153          const uint8_t * ptr;          const uint8_t * ptr;
154          int i, xc, yc;          int i, xc, yc;
# Line 160  Line 167 
167                  xc = x/2; yc = y/2;                  xc = x/2; yc = y/2;
168          }          }
169    
170          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);
171    
172          for(i = 0; i < 4; i++) {          for(i = 0; i < 4; i++) {
173                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);
174                  transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);                  transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);
175                  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,
176                                                                    &cbp, i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices, data->quant_sq);
177                  if (rd >= data->iMinSAD[0]) return;                  if (rd >= data->iMinSAD[0]) return;
178          }          }
179    
# Line 176  Line 184 
184          /* chroma U */          /* chroma U */
185          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);
186          transfer_8to16subro(in, data->CurU, ptr, data->iEdgedWidth/2);          transfer_8to16subro(in, data->CurU, ptr, data->iEdgedWidth/2);
187          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,
188                                                                    &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices, data->quant_sq);
189          if (rd >= data->iMinSAD[0]) return;          if (rd >= data->iMinSAD[0]) return;
190    
191          /* chroma V */          /* chroma V */
192          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);
193          transfer_8to16subro(in, data->CurV, ptr, data->iEdgedWidth/2);          transfer_8to16subro(in, data->CurV, ptr, data->iEdgedWidth/2);
194          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,
195                                                                    &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices, data->quant_sq);
196    
197          if (cbp) rd += BITS_MULT * 7;          if (cbp) rd += BITS_MULT * 7;
198    
# Line 194  Line 204 
204          }          }
205  }  }
206    
   
207  static void  static void
208  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)
209  {  {
# Line 241  Line 250 
250                  }                  }
251    
252                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF, ReferenceB, data->iEdgedWidth);                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF, ReferenceB, data->iEdgedWidth);
253                  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,
254                                                                                    &cbp, k, data->scan_table, data->lambda[k], data->mpeg_quant_matrices, data->quant_sq);
255                  if (rd > *(data->iMinSAD)) return;                  if (rd > *(data->iMinSAD)) return;
256          }          }
257    
# Line 255  Line 265 
265          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);
266          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);
267          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);
268          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,
269                                                                            &cbp, 4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices, data->quant_sq);
270          if (rd >= data->iMinSAD[0]) return;          if (rd >= data->iMinSAD[0]) return;
271    
272          /* chroma V */          /* chroma V */
273          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);
274          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);
275          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);
276          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,
277                                                                            &cbp, 5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices, data->quant_sq);
278    
279          if (cbp)          if (cbp)
280                  rd += BITS_MULT * 6;                  rd += BITS_MULT * 6;
281          if (cbp || x != 0 || y != 0)          if (cbp || x != 0 || y != 0)
282                  rd += BITS_MULT * d_mv_bits(x, y, zeroMV, 1, 0, 0);                  rd += BITS_MULT * d_mv_bits(x, y, zeroMV, 1, 0);
283    
284          if (rd < *(data->iMinSAD)) {          if (rd < *(data->iMinSAD)) {
285                  *data->iMinSAD = rd;                  *data->iMinSAD = rd;
# Line 277  Line 289 
289          }          }
290  }  }
291    
   
   
   
292  static void  static void
293  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)
294  {  {
# Line 322  Line 331 
331                  xcb = xb/2; ycb = yb/2;                  xcb = xb/2; ycb = yb/2;
332          }          }
333    
334          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)
335                                          + 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));
   
336    
337          for(i = 0; i < 4; i++) {          for(i = 0; i < 4; i++) {
338                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);
339                  if (rd >= *data->iMinSAD) return;                  if (rd >= *data->iMinSAD) return;
340                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF + s, ReferenceB + s, data->iEdgedWidth);                  transfer_8to16sub2ro(in, data->Cur + s, ReferenceF + s, ReferenceB + s, data->iEdgedWidth);
341                  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,
342                                                                    i, data->scan_table, data->lambda[i], data->mpeg_quant_matrices, data->quant_sq);
343          }          }
344    
345          /* chroma */          /* chroma */
# Line 343  Line 352 
352          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);
353          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);
354          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurU, ReferenceF, ReferenceB, data->iEdgedWidth/2);
355          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,
356                                                                    4, data->scan_table, data->lambda[4], data->mpeg_quant_matrices, data->quant_sq);
357          if (rd >= data->iMinSAD[0]) return;          if (rd >= data->iMinSAD[0]) return;
358    
359    
# Line 351  Line 361 
361          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);
362          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);
363          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);          transfer_8to16sub2ro(in, data->CurV, ReferenceF, ReferenceB, data->iEdgedWidth/2);
364          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,
365                                                                    5, data->scan_table, data->lambda[5], data->mpeg_quant_matrices, data->quant_sq);
366    
367          if (cbp) rd += BITS_MULT * 7;          if (cbp) rd += BITS_MULT * 7;
368    
# Line 375  Line 386 
386          Data->iMinSAD[0] = *best_sad;          Data->iMinSAD[0] = *best_sad;
387    
388          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,
389                  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);
390    
391          Data->qpel_precision = Data->qpel;          Data->qpel_precision = Data->qpel;
392    
# Line 418  Line 429 
429          Data->iMinSAD[0] = *best_sad;          Data->iMinSAD[0] = *best_sad;
430    
431          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,
432                  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);
433    
434          Data->qpel_precision = Data->qpel;          Data->qpel_precision = Data->qpel;
435    
# Line 460  Line 471 
471                                           VECTOR * b_predMV,                                           VECTOR * b_predMV,
472                                           const uint32_t MotionFlags,                                           const uint32_t MotionFlags,
473                                           const MBParam * const pParam,                                           const MBParam * const pParam,
474                                           int x, int y)                                           int x, int y,
475                                             int best_sad)
476  {  {
477          int mode = MODE_DIRECT, k;          int mode = MODE_DIRECT, k;
478          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 480 
480          const uint32_t iQuant = Data_d->iQuant;          const uint32_t iQuant = Data_d->iQuant;
481          int i;          int i;
482          int ref_quant = b_mb->quant;          int ref_quant = b_mb->quant;
483            int no_of_checks = 0;
484    
485          int order[4] = {MODE_DIRECT, MODE_FORWARD, MODE_BACKWARD, MODE_INTERPOLATE};          int order[4] = {MODE_DIRECT, MODE_FORWARD, MODE_BACKWARD, MODE_INTERPOLATE};
486    
487          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
488                  = /*VopFlags & XVID_VOP_ALTERNATESCAN ? scan_tables[2] : */scan_tables[0];                  = /*VopFlags & XVID_VOP_ALTERNATESCAN ? scan_tables[2] : */scan_tables[0];
489            *Data_f->cbp = *Data_b->cbp = *Data_i->cbp = *Data_d->cbp = 63;
490    
491          f_rd = b_rd = i_rd = d_rd = best_rd = 256*4096;          f_rd = b_rd = i_rd = d_rd = best_rd = 256*4096;
492    
# Line 500  Line 514 
514                  }                  }
515          }          }
516    
517            for(i = 0; i < 4; i++)
518                    if (get_sad_for_mode(order[i], Data_d, Data_b, Data_f, Data_i) < 2*best_sad)
519                            no_of_checks++;
520    
521            if (no_of_checks > 1) {
522          /* evaluate cost of all modes */          /* evaluate cost of all modes */
523          for (i = 0; i < 4; i++) {                  for (i = 0; i < no_of_checks; i++) {
524                  int rd;                  int rd;
525                            if (2*best_sad < get_sad_for_mode(order[i], Data_d, Data_b, Data_f, Data_i))
526                                    break; /* further SADs are too big */
527    
528                  switch (order[i]) {                  switch (order[i]) {
529                  case MODE_DIRECT:                  case MODE_DIRECT:
# Line 524  Line 545 
545                          best_rd = rd;                          best_rd = rd;
546                  }                  }
547          }          }
548            } else {
549                    /* only 1 mode is below the threshold */
550                    mode = order[0];
551                    best_rd = 0;
552            }
553    
554          pMB->sad16 = best_rd;          pMB->sad16 = best_rd;
555          pMB->mode = mode;          pMB->mode = mode;
# Line 576  Line 602 
602                  }                  }
603                  pMB->mvs[0] = *Data_f->currentMV;                  pMB->mvs[0] = *Data_f->currentMV;
604                  pMB->cbp = *Data_f->cbp;                  pMB->cbp = *Data_f->cbp;
605                    pMB->b_mvs[0] = *Data_b->currentMV; /* hint for future searches */
606                  break;                  break;
607    
608          case MODE_BACKWARD:          case MODE_BACKWARD:
# Line 591  Line 618 
618                  }                  }
619                  pMB->b_mvs[0] = *Data_b->currentMV;                  pMB->b_mvs[0] = *Data_b->currentMV;
620                  pMB->cbp = *Data_b->cbp;                  pMB->cbp = *Data_b->cbp;
621                    pMB->mvs[0] = *Data_f->currentMV; /* hint for future searches */
622                  break;                  break;
623    
624    

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

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