万圣节杀人狂百度云:PartitionMotionSearch函数分析 - 二手流氓的专栏 - CSDN博客
来源:百度文库 编辑:偶看新闻 时间:2024/04/25 17:14:49
这两个函数位于文件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
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