[svn] / trunk / xvidcore / src / prediction / mbprediction.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/prediction/mbprediction.c

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

revision 3, Fri Mar 8 02:46:11 2002 UTC revision 252, Sun Jun 30 10:46:29 2002 UTC
# Line 42  Line 42 
42    *                                                                            *    *                                                                            *
43    *  Revision history:                                                         *    *  Revision history:                                                         *
44    *                                                                            *    *                                                                            *
45      *  29.06.2002 predict_acdc() bounding                                        *
46    *  12.12.2001 improved calc_acdc_prediction; removed need for memcpy         *    *  12.12.2001 improved calc_acdc_prediction; removed need for memcpy         *
47    *  15.12.2001 moved pmv displacement to motion estimation                    *    *  15.12.2001 moved pmv displacement to motion estimation                    *
48    *  30.11.2001 mmx cbp support                                                *    *  30.11.2001 mmx cbp support                                                *
# Line 59  Line 60 
60  #define DIV_DIV(A,B)    ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) )  #define DIV_DIV(A,B)    ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) )
61    
62    
63  static int __inline rescale(int predict_quant, int current_quant, int coeff)  static int __inline
64    rescale(int predict_quant,
65                    int current_quant,
66                    int coeff)
67  {  {
68          return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant), (current_quant)) : 0;          return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
69                                                                      (current_quant)) : 0;
70  }  }
71    
72    
# Line 77  Line 82 
82  */  */
83    
84    
85  void predict_acdc(MACROBLOCK *pMBs,  void
86                                  uint32_t x, uint32_t y, uint32_t mb_width,  predict_acdc(MACROBLOCK * pMBs,
87                             uint32_t x,
88                             uint32_t y,
89                             uint32_t mb_width,
90                                  uint32_t block,                                  uint32_t block,
91                                  int16_t qcoeff[64],                                  int16_t qcoeff[64],
92                                  uint32_t current_quant,                                  uint32_t current_quant,
93                                  int32_t iDcScaler,                                  int32_t iDcScaler,
94                                  int16_t predictors[8])                           int16_t predictors[8],
95                            const int bound)
96    
97  {  {
98            const int mbpos = (y * mb_width) + x;
99      int16_t *left, *top, *diag, *current;      int16_t *left, *top, *diag, *current;
100    
101      int32_t left_quant = current_quant;      int32_t left_quant = current_quant;
# Line 104  Line 115 
115    
116          // left macroblock          // left macroblock
117    
118      if(x && (pMBs[index - 1].mode == MODE_INTRA          if (x && mbpos >= bound + 1  &&
119                  || pMBs[index - 1].mode == MODE_INTRA_Q)) {                  (pMBs[index - 1].mode == MODE_INTRA ||
120                     pMBs[index - 1].mode == MODE_INTRA_Q)) {
121    
122                  left = pMBs[index - 1].pred_values[0];                  left = pMBs[index - 1].pred_values[0];
123                  left_quant = pMBs[index - 1].quant;                  left_quant = pMBs[index - 1].quant;
124                  //DEBUGI("LEFT", *(left+MBPRED_SIZE));                  //DEBUGI("LEFT", *(left+MBPRED_SIZE));
125          }          }
   
126          // top macroblock          // top macroblock
127    
128          if(y && (pMBs[index - mb_width].mode == MODE_INTRA          if (mbpos >= bound + (int)mb_width &&
129                  || pMBs[index - mb_width].mode == MODE_INTRA_Q)) {                  (pMBs[index - mb_width].mode == MODE_INTRA ||
130                     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
131    
132                  top = pMBs[index - mb_width].pred_values[0];                  top = pMBs[index - mb_width].pred_values[0];
133                  top_quant = pMBs[index - mb_width].quant;                  top_quant = pMBs[index - mb_width].quant;
134      }      }
   
135          // diag macroblock          // diag macroblock
136    
137          if(x && y && (pMBs[index - 1 - mb_width].mode == MODE_INTRA          if (x && mbpos >= bound + (int)mb_width + 1 &&
138                  || pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {                  (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
139                     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
140    
141                  diag = pMBs[index - 1 - mb_width].pred_values[0];                  diag = pMBs[index - 1 - mb_width].pred_values[0];
142          }          }
# Line 204  Line 216 
216      if(ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0])) {      if(ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0])) {
217                  *acpred_direction = 1;             // vertical                  *acpred_direction = 1;             // vertical
218                  predictors[0] = DIV_DIV(pTop[0], iDcScaler);                  predictors[0] = DIV_DIV(pTop[0], iDcScaler);
219                  for (i = 1; i < 8; i++)                  for (i = 1; i < 8; i++) {
                 {  
220                          predictors[i] = rescale(top_quant, current_quant, pTop[i]);                          predictors[i] = rescale(top_quant, current_quant, pTop[i]);
221                  }                  }
222          }          } else {
         else  
         {  
223                  *acpred_direction = 2;             // horizontal                  *acpred_direction = 2;             // horizontal
224                  predictors[0] = DIV_DIV(pLeft[0], iDcScaler);                  predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
225                  for (i = 1; i < 8; i++)                  for (i = 1; i < 8; i++) {
                 {  
226                          predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);                          predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
227                  }                  }
228          }          }
# Line 226  Line 234 
234  */  */
235    
236    
237  void add_acdc(MACROBLOCK *pMB,  void
238    add_acdc(MACROBLOCK * pMB,
239                                  uint32_t block,                                  uint32_t block,
240                                  int16_t dct_codes[64],                                  int16_t dct_codes[64],
241                                  uint32_t iDcScaler,                                  uint32_t iDcScaler,
# Line 236  Line 245 
245          int16_t * pCurrent = pMB->pred_values[block];          int16_t * pCurrent = pMB->pred_values[block];
246          uint32_t i;          uint32_t i;
247    
248            DPRINTF(DPRINTF_COEFF,"predictor[0] %i", predictors[0]);
249    
250          dct_codes[0] += predictors[0];  // dc prediction          dct_codes[0] += predictors[0];  // dc prediction
251          pCurrent[0] = dct_codes[0] * iDcScaler;          pCurrent[0] = dct_codes[0] * iDcScaler;
252    
253          if (acpred_direction == 1)          if (acpred_direction == 1) {
254          {                  for (i = 1; i < 8; i++) {
                 for (i = 1; i < 8; i++)  
                 {  
255                          int level = dct_codes[i] + predictors[i];                          int level = dct_codes[i] + predictors[i];
256    
257                            DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i, predictors[i]);
258    
259                          dct_codes[i] = level;                          dct_codes[i] = level;
260                          pCurrent[i] = level;                          pCurrent[i] = level;
261                          pCurrent[i+7] = dct_codes[i*8];                          pCurrent[i+7] = dct_codes[i*8];
262                  }                  }
263          }          } else if (acpred_direction == 2) {
264          else if (acpred_direction == 2)                  for (i = 1; i < 8; i++) {
         {  
                 for (i = 1; i < 8; i++)  
                 {  
265                          int level = dct_codes[i*8] + predictors[i];                          int level = dct_codes[i*8] + predictors[i];
266                            DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i*8, predictors[i]);
267    
268                          dct_codes[i*8] = level;                          dct_codes[i*8] = level;
269                          pCurrent[i+7] = level;                          pCurrent[i+7] = level;
270                          pCurrent[i] = dct_codes[i];                          pCurrent[i] = dct_codes[i];
271                  }                  }
272          }          } else {
273          else                  for (i = 1; i < 8; i++) {
         {  
                 for (i = 1; i < 8; i++)  
                 {  
274                          pCurrent[i] = dct_codes[i];                          pCurrent[i] = dct_codes[i];
275                          pCurrent[i+7] = dct_codes[i*8];                          pCurrent[i+7] = dct_codes[i*8];
276                  }                  }
# Line 284  Line 292 
292                  S2 = sum of all qcoeff                  S2 = sum of all qcoeff
293          */          */
294    
295  uint32_t calc_acdc(MACROBLOCK *pMB,  uint32_t
296    calc_acdc(MACROBLOCK * pMB,
297                                  uint32_t block,                                  uint32_t block,
298                                  int16_t qcoeff[64],                                  int16_t qcoeff[64],
299                                  uint32_t iDcScaler,                                  uint32_t iDcScaler,
# Line 307  Line 316 
316    
317          qcoeff[0] = qcoeff[0] - predictors[0];          qcoeff[0] = qcoeff[0] - predictors[0];
318    
319          if (pMB->acpred_directions[block] == 1)          if (pMB->acpred_directions[block] == 1) {
         {  
320                  for(i = 1; i < 8; i++) {                  for(i = 1; i < 8; i++) {
321                          int16_t level;                          int16_t level;
322    
# Line 318  Line 326 
326                          S1 += ABS(level);                          S1 += ABS(level);
327                          predictors[i] = level;                          predictors[i] = level;
328                  }                  }
329          }          } else                                          // acpred_direction == 2
     else // acpred_direction == 2  
330          {          {
331                  for(i = 1; i < 8; i++) {                  for(i = 1; i < 8; i++) {
332                          int16_t level;                          int16_t level;
# Line 340  Line 347 
347    
348  /* apply predictors[] to qcoeff */  /* apply predictors[] to qcoeff */
349    
350  void apply_acdc(MACROBLOCK *pMB,  void
351    apply_acdc(MACROBLOCK * pMB,
352                                  uint32_t block,                                  uint32_t block,
353                                  int16_t qcoeff[64],                                  int16_t qcoeff[64],
354                                  int16_t predictors[8])                                  int16_t predictors[8])
355  {  {
356          uint32_t i;          uint32_t i;
357    
358          if (pMB->acpred_directions[block] == 1)          if (pMB->acpred_directions[block] == 1) {
359          {                  for (i = 1; i < 8; i++) {
                 for(i = 1; i < 8; i++)  
                 {  
360                          qcoeff[i] = predictors[i];                          qcoeff[i] = predictors[i];
361                  }                  }
362          }          } else {
363      else                  for (i = 1; i < 8; i++) {
         {  
                 for(i = 1; i < 8; i++)  
                 {  
364                          qcoeff[i*8] = predictors[i];                          qcoeff[i*8] = predictors[i];
365                  }                  }
366      }      }
367  }  }
368    
369    
370  void MBPrediction(MBParam *pParam, uint32_t x, uint32_t y,  void
371                                    uint32_t mb_width, int16_t qcoeff[][64], MACROBLOCK *mbs)  MBPrediction(FRAMEINFO * frame,
372                             uint32_t x,
373                             uint32_t y,
374                             uint32_t mb_width,
375                             int16_t qcoeff[6 * 64])
376  {  {
377    
378      int32_t j;      int32_t j;
379          int32_t iDcScaler, iQuant = pParam->quant;          int32_t iDcScaler, iQuant = frame->quant;
380          int32_t S = 0;          int32_t S = 0;
381          int16_t predictors[6][8];          int16_t predictors[6][8];
382    
383      MACROBLOCK *pMB = &mbs[x + y * mb_width];          MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
384    
385      if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {      if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
386    
387                  for(j = 0; j < 6; j++)                  for (j = 0; j < 6; j++) {
                 {  
388                          iDcScaler = get_dc_scaler(iQuant, (j < 4) ? 1 : 0);                          iDcScaler = get_dc_scaler(iQuant, (j < 4) ? 1 : 0);
389    
390                          predict_acdc(mbs, x, y, mb_width, j, qcoeff[j], iQuant, iDcScaler, predictors[j]);                          predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
391                          S += calc_acdc(pMB, j, qcoeff[j], iDcScaler, predictors[j]);                                                   iQuant, iDcScaler, predictors[j], 0);
392    
393                            S += calc_acdc(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
394    
395                  }                  }
396    
397                  if (S < 0)              // dont predict                  if (S < 0)              // dont predict
398                  {                  {
399                          for(j = 0; j < 6; j++)                          for (j = 0; j < 6; j++) {
                         {  
400                                  pMB->acpred_directions[j] = 0;                                  pMB->acpred_directions[j] = 0;
401                          }                          }
402                  }                  } else {
403                  else                          for (j = 0; j < 6; j++) {
404                  {                                  apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
                         for(j = 0; j < 6; j++)  
                         {  
                                  apply_acdc(pMB, j, qcoeff[j], predictors[j]);  
405                          }                          }
406                  }                  }
407                  pMB->cbp = calc_cbp(qcoeff);                  pMB->cbp = calc_cbp(qcoeff);
408          }          }
409    
410    }
411    
412    
413    
414    
415    /*
416      get_pmvdata2: get_pmvdata with bounding
417    */
418    #define OFFSET(x,y,stride)   ((x)+((y)*(stride)))
419    
420    int
421    get_pmvdata2(const MACROBLOCK * const pMBs,
422                            const uint32_t x,
423                            const uint32_t y,
424                            const uint32_t x_dim,
425                            const uint32_t block,
426                            VECTOR * const pmv,
427                            int32_t * const psad,
428                            const int bound)
429    {
430            const int mbpos = OFFSET(x, y ,x_dim);
431    
432            /*
433             * pmv are filled with:
434             *  [0]: Median (or whatever is correct in a special case)
435             *  [1]: left neighbour
436             *  [2]: top neighbour
437             *  [3]: topright neighbour
438             * psad are filled with:
439             *  [0]: minimum of [1] to [3]
440             *  [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
441             *  [2]: top neighbour's SAD
442             *  [3]: topright neighbour's SAD
443             */
444    
445            int xin1, xin2, xin3;
446            int yin1, yin2, yin3;
447            int vec1, vec2, vec3;
448    
449            int pos1, pos2, pos3;
450            int num_cand = 0;               // number of candidates
451            int last_cand;                  // last candidate
452    
453            uint32_t index = x + y * x_dim;
454            const VECTOR zeroMV = { 0, 0 };
455    
456            /*
457             * MODE_INTER, vm18 page 48
458             * MODE_INTER4V vm18 page 51
459             *
460             *  (x,y-1)      (x+1,y-1)
461             *  [   |   ]    [   |   ]
462             *  [ 2 | 3 ]    [ 2 |   ]
463             *
464             *  (x-1,y)      (x,y)        (x+1,y)
465             *  [   | 1 ]    [ 0 | 1 ]    [ 0 |   ]
466             *  [   | 3 ]    [ 2 | 3 ]    [   |   ]
467             */
468    
469            switch (block) {
470            case 0:
471                    xin1 = x - 1;
472                    yin1 = y;
473                    vec1 = 1;                               /* left */
474                    xin2 = x;
475                    yin2 = y - 1;
476                    vec2 = 2;                               /* top */
477                    xin3 = x + 1;
478                    yin3 = y - 1;
479                    vec3 = 2;                               /* top right */
480                    break;
481            case 1:
482                    xin1 = x;
483                    yin1 = y;
484                    vec1 = 0;
485                    xin2 = x;
486                    yin2 = y - 1;
487                    vec2 = 3;
488                    xin3 = x + 1;
489                    yin3 = y - 1;
490                    vec3 = 2;
491                    break;
492            case 2:
493                    xin1 = x - 1;
494                    yin1 = y;
495                    vec1 = 3;
496                    xin2 = x;
497                    yin2 = y;
498                    vec2 = 0;
499                    xin3 = x;
500                    yin3 = y;
501                    vec3 = 1;
502                    break;
503            default:
504                    xin1 = x;
505                    yin1 = y;
506                    vec1 = 2;
507                    xin2 = x;
508                    yin2 = y;
509                    vec2 = 0;
510                    xin3 = x;
511                    yin3 = y;
512                    vec3 = 1;
513            }
514    
515            pos1 = OFFSET(xin1, yin1, x_dim);
516            pos2 = OFFSET(xin2, yin2, x_dim);
517            pos3 = OFFSET(xin3, yin3, x_dim);
518    
519            // left
520            if (xin1 < 0 || pos1 < bound) {
521                    pmv[1] = zeroMV;
522                    psad[1] = MV_MAX_ERROR;
523            } else {
524                    pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
525                    psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1];
526                    num_cand++;
527                    last_cand = 1;
528            }
529    
530            // top
531            if (yin2 < 0 || pos2 < bound) {
532                    pmv[2] = zeroMV;
533                    psad[2] = MV_MAX_ERROR;
534            } else {
535                    pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
536                    psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2];
537                    num_cand++;
538                    last_cand = 2;
539            }
540    
541    
542            // top right
543            if (yin3 < 0 || pos3 < bound || xin3 >= (int)x_dim) {
544                    pmv[3] = zeroMV;
545                    psad[3] = MV_MAX_ERROR;
546                    //DPRINTF(DPRINTF_MV, "top-right");
547            } else {
548                    pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
549                    psad[3] = pMBs[xin2 + yin2 * x_dim].sad8[vec3];
550                    num_cand++;
551                    last_cand = 3;
552            }
553    
554            if (num_cand == 1)
555            {
556                    /* DPRINTF(DPRINTF_MV,"cand0=(%i,%i), cand1=(%i,%i) cand2=(%i,%i) last=%i",
557                            pmv[1].x, pmv[1].y,
558                            pmv[2].x, pmv[2].y,
559                            pmv[3].x, pmv[3].y, last_cand - 1);
560                    */
561    
562                    pmv[0] = pmv[last_cand];
563                    psad[0] = psad[last_cand];
564                    return 0;
565            }
566    
567            /* DPRINTF(DPRINTF_MV,"cand0=(%i,%i), cand1=(%i,%i) cand2=(%i,%i)",
568                    pmv[1].x, pmv[1].y,
569                    pmv[2].x, pmv[2].y,
570                    pmv[3].x, pmv[3].y);*/
571    
572            if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
573                    pmv[0] = pmv[1];
574                    psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
575                    return 1;
576            }
577    
578            /* median,minimum */
579    
580            pmv[0].x =
581                    MIN(MAX(pmv[1].x, pmv[2].x),
582                            MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
583            pmv[0].y =
584                    MIN(MAX(pmv[1].y, pmv[2].y),
585                            MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
586            psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
587    
588            return 0;
589  }  }

Legend:
Removed from v.3  
changed lines
  Added in v.252

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