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

homerHEVC代码阅读(10)——基础结构之picture_t、slice_t、ctu_info_t

2015-11-30 20:43 190 查看
picture_t表示一帧图像。注意到picture_t中只包含一个片。而实际的数据由video_frame_t对象来管理(或者说由video_frame_t对象来指向)。

slice_t表示图像中的片。

ctu_info_t表示一个CTU。

参考图像列表list0和list1的区别:

P帧只参考list0的图像。

B帧参考list0和list1的图像。

list0中可以包含,编码顺序在当前帧之前但是播放顺序在当前帧之后的图像(即后向帧),也包含前向帧。

在编码的过程中,一个帧只能被标志为:

1、不是参考帧

2、放在short-term中作为参考帧

3、放在long-term中作为参考帧

4、直接输出

list0中的帧可以是short-term也可以是long-term。

short-term中的图像,由自带的picnum(每个图像有一个变量),计算出一个值,然后从高到底排列在short-term中。

long-term也一样,但是它的次序是从低到高的。

每次编码完成一个帧,这个次序(short-term和long-term中帧的次序)都会变动。

正常情况下,编完一帧都是把它放到最近的short-term中,意味着最容易被参考到,如果编码器需要改动,就会把某一帧放到short-term的后面,就是long-term,这些都是按照long-term picnum和short-term picnum大的大小次序存放的。

总结帧间预测的过程就是:

1、从ListX=0(即list0)开始(即前向预测),将参考索引iRefIndex设置为0

2、在当前iRefIndex下,生成高级运动矢量预测(AMVP)候选列表,得到最佳的运动矢量和最小代价;

3、以步骤2中选中的AMVP为起始点,在当前的iRefIndex帧内,以SA(T)D+λpred*Bits为代价进行运动估计,得到最佳的运动矢量和最小代价

4、置 iRefIndex=iRefIndex+l,重复步骤2和3,得到当前 iReflndex下的最佳运动矢量和最小代价;直到参考帧队列ListX中的所有标记为“Used for Reference“的参考帧都完成最佳运动矢量和最小代价的计算,并从中挑选代价最小的iReflndex作为当前预测方向下,最佳的参考索引;

5、将ListX=1 (即后向预测),重复(2)到(4)步骤,并挑选代价最小的iReflndex作为当前预测方向下的最佳的参考索引;

6、固定以List0 (或者List1)中最佳的参考索引和运动矢量为双向预测中的其中之一,对List1(或者list0)中所有参考索引进行(2)到(4)步骤,并找到最佳的双向预测参考索引和运动矢量。

7、比较前向预测、后向预测以及双向预测的最小代价,选择出最佳的预测方向。

参考图像集中存放的实际是图像的poc。

参考图像集实际的作用是管理已编码的图像,为后续的帧提供参考的图像,参考图像列表中的帧是从参考图像集中选出的。

struct picture_t
{
// 片,在目前的编码器中,一帧中只有一片
slice_t	slice;

// 将要编码的帧
video_frame_t	*img2encode;
};


struct slice_t
{
// 片的索引
uint32_t slice_index; //indice en la lista de slices

// 片的类型
uint32_t slice_type;

// nal类型
uint32_t nalu_type;

// 该片中第一个slice的开始地址
uint32_t first_cu_address;//address of first coding tree block in the slice

// 当前cu的地址
uint32_t curr_cu_address;//address of current coding tree block in the slice

// 该片中最后一个cu的地址
uint32_t last_cu_address;//m_uiDependentSliceCurEndCUAddr - address of current coding tree block in the slice partition units (256 per CU)

// 是否为依赖性片
uint32_t is_dependent_slice;//
uint32_t slice_temporal_layer_non_reference_flag;//

// 时域层mvp标识
uint32_t slice_temporal_mvp_enable_flag;

// 去方块滤波标识
uint32_t deblocking_filter_disabled_flag;
uint32_t sao_luma_flag;
uint32_t sao_chroma_flag;
uint32_t slice_loop_filter_across_slices_enabled_flag;
uint32_t slice_beta_offset_div2;
uint32_t slice_tc_offset_div2;

// merge模式的最大候选数量
uint32_t max_num_merge_candidates;

// 对应的序列参数集
sps_t		*sps;

// 对应的图像参数集
pps_t		*pps;

// 量化步长
int qp;

// 图像计数
uint32_t poc;

// 深度
uint32_t depth;

// 子时域层
uint32_t sublayer;//TLayer

// 被参考的计数
uint32_t referenced;

// 参考的图像的索引数组
uint32_t num_ref_idx[2];

// 使用的参考图像集的索引
uint32_t ref_pic_set_index;

// 参考图像集中存放的实际是图像的poc
// 参考图像集实际的作用是管理已编码的图像
// 为后续的帧提供参考的图像
// 参考图像列表中的帧是从参考图像集中选出的
ref_pic_set_t	*ref_pic_set;

// 参考的图像列表
// 即list0和list1,P帧使用list0,B帧使用list0和list1
video_frame_t	*ref_pic_list[2][MAX_NUM_REF];

// 两个参考图像列表的长度,即ref_pic_list的长度
int				ref_pic_list_cnt[2];
};


