您的位置:首页 > 编程语言

homerHEVC代码阅读(27)——CTU初始化函数init_ctu

2015-12-08 14:51 555 查看
init_ctu主要用来初始化CTU的坐标,长度等各个属性,还有重要的一步是获取当前CTU的邻居,并设置相应的标志。

// ctu初始化
ctu_info_t* init_ctu(henc_thread_t* et)
{
ctu_info_t *ctu;
int ctu_width, ctu_height;

// 获取当前的cu
ctu = &et->enc_engine->ctu_info[et->cu_current];//&et->curr_ctu_group_info[0];

// 当前cu的索引
ctu->ctu_number = et->cu_current;

// et->cu_current_x是当前cu的坐标(并不是像素坐标,而是索引坐标)

// 设置ctu三个分量的像素坐标
ctu->x[Y_COMP] = et->cu_current_x*et->ctu_width[Y_COMP];
ctu->y[Y_COMP] = et->cu_current_y*et->ctu_height[Y_COMP];

ctu->x[U_COMP] = ctu->x[V_COMP] = et->cu_current_x*et->ctu_width[U_COMP];
ctu->y[U_COMP] = ctu->y[V_COMP] = et->cu_current_y*et->ctu_height[U_COMP];

// 设置CTU的尺寸,即LCU的尺寸64x64
ctu->size = et->max_cu_size;

// 设置ctu的划分数量
ctu->num_part_in_ctu = et->num_partitions_in_cu;
ctu->num_part_in_ctu = et->num_partitions_in_cu;

//	ctu->partition_list = &et->partition_info[0];

// ctu的宽和高,之所以这样设置的原因是为了防止有些图像的宽和高不是CTU的整数倍
// ctu->x[Y_COMP] 表示CTU的起始位置(像素坐标),ctu->size表示CTU的宽和高(被设置为64x64)
// ctu->x[Y_COMP]+ctu->size 就表示计算CTU最后一个像素的位置,用来判断当前的CTU(被设置为64x64)是否超出了图像的边界
// 如果图像不是64x64的整数倍,那么某一个边缘的CTU必然会超出图像的边界,所以需要调整该边缘CTU的宽和高
ctu_width = ((ctu->x[Y_COMP]+ctu->size) < et->pict_width[Y_COMP])?(ctu->size):et->pict_width[Y_COMP]-ctu->x[Y_COMP];
ctu_height = ((ctu->y[Y_COMP]+ctu->size) < et->pict_height[Y_COMP])?(ctu->size):et->pict_height[Y_COMP]-ctu->y[Y_COMP];

// 如果最后计算出来的宽和高不是64,那么需要调整CTU的宽和高
if(ctu_width!=ctu->size || ctu_height!=ctu->size)
{
// 如果当前CTU被划分,那么每一个部分的宽度
int width_in_partitions = ctu_width>>2;

// 如果当前CTU被划分,那么每一个部分的高度
int height_in_partitions = ctu_height>>2;

// 如果当前CTU被划分,那么每一个部分的尺寸
int cu_size_in_partitions = ctu->size>>2;
//		if(height_in_partitions == cu_size_in_partitions)
//			height_in_partitions = cu_size_in_partitions-1;
//		else if(width_in_partitions == cu_size_in_partitions)

height_in_partitions -= 1;

// 最后一个有效的划分,raster2abs_table这个转换表是从像素地址转换为索引地址
ctu->last_valid_partition =	et->enc_engine->raster2abs_table[height_in_partitions*cu_size_in_partitions+width_in_partitions-1];
}
else
{
// 最后一个有效的划分
ctu->last_valid_partition = et->num_partitions_in_cu-1;
}

// 获取当前ctu的邻居
CuGetNeighbors(et, ctu);//raster order
return ctu;
}


// 取得cu的邻居
void CuGetNeighbors(henc_thread_t* et, ctu_info_t* ctu)
{
// 如果CTU的横坐标是0,那么表示他的左边没有邻居
if(ctu->x[Y_COMP]==0)
ctu->ctu_left = NULL;
else
{
// 否则有左邻居
ctu->ctu_left = &et->enc_engine->ctu_info[ctu->ctu_number-1];
}

// 由于使用了wfpp的方式,一般认为左下角的邻居不存在
ctu->ctu_left_bottom = NULL;//en raster order este no existe. En wavefront si

// 如果ctu的纵坐标是0,表示它的上面、左上角、右上角的邻居为空
if(ctu->y[Y_COMP]==0)
{
ctu->ctu_top = NULL;
ctu->ctu_top_right = NULL;
ctu->ctu_top_left = NULL;
}
// 如果纵坐标不为0
else
{
ctu->ctu_top = &et->enc_engine->ctu_info[ctu->ctu_number-et->pict_width_in_ctu];

// 但是横坐标为0,那么它的左上角不存在
if(ctu->x[Y_COMP]==0)
ctu->ctu_top_left = NULL;
else
ctu->ctu_top_left = &et->enc_engine->ctu_info[ctu->ctu_number-et->pict_width_in_ctu-1];

// 判断是否存在右上角
// 如果当前CTU位于帧的右边缘,那么它不存在右上角邻居
if(et->cu_current_y==0 || ((et->cu_current_x % et->pict_width_in_ctu) == (et->pict_width_in_ctu-1)))
ctu->ctu_top_right = NULL;
else
{
ctu->ctu_top_right = &et->enc_engine->ctu_info[ctu->ctu_number-et->pict_width_in_ctu+1];
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: