📄 mae_fe_mcomp.c
字号:
#endifvoid MAE_MPV_motion(MAEContext *s) { int mc_blocktype; int32 iscale, ishift, i, j; int32 luty[256], lutuv[256]; unsigned int y_mbmode, uv_mbmode, bn, exp_bc; // Build LUT for intensity compensation // If intensity compensation is not done, set LUT 1:1 if (s->icomp & s->codstyl) { if(s->lumscale == 0) { iscale = -64; ishift = (255 * 64) + 32 - (s->lumshift * 2 * 64); } else { iscale = s->lumscale + 32; ishift = (s->lumshift > 31) ? ((s->lumshift *64) - (64 * 64)) : (s->lumshift *64); } for(i = 0; i < 256; i++) { j = ((iscale*i) + ishift + 32) >> 6; j = (j < 0) ? 0 : (j > 255) ? 255 : j; luty[i] = j; j = ((iscale * (i - 128)) + (128 * 64) + 32) >> 6; j = (j < 0) ? 0 : (j > 255) ? 255 : j; lutuv[i] = j; } } else { for(i = 0; i < 256; i++) { luty[i] = i; lutuv[i] = i; } } // y_mbmode & uv_mbmode are used to determine if interlaced frames can be created exp_bc = s->bc ? 8 : 6; y_mbmode = 0; for(bn = 0; bn < 4; bn++) y_mbmode |= (s->mbmode>>(14 - 2*bn)) & 0x3; uv_mbmode = 0; for(bn = 4; bn < exp_bc; bn++) uv_mbmode |= (s->mbmode>>(14 - 2*bn)) & 0x3; // Copy only once per frame MAE_oof_start(s, y_mbmode, uv_mbmode, luty, lutuv);// Can be used for MPEG-4 also if needed#if ((defined(REF_WMV9) && defined(DUMP_REF_FRAME)) || defined(REF_DIVX)) MAE_oof_print(s);#endif // Determine the motion compensation block type mc_blocktype = s->mbtype & 7; // Since the frame size has changed, change linesz, height, xpos, & ypos s->linesz = s->linesz + 96; s->height = s->height + 96; s->xpos = s->xpos + (3 * 16); s->ypos = (s->fp && s->ps) ? s->ypos + (3 * 16/2) : s->ypos + (3 * 16); switch (mc_blocktype) { case MAE_MC_BLKTYPE_16X16: MAE_motion_16x16(s); break; case MAE_MC_BLKTYPE_16X8: MAE_motion_16x8(s); break; case MAE_MC_BLKTYPE_8X8: MAE_motion_8x8(s); break; default: MAE_ASSERT_MSG("Header Error: mbtyp/mc_blocktype out of range\n"); } MAE_oof_end(s);}void MAE_motion_16x16(MAEContext *s) { uint32 mc_mode; int mvx[8], mvy[8]; uint8 *ptr,*destptr; int rnd,avg,qpel,bwd,qpeluv; int dxy_y[2], dxy_uv[2],dxy_y_e[2],dxy_uv_e[2]; //int src_x_y[2],src_x_uv[2],src_y_y[2],src_y_uv[2]; int linesize_y,linesize_uv; int linesize_y_clip,linesize_uv_clip; int y_clip_min_y, uv_clip_min_y; int y_clip_min_x, uv_clip_min_x; int height_y_clip,height_uv_clip; int height_y,height_uv; int ring_size_y, ring_size_uv; uint32 bn; uint32 exp_bc; int chroma_ypos; int64 oof; uint8 * previous_y; uint8 * previous_cb; uint8 * previous_cr; uint8 * future_y; uint8 * future_cb; uint8 * future_cr; // For pointing to global structure so don't have to change code // Okay to copy here since malloc'ed if necessary in mae_fe before call uint8 *current_y = gCM.cur_y_oof; uint8 *current_cb = gCM.cur_cb_oof; uint8 *current_cr = gCM.cur_cr_oof; uint8 *previous_y_top = (s->fp) ? gCM.prev_y_top_oof_fp1 : gCM.prev_y_top_oof_fp0; uint8 *previous_cb_top = (s->fp) ? gCM.prev_cb_top_oof_fp1 : gCM.prev_cb_top_oof_fp0; uint8 *previous_cr_top = (s->fp) ? gCM.prev_cr_top_oof_fp1 : gCM.prev_cr_top_oof_fp0; uint8 *future_y_top = (s->fp) ? gCM.fut_y_top_oof_fp1 : gCM.fut_y_top_oof_fp0; uint8 *future_cb_top = (s->fp) ? gCM.fut_cb_top_oof_fp1 : gCM.fut_cb_top_oof_fp0; uint8 *future_cr_top = (s->fp) ? gCM.fut_cr_top_oof_fp1 : gCM.fut_cr_top_oof_fp0; uint8 *previous_y_bot = (s->fp) ? gCM.prev_y_bot_oof_fp1 : gCM.prev_y_bot_oof_fp0; uint8 *previous_cb_bot = (s->fp) ? gCM.prev_cb_bot_oof_fp1 : gCM.prev_cb_bot_oof_fp0; uint8 *previous_cr_bot = (s->fp) ? gCM.prev_cr_bot_oof_fp1 : gCM.prev_cr_bot_oof_fp0; uint8 *future_y_bot = (s->fp) ? gCM.fut_y_bot_oof_fp1 : gCM.fut_y_bot_oof_fp0; uint8 *future_cb_bot = (s->fp) ? gCM.fut_cb_bot_oof_fp1 : gCM.fut_cb_bot_oof_fp0; uint8 *future_cr_bot = (s->fp) ? gCM.fut_cr_bot_oof_fp1 : gCM.fut_cr_bot_oof_fp0; // If 4:2:2, use 8 blocks, otherwise 6 blocks exp_bc = s->bc ? 8 : 6; // the "- 24" is needed because of the out-of-frame calc chroma_ypos = (s->fp && s->ps) ? (s->ypos - 12) : (s->ypos - 24); chroma_ypos = s->bc ? chroma_ypos : (s->ypos >> 1); // Set values for rnd and qpel rnd = s->rndctl; qpel = (s->mcprec == MAE_QUARTER_PEL) ? 1 : 0; qpeluv = ((s->mcprecuv == MAE_QUARTER_PEL) & (s->codstyl)) ? 1 : 0; height_y = s->height; height_uv = (s->bc) ? (s->height - 48) : height_y >> 1; // Set linesize & height // Linesize & height are half for chroma linesize_y_clip = (s->linesz - 18); linesize_uv_clip = (s->linesz >> 1) - 10; height_y_clip = (s->height - 18); height_uv_clip = (height_uv - 10); y_clip_min_y = (s->codstyl) ? 32 : 1; uv_clip_min_y = (s->codstyl) ? 16 : 1; y_clip_min_x = (s->codstyl) ? 32 : 1; uv_clip_min_x = (s->codstyl) ? 16 : 1; height_y = (s->fp) ? (height_y >> 1) : height_y; height_uv = (s->fp) ? (height_uv >> 1) : height_uv; linesize_y = (s->fp) ? (s->linesz << 1) : s->linesz; linesize_uv = (s->fp) ? (s->linesz) : (s->linesz>>1); ring_size_uv = (s->fp) ? 12 : 24; ring_size_y = (s->fp) ? 24 : 48; // Fetch motion vectors // For 16x16, we get 4 luma mv's and 2 chroma mv's MAE_Get_4MV(s, mvx, mvy); // dxy_y[0] is used to index into the leaf functions (mc??) // At this point, mvy & mvx are in qpel units. // By masking and shifting, you get the mc?? value dxy_y[0] = ((mvy[0] & 3) << 2) | (mvx[0] & 3); dxy_y_e[0] = ((mvx[0] & 3) << 2) | (mvy[0] & 3); // src_[xy]_y gives the location of the ref block for y src_x_y[0] = s->xpos + (mvx[0] >> 2); src_y_y[0] = s->ypos + (mvy[0] >> 2); // Clips so that ref block does not more than 16 pixels // outside of frame // EricS: This will have to change for out-of-frame pixels src_x_y[0] = mae_clip(src_x_y[0], y_clip_min_x, linesize_y_clip); if (src_x_y[0] == linesize_y_clip) dxy_y[0] &= ~3; src_y_y[0] = mae_clip(src_y_y[0], y_clip_min_y, height_y_clip); if (src_y_y[0] == height_y_clip) dxy_y[0] &= ~12; // dxy_uv[0] is used to index into the leaf functions (mc??) // Since uv can only be on hpel boundaries, the only possible // leaf functions are mc00, mc20, mc02, or mc22 dxy_uv[0] = ((mvy[4] & 3) << 2) | (mvx[4] & 3); dxy_uv[0] = (s->codstyl) ? dxy_uv[0] : (dxy_uv[0] & 0xfffffffa); dxy_uv_e[0] = ((mvx[4] & 3) << 2) | (mvy[4] & 3); dxy_uv_e[0] = (s->codstyl) ? dxy_uv_e[0] : (dxy_uv_e[0] & 0xfffffffa); // src_[xy]_uv gives the location of the ref block for uv // xpos & ypos are in fpel units when referring to the luma (y) // since the chroma (uv) is sub-samples, xpos & ypos must be /2 // The mv's are in qpel units, so they must be shifted by 2 src_x_uv[0] = (s->xpos >> 1) + (mvx[4] >> 2); src_y_uv[0] = (chroma_ypos) + (mvy[4] >> 2); // Clips so that ref block does not more than 8 pixels // outside of frame // EricS: This will have to change for out-of-frame pixels src_x_uv[0] = mae_clip(src_x_uv[0], uv_clip_min_x, linesize_uv_clip); if (src_x_uv[0] == (linesize_uv_clip)) dxy_uv[0] &= ~3; src_y_uv[0] = mae_clip(src_y_uv[0], uv_clip_min_y, height_uv_clip); if (src_y_uv[0] == height_uv_clip) dxy_uv[0] &= ~12; // determines mbmode for each block mc_mode = 0; for(bn = 0; bn < exp_bc; bn++){ mc_mode |= (s->mbmode>>(14 - 2*bn)) & 0x3; } switch (mc_mode) { case MAE_MC_MODE_INTRA: MAE_ASSERT_MSG("Header Error: mc being called for INTRA mb\n"); break; case MAE_MC_MODE_FWD: // ********** Y ********** avg = 0; // only set for bidir to avg final pixel bwd = 0; // bwd == 0 means fwd // Determine if reference block is out-of frame x_fwd_pixel[x_fwd_blk_in].oof = MAE_create_oof_mask("Y (16x16, fwd)", src_x_y[0], src_y_y[0], s->linesz, height_y, 48, ring_size_y, 16, 16, s->codstyl); oof = x_fwd_pixel[x_fwd_blk_in].oof; // Determine whether to use top/bot field only based on fp & ft previous_y = (s->fp && !s->ft) ? previous_y_bot : previous_y_top; // ptr is the pointer to the reference block // destptr is the pointer to the destination block ptr = previous_y + src_y_y[0] * linesize_y + src_x_y[0]; destptr = current_y + s->ypos * linesize_y + s->xpos; // calls one of the mc?? leaf functions for luma (y) if (!s->codstyl) MAE_mpeg_hv_4t (destptr, ptr, linesize_y, linesize_y, 16, 16, 0, rnd, dxy_y_e[0], oof, 0, bwd, s->mbmode,s->mbtype, s->mcprec); else MAE_wmv9_vh_4t (destptr, ptr, linesize_y, linesize_y, 16, 16, 0, rnd, dxy_y_e[0], oof, 0, bwd, s->mbmode,s->mbtype, s->mcprec); // ********** Cb ********** // Determine whether to use top/bot field only based on fp & ft previous_cb = (s->fp && !s->ft) ? previous_cb_bot : previous_cb_top; // Determine if reference block is out-of frame x_fwd_pixel[x_fwd_blk_in].oof = MAE_create_oof_mask("Cb (16x16, fwd)", src_x_uv[0], src_y_uv[0], s->linesz>>1, height_uv, 24, ring_size_uv, 8, 8, s->codstyl); oof = x_fwd_pixel[x_fwd_blk_in].oof; // ptr is the pointer to the reference block // destptr is the pointer to the destination block ptr = previous_cb + src_y_uv[0] * linesize_uv + src_x_uv[0]; destptr = current_cb + (chroma_ypos * linesize_uv) + (s->xpos >> 1); // calls one of the mc?? leaf functions for first chroma (cb) if (!s->codstyl) MAE_mpeg_hv_4t (destptr, ptr, linesize_uv, linesize_uv, 8, 8, 0, rnd, dxy_uv_e[0], oof, 4, bwd, s->mbmode,s->mbtype, s->mcprecuv); else MAE_wmv9_vh_4t (destptr, ptr, linesize_uv, linesize_uv, 8, 8, 0, rnd, dxy_uv_e[0], oof, 4, bwd, s->mbmode,s->mbtype, s->mcprecuv); // ********** Cr ********** // Determine whether to use top/bot field only based on fp & ft previous_cr = (s->fp && !s->ft) ? previous_cr_bot : previous_cr_top; // Determine if reference block is out-of frame x_fwd_pixel[x_fwd_blk_in].oof = MAE_create_oof_mask("Cr (16x16, fwd)", src_x_uv[0], src_y_uv[0], s->linesz>>1, height_uv, 24, ring_size_uv, 8, 8, s->codstyl); oof = x_fwd_pixel[x_fwd_blk_in].oof; // ptr is the pointer to the reference block // destptr is the pointer to the destination block ptr = previous_cr + src_y_uv[0] * linesize_uv + src_x_uv[0]; destptr = current_cr + (chroma_ypos * linesize_uv) + (s->xpos >> 1); // calls one of the mc?? leaf functions for second chroma (cr) if (!s->codstyl)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -