motion_comp.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "../encoder.h"
  2. #include "../utils/mbfunctions.h"
  3. #include "../image/interpolate8x8.h"
  4. #include "../utils/timer.h"
  5. #define ABS(X) (((X)>0)?(X):-(X))
  6. #define SIGN(X) (((X)>0)?1:-1)
  7. static __inline void compensate8x8_halfpel(
  8. int16_t * const dct_codes,
  9. uint8_t * const cur,
  10. const uint8_t * const ref,
  11. const uint8_t * const refh,
  12. const uint8_t * const refv,
  13. const uint8_t * const refhv,
  14. const uint32_t x, const uint32_t y,
  15. const int32_t dx,  const int dy,
  16. const uint32_t stride)
  17. {
  18. int32_t ddx,ddy;
  19. switch ( ((dx&1)<<1) + (dy&1) )   // ((dx%2)?2:0)+((dy%2)?1:0)
  20.     {
  21.     case 0 :
  22. ddx = dx/2;
  23. ddy = dy/2;
  24. transfer_8to16sub(dct_codes, cur + y*stride + x, 
  25. ref + (y+ddy)*stride + x+ddx, stride);
  26. break;
  27.     case 1 :
  28. ddx = dx/2;
  29. ddy = (dy-1)/2;
  30. transfer_8to16sub(dct_codes, cur + y*stride + x, 
  31. refv + (y+ddy)*stride + x+ddx, stride);
  32. break;
  33.     case 2 :
  34. ddx = (dx-1)/2;
  35. ddy = dy/2;
  36. transfer_8to16sub(dct_codes, cur + y*stride + x, 
  37. refh + (y+ddy)*stride + x+ddx, stride);
  38. break;
  39. default : // case 3:
  40. ddx = (dx-1)/2;
  41. ddy = (dy-1)/2;
  42. transfer_8to16sub(dct_codes, cur + y*stride + x, 
  43. refhv + (y+ddy)*stride + x+ddx, stride);
  44. break;
  45.     }
  46. }
  47. void MBMotionCompensation(
  48. MACROBLOCK * const mb,
  49. const uint32_t i,
  50. const uint32_t j,
  51. const IMAGE * const ref,
  52. const IMAGE * const refh,
  53. const IMAGE * const refv,
  54. const IMAGE * const refhv,
  55. IMAGE * const cur,
  56. int16_t *dct_codes,
  57. const uint32_t width, 
  58. const uint32_t height,
  59. const uint32_t edged_width,
  60. const uint32_t rounding)
  61. {
  62. static const uint32_t roundtab[16] =
  63. { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 };
  64. if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
  65. {
  66. int32_t dx = mb->mvs[0].x;
  67. int32_t dy = mb->mvs[0].y;
  68. compensate8x8_halfpel(&dct_codes[0*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  69.       16*i,     16*j,     dx, dy, edged_width);
  70. compensate8x8_halfpel(&dct_codes[1*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  71.       16*i + 8, 16*j,     dx, dy, edged_width);
  72. compensate8x8_halfpel(&dct_codes[2*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  73.       16*i,     16*j + 8, dx, dy, edged_width);
  74. compensate8x8_halfpel(&dct_codes[3*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  75.       16*i + 8, 16*j + 8, dx, dy, edged_width);
  76. dx = (dx & 3) ? (dx >> 1) | 1 : dx / 2;
  77. dy = (dy & 3) ? (dy >> 1) | 1 : dy / 2;
  78. /* uv-image-based compensation
  79.    compensate8x8_halfpel(dct_codes[4], cur->u, ref->u, refh->u, refv->u, refhv->u,
  80.    8*i, 8*j, dx, dy, edged_width/2);
  81.    compensate8x8_halfpel(dct_codes[5], cur->v, ref->v, refh->v, refv->v, refhv->v,
  82.    8*i, 8*j, dx, dy, edged_width/2); */
  83. /* uv-block-based compensation */
  84. interpolate8x8_switch(refv->u, ref->u, 8*i, 8*j, dx, dy, edged_width/2, rounding);
  85. transfer_8to16sub(&dct_codes[4*64], 
  86.   cur->u + 8*j*edged_width/2 + 8*i, 
  87.   refv->u + 8*j*edged_width/2 + 8*i, edged_width/2);
  88. interpolate8x8_switch(refv->v, ref->v, 8*i, 8*j, dx, dy, edged_width/2, rounding);
  89. transfer_8to16sub(&dct_codes[5*64], 
  90.   cur->v + 8*j*edged_width/2 + 8*i, 
  91.   refv->v + 8*j*edged_width/2 + 8*i, edged_width/2);
  92. }
  93. else // mode == MODE_INTER4V
  94. {
  95. int32_t sum, dx, dy;
  96. compensate8x8_halfpel(&dct_codes[0*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  97.       16*i,     16*j,     mb->mvs[0].x, mb->mvs[0].y, edged_width);
  98. compensate8x8_halfpel(&dct_codes[1*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  99.       16*i + 8, 16*j,     mb->mvs[1].x, mb->mvs[1].y, edged_width);
  100. compensate8x8_halfpel(&dct_codes[2*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  101.       16*i,     16*j + 8, mb->mvs[2].x, mb->mvs[2].y, edged_width);
  102. compensate8x8_halfpel(&dct_codes[3*64], cur->y, ref->y, refh->y, refv->y, refhv->y,
  103.       16*i + 8, 16*j + 8, mb->mvs[3].x, mb->mvs[3].y, edged_width);
  104. sum = mb->mvs[0].x + mb->mvs[1].x + mb->mvs[2].x + mb->mvs[3].x;
  105. dx = (sum ? SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) : 0);
  106. sum = mb->mvs[0].y + mb->mvs[1].y + mb->mvs[2].y + mb->mvs[3].y;
  107. dy = (sum ? SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) : 0);
  108. /* uv-image-based compensation
  109.    compensate8x8_halfpel(dct_codes[4], cur->u, ref->u, refh->u, refv->u, refhv->u,
  110.    8*i, 8*j, dx, dy, edged_width/2);
  111.    compensate8x8_halfpel(dct_codes[5], cur->v, ref->v, refh->v, refv->v, refhv->v,
  112.    8*i, 8*j, dx, dy, edged_width/2); */
  113. /* uv-block-based compensation */
  114. interpolate8x8_switch(refv->u, ref->u, 8*i, 8*j, dx, dy, edged_width/2, rounding);
  115. transfer_8to16sub(&dct_codes[4*64], 
  116.   cur->u + 8*j*edged_width/2 + 8*i, 
  117.   refv->u + 8*j*edged_width/2 + 8*i, edged_width/2);
  118. interpolate8x8_switch(refv->v, ref->v, 8*i, 8*j, dx, dy, edged_width/2, rounding);
  119. transfer_8to16sub(&dct_codes[5*64], 
  120.   cur->v + 8*j*edged_width/2 + 8*i, 
  121.   refv->v + 8*j*edged_width/2 + 8*i, edged_width/2);
  122. }
  123. }