struct ctu_info_t
{
// cut编号
int				ctu_number;
// 该ctu在帧中的坐标(yuv三个分量)
int				x[3],y[3];//global coordinates in frame
// 尺寸
int				size;
// 该ctu被分成了多少个部分
int				num_part_in_ctu;
// 最后一个有效的分区
int				last_valid_partition;
// 失真
uint32_t		distortion;

// 分区信息列表
cu_partition_info_t	*partition_list;

uint8_t			*cbf[NUM_PICT_COMPONENTS];//[MAX_NUM_PARTITIONS];

// 帧内预测模式
uint8_t			*intra_mode[NUM_PICT_COMPONENTS-1];//[MAX_NUM_PARTITIONS];

// 帧间预测模式
uint8_t			*inter_mode;//[MAX_NUM_PARTITIONS];
// 四叉树的索引
uint8_t			*tr_idx;//[MAX_NUM_PARTITIONS];

// 预测的深度
uint8_t			*pred_depth;//[MAX_NUM_PARTITIONS];

// 对ctu分割时的类型NxN还是2NxN等
uint8_t			*part_size_type;//[MAX_NUM_PARTITIONS];
// 预测模式
uint8_t			*pred_mode;//[MAX_NUM_PARTITIONS];//intra or inter

// skip模式
uint8_t			*skipped;//[MAX_NUM_PARTITIONS];

// merge模式
uint8_t			*merge;
// merge模式的索引
uint8_t			*merge_idx;

// 量化步长
uint8_t			*qp;

// 系数窗口
wnd_t			*coeff_wnd;

//inter

// 参考的两个运动向量
motion_vector_t		*mv_ref[2];
// 运动向量的索引(不知到作用是什么)
int8_t				*mv_ref_idx[2];
// 运动向量的残差
motion_vector_t		*mv_diff[2];
// 运动向量残差的索引(不知道作用是什么)
uint8_t				*mv_diff_ref_idx[2];

//	uint8_t				*ref_idx1;

// 当前ctu左边的ctu
ctu_info_t		*ctu_left;
// 左下角的ctu
ctu_info_t		*ctu_left_bottom;
// 上方的ctu
ctu_info_t		*ctu_top;
// 右上角的ctu
ctu_info_t		*ctu_top_right;
// 左上角的ctu
ctu_info_t		*ctu_top_left;

// 上方的啥?/左边的啥?
int				top;
int				left;

//sao
//	sao_stat_data_t (*stat_data)[NUM_PICT_COMPONENTS][NUM_SAO_NEW_TYPES];//to save memory this can be allocated in a wpp thread basis when processing is distributed (COMPUTE_AS_HM undefined)
// sao的数据
sao_stat_data_t stat_data[NUM_PICT_COMPONENTS][NUM_SAO_NEW_TYPES];//to save memory this can be allocated in a wpp thread basis when processing is distributed (COMPUTE_AS_HM undefined)

// sao重建的参数
sao_blk_param_t recon_params;

// sao编码的参数
sao_blk_param_t coded_params;
//quant
//	int				/*qp, */qp_chroma;/*, prev_qp, prev_dqp*/
//    int				per;//, per_chroma;
//    int				rem;//, rem_chroma;
//    int				qpbits;
//	uint			variance;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: