motion.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:5k
- /*
- File: motion.cc
- Description:
- Motion Vectors
- */
- #ifdef __GNUG__
- #pragma implementation
- #endif
- #include <stdio.h>
- #include <fstream.h>
- #include <sys/time.h>
- #include "athread.hh"
- #include "error.hh"
- #include "debug.hh"
- #include "util.hh"
- #include "sync.hh"
- #include "mpeg2const.hh"
- #include "mpeg2buff.hh"
- #include "videoconst.hh"
- #include "display.hh"
- #include "idct.hh"
- #include "vstream.hh"
- #include "layerdata.hh"
- #include "global.hh"
- inline void calcMV(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector);
- void LayerData::motion_vectors(int PMV[2][2][2], int dmvector[2], int mv_field_sel[2][2],
- int s, int mv_count, int mv_format, int h_r_size, int v_r_size, int dmv, int mvscale){
- if (mv_count==1){
- if (mv_format==MV_FIELD && !dmv){
- mv_field_sel[1][s] = mv_field_sel[0][s] = input->getbits(1);
- #ifdef TRACE
- if (trace){
- printf("motion_vertical_field_select[][%d] (%d): %dn",s,
- mv_field_sel[0][s],mv_field_sel[0][s]);
- }
- #endif
- }
- motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
- /* update other motion vector predictors */
- PMV[1][s][0] = PMV[0][s][0];
- PMV[1][s][1] = PMV[0][s][1];
- }
- else {
- mv_field_sel[0][s] = input->getbits(1);
- #ifdef TRACE
- if (trace){
- printf("motion_vertical_field_select[0][%d] (%d): %dn",s,
- mv_field_sel[0][s],mv_field_sel[0][s]);
- }
- #endif
- motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
- if (fault)
- return;
- mv_field_sel[1][s] = input->getbits(1);
- #ifdef TRACE
- if (trace){
- printf("motion_vertical_field_select[1][%d] (%d): %dn",s,
- mv_field_sel[1][s],mv_field_sel[1][s]);
- }
- #endif
- motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
- if (fault)
- return;
- }
- }
- /* get and decode motion vector and differential motion vector */
- void LayerData::motion_vector(int *PMV, int *dmvector, int h_r_size, int v_r_size,
- int dmv, int mvscale, int full_pel_vector){
- /*
- int dmv, * MPEG-2 only: get differential motion vectors *
- int mvscale, * MPEG-2 only: field vector in frame pic *
- int full_pel_vector * MPEG-1 only *
- */
- int motion_code = getMV();
- if (fault)
- return;
- int motion_r = (h_r_size!=0 && motion_code!=0) ? input->getbits(h_r_size) : 0;
- #ifdef TRACE
- if (trace){
- if (h_r_size!=0 && motion_code!=0){
- printf("motion_residual (");
- printbits(motion_r,h_r_size,h_r_size);
- printf("): %dn",motion_r);
- }
- }
- #endif
- calcMV(&PMV[0],h_r_size,motion_code,motion_r,full_pel_vector);
- if (dmv) dmvector[0] = getDMV();
- motion_code = getMV();
- if (fault)
- return;
- motion_r = (v_r_size!=0 && motion_code!=0) ? input->getbits(v_r_size) : 0;
- #ifdef TRACE
- if (trace){
- if (v_r_size!=0 && motion_code!=0){
- printf("motion_residual (");
- printbits(motion_r,v_r_size,v_r_size);
- printf("): %dn",motion_r);
- }
- }
- #endif
- if (mvscale) PMV[1] >>= 1; /* DIV 2 */
- calcMV(&PMV[1],v_r_size,motion_code,motion_r,full_pel_vector);
- if (mvscale) PMV[1] <<= 1;
- if (dmv) dmvector[1] = getDMV();
- #ifdef TRACE
- if (trace)
- printf("PMV = %d,%dn",PMV[0],PMV[1]);
- #endif
- }
- /* calculate motion vector component */
- inline void calcMV(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector){
- int lim = 16<<r_size;
- int vec = full_pel_vector ? (*pred >> 1) : (*pred);
- if (motion_code>0){
- vec+= ((motion_code-1)<<r_size) + motion_r + 1;
- if (vec>=lim) vec-= lim + lim;
- }
- else if (motion_code<0){
- vec-= ((-motion_code-1)<<r_size) + motion_r + 1;
- if (vec<-lim) vec+= lim + lim;
- }
- *pred = full_pel_vector ? (vec<<1) : vec;
- }
- void LayerData::calc_DMV(int DMV[][2], int *dmvector, int mvx, int mvy){
- /*
- int *dmvector, * differential motion vector *
- int mvx, int mvy * decoded mv components (always in field format) *
- */
- if (pict_struct==FRAME_PICTURE){
- if (topfirst){
- /* vector for prediction of top field from bottom field */
- DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
- DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
- /* vector for prediction of bottom field from top field */
- DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
- DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
- }
- else {
- /* vector for prediction of top field from bottom field */
- DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
- DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
- /* vector for prediction of bottom field from top field */
- DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
- DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
- }
- }
- else {
- /* vector for prediction from field of opposite 'parity' */
- DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
- DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
- /* correct for vertical field shift */
- if (pict_struct==TOP_FIELD) DMV[0][1]--;
- else DMV[0][1]++;
- }
- }