这两个函数位于文件mv_search.c中,在分析这两个函数前,先看一下文件开头定义的两个数组:
static const short bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
static const short by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}}; 这里,每一行的五个一维数组分别代表了Skip,16×16,16×8,8×16,8×8五种分块方式下,每个子分块左上角像素的坐标值(这个坐标以4×4的分块为单位)。
/*!
************************************************************************ * \brief * Motion search for a macroblock partition ************************************************************************ */ void PartitionMotionSearch (Macroblock *currMB, /*指向当前宏块*/ int blocktype, /* 块类型,Skip,16×16,16×8,8×16,8×8 */ int block8x8, /* 8×8分块标识 */ int *lambda_factor)/* 拉格朗日参数 */ { VideoParameters *p_Vid = currMB->p_Vid; Slice *currSlice = currMB->p_Slice; #if GET_METIME
TIME_T me_time_start; TIME_T me_time_end; int64 me_tmp_time; gettime( &me_time_start ); // start time ms #endif if (currSlice->rdoq_motion_copy == 1)
{ PicMotionParams **motion = p_Vid->enc_picture->mv_info; short by = by0[blocktype][block8x8]; /* 含义见文章开头 */ short bx = bx0[blocktype][block8x8]; short step_h = (part_size[blocktype][0]); /* */ short step_v = (part_size[blocktype][1]); /* */ short pic_block_y = currMB->block_y + by;
short pic_block_x = currMB->block_x + bx; int list_offset = currMB->list_offset; /* ???? */ int numlists = (currSlice->slice_type == B_SLICE) ? 2 : 1; distblk *m_cost; short list = LIST_0; short ref = 0; //===== LOOP OVER REFERENCE FRAMES =====
for (list = 0; list < numlists; list++) { for (ref=0; ref < currSlice->listXsize[list+list_offset]; ref++) { m_cost = &p_Vid->motion_cost[blocktype][list][ref][block8x8]; //===== LOOP OVER SUB MACRO BLOCK partitions
updateMV_mp(currMB, m_cost, ref, list, bx, by, blocktype, block8x8); set_me_parameters(motion, &currSlice->all_mv[list][ref][blocktype][by][bx], list, (char) ref, step_h, step_v, pic_block_y, pic_block_x); } } } else { InputParameters *p_Inp = currMB->p_Inp; short by = by0[blocktype][block8x8]; /* 当前块在宏块内y方向的偏移,以4×4为单位 */ short bx = bx0[blocktype][block8x8]; /* 当前块在宏块内x方向的偏移,以4×4为单位 */ short step_h = (part_size[blocktype][0]); short step_v = (part_size[blocktype][1]); short pic_block_y = currMB->block_y + by;/* 当前块的位置,y方向 */
short pic_block_x = currMB->block_x + bx;/* 当前块的位置,x方向 */ int list_offset = currMB->list_offset; int numlists = (currSlice->slice_type == B_SLICE) ? 2 : 1; /* 使用的参考图像列表数目 */ short list = LIST_0;/* 参考图像列表 */ short ref = 0; /* 参考图像索引值 */ MEBlock mv_block; /* 运动矢量 */ distblk *m_cost; PicMotionParams **motion = p_Vid->enc_picture->mv_info; // Set flag for 8x8 Hadamard consideration for SATD (only used when 8x8 integer transform is used for encoding)
mv_block.test8x8 = p_Inp->Transform8x8Mode; /* 初始化结构体,主要是这支参考图像列表及索引值,块类型等 */
init_mv_block(currMB, &mv_block, (short) blocktype, list, (char) ref, bx, by);
if (p_Inp->SearchMode == EPZS)
{ if (p_Inp->EPZSSubPelGrid) currMB->IntPelME = EPZSIntPelBlockMotionSearch; else currMB->IntPelME = EPZSPelBlockMotionSearch; } /* 获取图像原像素值 */
get_original_block(p_Vid, &mv_block); //--- motion search for block ---
{ //===== LOOP OVER REFERENCE FRAMES ===== for (list = 0; list < numlists; list++) { //----- set arrays ----- mv_block.list = (char) list; for (ref=0; ref < currSlice->listXsize[list+list_offset]; ref++) { mv_block.ref_idx = (char) ref; //设定参考图像索引值 m_cost = &p_Vid->motion_cost[blocktype][list][ref][block8x8]; {
//----- set search range --- get_search_range(&mv_block, p_Inp, ref, blocktype); //===== LOOP OVER MACROBLOCK partitions
*m_cost = BlockMotionSearch (currMB, &mv_block, bx<<2, by<<2, lambda_factor); } //--- set motion vectors and reference frame --- set_me_parameters(motion, &currSlice->all_mv[list][ref][blocktype][by][bx], list, (char) ref, step_h, step_v, pic_block_y, pic_block_x);
} } } free_mv_block(&mv_block);
} #if GET_METIME
gettime(&me_time_end); // end time ms me_tmp_time = timediff (&me_time_start, &me_time_end); p_Vid->me_tot_time += me_tmp_time; p_Vid->me_time += me_tmp_time; #endif } 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/underway2010/archive/2010/12/12/6071374.aspx
|
|