create_partition_ctu_neighbours的作用是计算当前CTU中的每一个CU的邻居存在的标志。
// 计算CTU下所有CU的邻居存在的标志 void create_partition_ctu_neighbours(henc_thread_t* et, ctu_info_t *ctu, cu_partition_info_t* curr_partition_info) { // 父CU的分割信息 cu_partition_info_t* parent_part_info = curr_partition_info->parent; // 当前深度 int curr_depth = curr_partition_info->depth; // 深度状态 int depth_state[MAX_PARTITION_DEPTH] = {0,0,0,0,0}; int cu_min_tu_size_shift = max((et->max_cu_size_shift - (et->max_pred_partition_depth+max(et->max_intra_tr_depth, et->max_inter_tr_depth)-1)), MIN_TU_SIZE_SHIFT);//(et->max_cu_size_shift - (et->max_pred_partition_depth+et->max_intra_tr_depth-1))>MIN_TU_SIZE_SHIFT?(et->max_cu_size_shift - (et->max_pred_partition_depth+et->max_intra_tr_depth)):MIN_TU_SIZE_SHIFT;//+ interSplitFlag + intraSplitFlag //(part_size_type==SIZE_NxN));// int max_processing_depth = et->max_cu_size_shift-cu_min_tu_size_shift; // 一帧中ctu的行数 int ctu_valid_lines = (ctu->y[Y_COMP]+ctu->size)>et->pict_height[Y_COMP]?(et->pict_height[Y_COMP]-ctu->y[Y_COMP]):ctu->size;//((ctu->y[Y_COMP]+ctu->size)>et->pict_height)?(et->pict_height-ctu->y[Y_COMP]):ctu->size; // 一帧中ctu的列数 int ctu_valid_colums = (ctu->x[Y_COMP]+ctu->size)>et->pict_width[Y_COMP]?(et->pict_width[Y_COMP]-ctu->x[Y_COMP]):ctu->size;//((ctu->y[Y_COMP]+ctu->size)>et->pict_width)?(et->pict_width-ctu->y[Y_COMP]):ctu->size; while(curr_depth!=0 || depth_state[curr_depth]!=1) { curr_depth = curr_partition_info->depth; // ctu->y表示该CTU在帧中的坐标 // y_position则表示CTU的某一个cu在该CTU中的坐标,两者相加可以得到cu的实际坐标 // 这个标志就表示该cu的左上角是否仍然在帧内 curr_partition_info->is_tl_inside_frame = (ctu->y[Y_COMP]+curr_partition_info->y_position < et->pict_height[Y_COMP]) && (ctu->x[Y_COMP]+curr_partition_info->x_position < et->pict_width[Y_COMP]); // 这个标志表示该cu的底部是否仍然在帧内 curr_partition_info->is_b_inside_frame = (ctu->y[Y_COMP]+curr_partition_info->y_position+curr_partition_info->size <= et->pict_height[Y_COMP]); // 这个标志表示该cu的右侧是否仍然在帧内 curr_partition_info->is_r_inside_frame = (ctu->x[Y_COMP]+curr_partition_info->x_position+curr_partition_info->size <= et->pict_width[Y_COMP]); // 如果当前CU的左上角在帧内 if(curr_partition_info->is_tl_inside_frame) { // 如果父亲cu的划分信息为空 if(parent_part_info == NULL)//ctu { curr_partition_info->left_neighbour = ctu->ctu_left?1:0; curr_partition_info->top_neighbour = ctu->ctu_top?1:0; curr_partition_info->left_bottom_neighbour = ctu->ctu_left_bottom?1:0; curr_partition_info->top_right_neighbour = ctu->ctu_top_right?1:0; } else // 如果父cu的划分信息不为空,获取CU的划分块的邻居信息 cu_partition_get_neighbours(curr_partition_info, et->max_cu_size, ctu_valid_colums, ctu_valid_lines); } // 深度状态改变 depth_state[curr_depth]++; // 如果当前的深度未到达最大的处理深度,而且 当前CU仍在帧的内部,那么继续按照四叉树的方式向下计算 if(curr_depth<max_processing_depth && curr_partition_info->is_tl_inside_frame)//if tl is not inside the frame don't process the next depths { curr_depth++; parent_part_info = curr_partition_info; } // 如果上述两个条件中的一个不满足,即:当前深度达到了最大的处理深度,或者当前CU不在帧的内部 // 同时当前深度的四个分区已经处理完毕,那么就从当前深度一直沿着四叉树的分支向上,直到遇到一个某一个深度状态不是4的CU,继续处理 else if(depth_state[curr_depth]==4) { while(depth_state[curr_depth]==4) { depth_state[curr_depth] = 0; curr_depth--; parent_part_info = parent_part_info->parent; } } // 调整当前cu分割信息 if(parent_part_info!=NULL) curr_partition_info = parent_part_info->children[depth_state[curr_depth]]; } }
// 获取cu的划分(分割、分区)的邻居信息(不能用于CTU) void cu_partition_get_neighbours(cu_partition_info_t *curr_part, int cu_size, int ctu_valid_colums, int ctu_valid_lines) { // 获取当前cu的父亲cu cu_partition_info_t *parent = curr_part->parent; // 如果父亲CU有左邻居或者当前CU的横坐标大于0,那么当前CU一定存在左邻居 if(parent->left_neighbour || curr_part->x_position) curr_part->left_neighbour = 1; else // 否则不存在左邻居 curr_part->left_neighbour = 0; // 如果父亲cu有上侧邻居 或者 当前cu的纵坐标大于0 ,那么当前CU一定存在上侧邻居 if(parent->top_neighbour || curr_part->y_position) curr_part->top_neighbour = 1; else curr_part->top_neighbour = 0; // 同上判断是否存在左下角邻居 if((parent->left_bottom_neighbour && curr_part->x_position == parent->x_position) || (parent->left_neighbour && curr_part->x_position == parent->x_position && curr_part->y_position == parent->y_position && ctu_valid_lines>curr_part->y_position+curr_part->size))// && parent->is_b_inside_frame)) curr_part->left_bottom_neighbour = 1; else curr_part->left_bottom_neighbour = 0; // 判断是否存在右上角邻居 if((parent->top_right_neighbour && curr_part->y_position == parent->y_position) || (parent->top_neighbour && curr_part->x_position == parent->x_position && curr_part->y_position == parent->y_position && ctu_valid_colums>curr_part->x_position+curr_part->size) || (curr_part->x_position == parent->x_position && curr_part->y_position != parent->y_position && ctu_valid_colums>curr_part->x_position+curr_part->size))//parent->is_r_inside_frame)) curr_part->top_right_neighbour = 1; else curr_part->top_right_neighbour = 0; }