📄 motionest.cc
字号:
me.MV[0][1][0] = frameb_mc.pos.x - (i<<1); me.MV[0][1][1] = frameb_mc.pos.y - (j<<1); me.mb_type = MB_FORWARD; me.var = unidir_var_sum( &framef_mc, picture.fwd_rec, &ssmb, eparams.phy_width, 16 ); best_of_kind_me.push_back( me ); me.mb_type = MB_BACKWARD; me.var = unidir_var_sum( &frameb_mc, picture.bwd_rec, &ssmb, eparams.phy_width, 16 ); best_of_kind_me.push_back( me ); me.mb_type = MB_FORWARD|MB_BACKWARD; me.var = bidir_var_sum( &framef_mc, &frameb_mc, picture.fwd_rec, picture.bwd_rec, &ssmb, eparams.phy_width, 16 ); best_of_kind_me.push_back( me ); /* FIELD modes only possible if appropriate picture type is legal */ if (!picture.frame_pred_dct ) { botssmb.mb = ssmb.mb+eparams.phy_width; botssmb.fmb = ssmb.fmb+(eparams.phy_width>>1); botssmb.qmb = ssmb.qmb+(eparams.phy_width>>2); botssmb.umb = ssmb.umb+(eparams.phy_width>>1); botssmb.vmb = ssmb.vmb+(eparams.phy_width>>1); // Forward motion estimates... FieldMotionCands( eparams, picture.fwd_org[0],picture.fwd_rec[0], &ssmb, &botssmb, i,j,picture.sxf,picture.syf, &topfldf_mc, &botfldf_mc, best_fieldmcs); // Backward motion estimates... FieldMotionCands( eparams, picture.bwd_org[0],picture.bwd_rec[0], &ssmb, &botssmb, i,j,picture.sxb,picture.syb, &topfldb_mc, &botfldb_mc, best_fieldmcs); me.motion_type = MC_FIELD; me.MV[0][0][0] = topfldf_mc.pos.x - (i<<1); me.MV[0][0][1] = (topfldf_mc.pos.y<<1) - (j<<1); me.MV[1][0][0] = botfldf_mc.pos.x - (i<<1); me.MV[1][0][1] = (botfldf_mc.pos.y<<1) - (j<<1); me.field_sel[0][0] = topfldf_mc.fieldsel; me.field_sel[1][0] = botfldf_mc.fieldsel; me.MV[0][1][0] = topfldb_mc.pos.x - (i<<1); me.MV[0][1][1] = (topfldb_mc.pos.y<<1) - (j<<1); me.MV[1][1][0] = botfldb_mc.pos.x - (i<<1); me.MV[1][1][1] = (botfldb_mc.pos.y<<1) - (j<<1); me.field_sel[0][1] = topfldb_mc.fieldsel; me.field_sel[1][1] = botfldb_mc.fieldsel; me.mb_type = MB_FORWARD|MB_BACKWARD; me.var = bidir_var_sum( &topfldf_mc, &topfldb_mc, picture.fwd_rec,picture.bwd_rec, &ssmb, eparams.phy_width<<1, 8) + bidir_var_sum( &botfldf_mc, &botfldb_mc, picture.fwd_rec,picture.bwd_rec, &botssmb, eparams.phy_width<<1, 8); best_of_kind_me.push_back( me ); me.mb_type = MB_FORWARD; me.var = unidir_var_sum( &topfldf_mc, picture.fwd_rec, &ssmb, (eparams.phy_width<<1), 8 ) + unidir_var_sum( &botfldf_mc, picture.fwd_rec, &botssmb, (eparams.phy_width<<1), 8 ); best_of_kind_me.push_back( me ); me.mb_type = MB_BACKWARD; me.var = unidir_var_sum( &topfldb_mc, picture.bwd_rec, &ssmb, (eparams.phy_width<<1), 8 ) + unidir_var_sum( &botfldb_mc, picture.bwd_rec, &botssmb, (eparams.phy_width<<1), 8 ); best_of_kind_me.push_back( me ); } }}/* * motion estimation for field pictures * picture: picture object for which MC is to be computed. * mbi: pointer to macroblock info of picture object * mb_row_start: offset in chrominance block of start of this MB's row * * results: * mbi-> * me.mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD * me.MV[][][]: motion vectors (field format) * me.field_sel: top/bottom field * me.motion_type: MC_FIELD, MC_16X8 * */void MacroBlock::FieldME(){ const Picture &picture = ParentPicture(); const EncoderParams &eparams = picture.encparams; int i = TopleftX(); int j = TopleftY(); int w2; uint8_t *toporg, *topref, *botorg, *botref; SubSampledImg ssmb; MotionCand fieldsp_mc, dualp_mc; MotionCand fieldf_mc, fieldb_mc; MotionCand field8uf_mc, field8lf_mc; MotionCand field8ub_mc, field8lb_mc; int intravar, vmc,v0,dmc,dmcfieldi,dmcfield,dmcfieldf,dmcfieldr,dmc8i; int dmc8f,dmc8r; int vmc_dp,dctl_dp; MotionEst me; w2 = eparams.phy_width<<1; /* Fast motion data sits at the end of the luminance buffer */ ssmb.mb = picture.org_img[0] + i + w2*j; ssmb.umb = picture.org_img[1] + ((i>>1)+(w2>>1)*(j>>1)); ssmb.vmb = picture.org_img[2] + ((i>>1)+(w2>>1)*(j>>1)); ssmb.fmb = picture.org_img[0] + eparams.fsubsample_offset+((i>>1)+(w2>>1)*(j>>1)); ssmb.qmb = picture.org_img[0] + eparams.qsubsample_offset+ (i>>2)+(w2>>2)*(j>>2); if (picture.pict_struct==BOTTOM_FIELD) { ssmb.mb += eparams.phy_width; ssmb.umb += (eparams.phy_width >> 1); ssmb.vmb += (eparams.phy_width >> 1); ssmb.fmb += (eparams.phy_width >> 1); ssmb.qmb += (eparams.phy_width >> 2); } pvariance( ssmb.mb, 16, w2, &lum_variance, &lum_mean ); intravar = lum_variance + chrom_var_sum(&ssmb,16,w2); if(picture.pict_type==I_TYPE) { me.mb_type = MB_INTRA; me.var = intravar; } else if (picture.pict_type==P_TYPE) { toporg = picture.fwd_org[0]; topref = picture.fwd_rec[0]; botorg = picture.fwd_org[0]; botref = picture.fwd_rec[0]; if (picture.secondfield) { /* opposite parity field is in same frame */ if (picture.pict_struct==TOP_FIELD) { /* current is top field */ botorg = picture.org_img[0] ; botref = picture.rec_img[0]; } else { /* current is bottom field */ toporg = picture.org_img[0]; topref = picture.rec_img[0]; } } field_estimate(picture, toporg,topref,botorg,botref,&ssmb, i,j,picture.sxf,picture.syf, &fieldf_mc, &field8uf_mc, &field8lf_mc, &fieldsp_mc); dmcfield = fieldf_mc.sad; dmc8f = field8uf_mc.sad + field8lf_mc.sad; dctl_dp = 100000000; /* Suppress compiler warning */ if ( eparams.dualprime && !picture.ipflag) /* generic condition which permits Dual Prime */ { dpfield_estimate(picture, topref,botref,ssmb.mb,i,j, &fieldsp_mc, &dualp_mc, &vmc_dp); dctl_dp = dualp_mc.sad; } /* select between dual prime, field and 16x8 prediction */ if ( eparams.M==1 && !picture.ipflag && dctl_dp<dmc8f && dctl_dp<dmcfield) { /* Dual Prime prediction */ me.motion_type = MC_DMV; dmc = dualp_mc.sad; vmc = vmc_dp; } else if (dmc8f<dmcfield) { /* 16x8 prediction */ me.motion_type = MC_16X8; /* upper and lower half blocks */ vmc = field8uf_mc.var + unidir_pred_var( &field8uf_mc, ssmb.mb, w2, 8); vmc += field8lf_mc.var + unidir_pred_var( &field8lf_mc, ssmb.mb, w2, 8); } else { /* field prediction */ me.motion_type = MC_FIELD; vmc = fieldf_mc.var + unidir_pred_var( &fieldf_mc, ssmb.mb, w2, 16 ); } /* select between intra and non-intra coding */ if ( vmc>intravar && vmc > 12*256) { me.mb_type = MB_INTRA; me.var = intravar; } else { /* zero MV field prediction from same parity ref. field * (not allowed if ipflag is set) */ if (!picture.ipflag) v0 = psumsq(((picture.pict_struct==BOTTOM_FIELD) ? botref : topref) + i + w2*j, ssmb.mb,w2,0,0,16); else v0 = 1234; /* Keep Compiler happy... */ if (picture.ipflag || (4*v0>5*vmc )) { me.mb_type = MB_FORWARD; me.var = vmc; if (me.motion_type==MC_FIELD) { me.MV[0][0][0] = fieldf_mc.pos.x - (i<<1); me.MV[0][0][1] = fieldf_mc.pos.y - (j<<1); me.field_sel[0][0] = fieldf_mc.fieldsel; } else if (me.motion_type==MC_DMV) { /* same parity vector */ me.MV[0][0][0] = fieldsp_mc.pos.x - (i<<1); me.MV[0][0][1] = fieldsp_mc.pos.y - (j<<1); /* opposite parity vector */ me.dualprimeMV[0] = dualp_mc.pos.x; me.dualprimeMV[1] = dualp_mc.pos.y; } else { me.MV[0][0][0] = field8uf_mc.pos.x - (i<<1); me.MV[0][0][1] = field8uf_mc.pos.y - (j<<1); me.MV[1][0][0] = field8lf_mc.pos.x - (i<<1); me.MV[1][0][1] = field8lf_mc.pos.y - ((j+8)<<1); me.field_sel[0][0] = field8uf_mc.fieldsel; me.field_sel[1][0] = field8lf_mc.fieldsel; } } else { /* No MC */ me.mb_type = 0; me.var = v0; me.motion_type = MC_FIELD; me.MV[0][0][0] = 0; me.MV[0][0][1] = 0; me.field_sel[0][0] = (picture.pict_struct==BOTTOM_FIELD); } } } else /* if (pict_type==B_TYPE) */ { /* forward prediction */ field_estimate(picture, picture.fwd_org[0], picture.fwd_rec[0], picture.fwd_org[0], picture.fwd_rec[0], &ssmb,i,j,picture.sxf,picture.syf, &fieldf_mc, &field8uf_mc, &field8lf_mc, &fieldsp_mc); dmcfieldf = fieldf_mc.sad; dmc8f = field8uf_mc.sad + field8lf_mc.sad; /* backward prediction */ field_estimate(picture, picture.bwd_org[0], picture.bwd_rec[0], picture.bwd_org[0], picture.bwd_rec[0], &ssmb,i,j,picture.sxb,picture.syb, &fieldb_mc, &field8ub_mc, &field8lb_mc, &fieldsp_mc); dmcfieldr = fieldb_mc.sad; dmc8r = field8ub_mc.sad + field8lb_mc.sad; /* calculate distances for bidirectional prediction */ /* field */ dmcfieldi = bidir_pred_sad( &fieldf_mc, &fieldb_mc, ssmb.mb, w2, 16); /* 16x8 upper and lower half blocks */ dmc8i = bidir_pred_sad( &field8uf_mc, &field8ub_mc, ssmb.mb, w2, 16 ); dmc8i += bidir_pred_sad( &field8lf_mc, &field8lb_mc, ssmb.mb, w2, 16 ); /* select prediction type of minimum distance */ if (dmcfieldi<dmc8i && dmcfieldi<dmcfieldf && dmcfieldi<dmc8f && dmcfieldi<dmcfieldr && dmcfieldi<dmc8r) { /* field, interpolated */ me.mb_type = MB_FORWARD|MB_BACKWARD; me.motion_type = MC_FIELD; vmc = fieldf_mc.var + bidir_pred_var( &fieldf_mc, &fieldb_mc, ssmb.mb, w2, 16); } else if (dmc8i<dmcfieldf && dmc8i<dmc8f && dmc8i<dmcfieldr && dmc8i<dmc8r) { /* 16x8, interpolated */ me.mb_type = MB_FORWARD|MB_BACKWARD; me.motion_type = MC_16X8; /* upper and lower half blocks */ vmc = field8uf_mc.var + bidir_pred_var( &field8uf_mc, &field8ub_mc, ssmb.mb, w2, 8); vmc += field8lf_mc.var + bidir_pred_var( &field8lf_mc, &field8lb_mc, ssmb.mb, w2, 8); } else if (dmcfieldf<dmc8f && dmcfieldf<dmcfieldr && dmcfieldf<dmc8r) { /* field, forward */ me.mb_type = MB_FORWARD; me.motion_type = MC_FIELD; vmc = fieldf_mc.var + unidir_pred_var( &fieldf_mc, ssmb.mb, w2, 16); } else if (dmc8f<dmcfieldr && dmc8f<dmc8r) { /* 16x8, forward */ me.mb_type = MB_FORWARD; me.motion_type = MC_16X8; /* upper and lower half blocks */ vmc = field8uf_mc.var + unidir_pred_var( &field8uf_mc, ssmb.mb, w2, 8); vmc += field8lf_mc.var + unidir_pred_var( &field8lf_mc, ssmb.mb, w2, 8); } else if (dmcfieldr<dmc8r) { /* field, backward */ me.mb_type = MB_BACKWARD; me.motion_type = MC_FIELD; vmc = fieldb_mc.var + unidir_pred_var( &fieldb_mc, ssmb.mb, w2, 16 ); } else { /* 16x8, backward */ me.mb_type = MB_BACKWARD; me.motion_type = MC_16X8; /* upper and lower half blocks */ vmc = field8ub_mc.var + unidir_pred_var( &field8ub_mc, ssmb.mb, w2, 8); vmc += field8lb_mc.var + unidir_pred_var( &field8lb_mc, ssmb.mb, w2, 8); } /* select between intra and non-intra coding */ if (vmc>intravar && vmc > 12*256) { me.mb_type = MB_INTRA; me.var = intravar; } else { me.var = vmc; if (me.motion_type==MC_FIELD) { /* forward */ me.MV[0][0][0] = fieldf_mc.pos.x - (i<<1); me.MV[0][0][1] = fieldf_mc.pos.y - (j<<1); me.field_sel[0][0] = fieldf_mc.fieldsel; /* backward */ me.MV[0][1][0] = fieldb_mc.pos.x - (i<<1); me.MV[0][1][1] = fieldb_mc.pos.y - (j<<1); me.field_sel[0][1] = fieldb_mc.fieldsel; } else /* MC_16X8 */ { /* forward */ me.MV[0][0][0] = field8uf_mc.pos.x - (i<<1); me.MV[0][0][1] = field8uf_mc.pos.y - (j<<1); me.field_sel[0][0] = field8uf_mc.fieldsel; me.MV[1][0][0] = field8lf_mc.pos.x - (i<<1); me.MV[1][0][1] = field8lf_mc.pos.y - ((j+8)<<1); me.field_sel[1][0] = field8lf_mc.fieldsel; /* backward */ me.MV[0][1][0] = field8ub_mc.pos.x - (i<<1); me.MV[0][1][1] = field8ub_mc.pos.y - (j<<1); me.field_sel[0][1] = field8ub_mc.fieldsel; me.MV[1][1][0] = field8lb_mc.pos.x - (i<<1); me.MV[1][1][1] = field8lb_mc.pos.y - ((j+8)<<1); me.field_sel[1][1] = field8lb_mc.fieldsel; } } } best_of_kind_me.erase(best_of_kind_me.begin(), best_of_kind_me.end()); best_of_kind_me.push_back( me );}/* * frame picture field mode motion estimates... * * org: top left pel of source reference frame * ref: top left pel of reconstructed reference frame * ssmb: macroblock to be matched * i,j: location of mb relative to ref (=center of search window) * sx,sy: half widths of search window * besttop: location of best field pred. for top field of mb * bestbo : location of best field pred. for bottom field of mb *//* * field picture motion estimation subroutine * * toporg: address of frame holding original top reference field * topref: address of frame holding reconstructed top reference field * botorg: address of frame holding original bottom reference field * botref: address of frame holding reconstructed bottom reference field * ssmmb: macroblock to be matched * i,j: location of mb (=center of search window) * sx,sy: half width/height of search window *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -