motion.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:5k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.    File: motion.cc
  3.    Description:
  4.    Motion Vectors
  5. */
  6. #ifdef __GNUG__
  7. #pragma implementation
  8. #endif
  9. #include <stdio.h>
  10. #include <fstream.h>
  11. #include <sys/time.h>
  12. #include "athread.hh"
  13. #include "error.hh"
  14. #include "debug.hh"
  15. #include "util.hh"
  16. #include "sync.hh"
  17. #include "mpeg2const.hh"
  18. #include "mpeg2buff.hh"
  19. #include "videoconst.hh"
  20. #include "display.hh"
  21. #include "idct.hh"
  22. #include "vstream.hh"
  23. #include "layerdata.hh"
  24. #include "global.hh"
  25. inline void calcMV(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector);
  26. void LayerData::motion_vectors(int PMV[2][2][2], int dmvector[2], int mv_field_sel[2][2],
  27. int s, int mv_count, int mv_format, int h_r_size, int v_r_size, int dmv, int mvscale){
  28.   if (mv_count==1){
  29.     if (mv_format==MV_FIELD && !dmv){
  30.       mv_field_sel[1][s] = mv_field_sel[0][s] = input->getbits(1);
  31. #ifdef TRACE
  32.       if (trace){
  33.         printf("motion_vertical_field_select[][%d] (%d): %dn",s,
  34.           mv_field_sel[0][s],mv_field_sel[0][s]);
  35.       }
  36. #endif
  37.     }
  38.     motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
  39.     /* update other motion vector predictors */
  40.     PMV[1][s][0] = PMV[0][s][0];
  41.     PMV[1][s][1] = PMV[0][s][1];
  42.   }
  43.   else {
  44.     mv_field_sel[0][s] = input->getbits(1);
  45. #ifdef TRACE
  46.     if (trace){
  47.       printf("motion_vertical_field_select[0][%d] (%d): %dn",s,
  48.         mv_field_sel[0][s],mv_field_sel[0][s]);
  49.     }
  50. #endif
  51.     motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
  52.     if (fault)
  53.       return;
  54.     mv_field_sel[1][s] = input->getbits(1);
  55. #ifdef TRACE
  56.     if (trace){
  57.       printf("motion_vertical_field_select[1][%d] (%d): %dn",s,
  58.         mv_field_sel[1][s],mv_field_sel[1][s]);
  59.     }
  60. #endif
  61.     motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
  62.     if (fault)
  63.       return;
  64.   }
  65. }
  66. /* get and decode motion vector and differential motion vector */
  67. void LayerData::motion_vector(int *PMV, int *dmvector, int h_r_size, int v_r_size,
  68. int dmv, int mvscale, int full_pel_vector){
  69. /*
  70. int dmv, * MPEG-2 only: get differential motion vectors *
  71. int mvscale, * MPEG-2 only: field vector in frame pic *
  72. int full_pel_vector * MPEG-1 only *
  73. */
  74.   int motion_code = getMV();
  75.   if (fault)
  76.     return;
  77.   int motion_r = (h_r_size!=0 && motion_code!=0) ? input->getbits(h_r_size) : 0;
  78. #ifdef TRACE
  79.   if (trace){
  80.     if (h_r_size!=0 && motion_code!=0){
  81.       printf("motion_residual (");
  82.       printbits(motion_r,h_r_size,h_r_size);
  83.       printf("): %dn",motion_r);
  84.     }
  85.   }
  86. #endif
  87.   calcMV(&PMV[0],h_r_size,motion_code,motion_r,full_pel_vector);
  88.   if (dmv) dmvector[0] = getDMV();
  89.   motion_code = getMV();
  90.   if (fault)
  91.     return;
  92.   motion_r = (v_r_size!=0 && motion_code!=0) ? input->getbits(v_r_size) : 0;
  93. #ifdef TRACE
  94.   if (trace){
  95.     if (v_r_size!=0 && motion_code!=0){
  96.       printf("motion_residual (");
  97.       printbits(motion_r,v_r_size,v_r_size);
  98.       printf("): %dn",motion_r);
  99.     }
  100.   }
  101. #endif
  102.   if (mvscale) PMV[1] >>= 1; /* DIV 2 */
  103.   calcMV(&PMV[1],v_r_size,motion_code,motion_r,full_pel_vector);
  104.   if (mvscale) PMV[1] <<= 1;
  105.   if (dmv) dmvector[1] = getDMV();
  106. #ifdef TRACE
  107.   if (trace)
  108.     printf("PMV = %d,%dn",PMV[0],PMV[1]);
  109. #endif
  110. }
  111. /* calculate motion vector component */
  112. inline void calcMV(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector){
  113.   int lim = 16<<r_size;
  114.   int vec = full_pel_vector ? (*pred >> 1) : (*pred);
  115.   if (motion_code>0){
  116.     vec+= ((motion_code-1)<<r_size) + motion_r + 1;
  117.     if (vec>=lim) vec-= lim + lim;
  118.   }
  119.   else if (motion_code<0){
  120.     vec-= ((-motion_code-1)<<r_size) + motion_r + 1;
  121.     if (vec<-lim) vec+= lim + lim;
  122.   }
  123.   *pred = full_pel_vector ? (vec<<1) : vec;
  124. }
  125. void LayerData::calc_DMV(int DMV[][2], int *dmvector, int mvx, int mvy){
  126. /*
  127. int *dmvector, * differential motion vector *
  128. int mvx, int mvy  * decoded mv components (always in field format) *
  129. */
  130.   if (pict_struct==FRAME_PICTURE){
  131.     if (topfirst){
  132.       /* vector for prediction of top field from bottom field */
  133.       DMV[0][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
  134.       DMV[0][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] - 1;
  135.       /* vector for prediction of bottom field from top field */
  136.       DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
  137.       DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
  138.     }
  139.     else {
  140.       /* vector for prediction of top field from bottom field */
  141.       DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
  142.       DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
  143.       /* vector for prediction of bottom field from top field */
  144.       DMV[1][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
  145.       DMV[1][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] + 1;
  146.     }
  147.   }
  148.   else {
  149.     /* vector for prediction from field of opposite 'parity' */
  150.     DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
  151.     DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
  152.     /* correct for vertical field shift */
  153.     if (pict_struct==TOP_FIELD) DMV[0][1]--;
  154.     else                        DMV[0][1]++;
  155.   }
  156. }