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]; } } }
相关文章推荐
- 在eclipse里如何快速定位到某一行?
- Spring:bean的生命周期
- Java学习日记-10 集合
- 通过hibernate实体java文件 立即生成数据库table
- 通过hibernate实体java文件 立即生成数据库table
- Python yield
- PHP代码规范的10个好习惯
- GridView自带分页 1总页数 首页 下一页 上一页 尾页 X 页 go 实现方法 .
- C++大数类
- Java学习----main详解
- IDFTP连不上FTP服务器的解决方法
- 学习php设计模式 php实现模板方法模式
- Thinkphp 缓存微信jssdk相关认证参数
- ThinkPHP框架九上传文件和生成缩略图
- PHP中日期的获取及转换
- 图像旋转 双线性插值 c++
- java并发的处理方式
- python 学习笔记一
- Python使用pygame模块编写俄罗斯方块游戏的代码实例
- [总结]C#用于BMP图像显示的方法