x265源码分析:SAO 函数总结及逻辑关系图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nk_wavelet/article/details/52662954
/**
* @brief 边界补偿模式下像素的5种分类 :
*         第1类谷点和第2类凹拐点,需要加上一个正补偿值;
*         第4类峰点和第3类凸拐点,需要加上一个负补偿值;
*         第0类像素不进行补偿。
*/
const uint32_t SAO::s_eoTable[NUM_EDGETYPE] = {1, 2, 0, 3, 4};

/* 对|num / den|四舍五入,然后前面添加符号 */
inline int32_t roundIBDI(int32_t num, int32_t den);

/* 获取输入变量x的符号 */
inline int8_t signOf(int x);

/* 获取 a-b的符号 */
inline int signOf2(const int a, const int b);

/**
 * @brief 计算D_post和 D_pre的差值,其中D_pre和D_post分别表示原始像素与重构像素(SAO补偿前、补偿后)之间的失真。
 * @param count  : 一个CTB内某个特定SAO类型样本的个数
 * @param offset : 一个CTB内某个特定SAO类型样本的补偿值
 * @param offsetOrg : 原始像素与重构像素(SAO补偿前)之间的差值之和
 */
inline int64_t estSaoDist(int32_t count, int32_t offset, int32_t offsetOrg);

/* 创建SAO的部分参数,分配空间 */
bool SAO::create(x265_param* param, int initCommon);

/* 为当前CTU的SAO参数分配空间并初始化 */
void SAO::allocSaoParam(SAOParam* saoParam);

/**
 * @brief 根据SAO补偿模式对重构像素值进行补偿.
 * @param addr : 从上到下、从左到右,当前CTU的序号
 * @param typeIdx : SAO补偿模式,取值SAO_EO_X 或 SAO_BO
 * @param plane : 颜色空间平面的序号,亮度平面为0,两个色度平面分别为1和2. 
 */
void SAO::applyPixelOffsets(int addr, int typeIdx, int plane);

/* 获取亮度CTU的SAO补偿模式及对应的补偿值(在此函数之前已经计算得到)并进行补偿 */
void SAO::generateLumaOffsets(SaoCtuParam* ctuParam, int idxY, int idxX);

/* 获取色度CTU的SAO补偿模式及对应的补偿值(在此函数之前已经计算得到)并进行补偿 */
void SAO::generateChromaOffsets(SaoCtuParam* ctuParam[3], int idxY, int idxX);


/* 统计当前CTU在BO和EO各模式下的像素归类:
重构像素与原始像素差值之和(保存在数组 m_offsetOrg 中),
像素种类 classIdx 的计数(保存在数组 m_count 中) */
void SAO::calcSaoStatsCTU(int addr, int plane);

/* 去方块滤波前对CTU的像素统计归类,
只有当 SAO 和 bSaoNonDeblocked 都开启的情况下才使用,因此暂时忽略 */
void SAO::calcSaoStatsCu_BeforeDblk(Frame* frame, int idxX, int idxY);


/* 计算CTU在各种模式下的最佳SAO代价,与直接采用左边或上面CTU的SAO参数作比较,找出最
优的SAO代价并将最优SAO模式下的各种参数保存在saoParam->ctuParam[plane][addr]中 */
void SAO::rdoSaoUnitCu(SAOParam* saoParam, int rowBaseAddr, int idxX, int addr);

/* 利用先前已得到的统计信息(即m_count和m_offsetOrg)计算初始补偿值(即m_offset) */
void SAO::saoStatsInitialOffset(int planes);

/* 计算率失真代价值,公式为:(失真 + lambda * 编码比特数)*/
inline int64_t SAO::calcSaoRdoCost(int64_t distortion, 
uint32_t bits, int64_t lambda);

/**
* @brief 估计中间过程的补偿值,即:在给定的SAO模式和某种类点的情况下,找到最优率失真代价及对应的补偿值和失真值.
* @param typeIdx : SAO模式,即 SAO_EO_X 和 SAO_BO
* @param lambda  : 拉格朗日乘子,取值依赖QP,即 256.0 * x265_lambda2_tab[qp]
* @param count   : typeIdx模式下,某classIdx的点的数目
* @param offsetOrg : 原始像素与重构像素(SAO补偿前)之间的差值之和
* @param offset[输出] : 最优率失真代价对应的补偿值
* @param distClasses[输出] : 最优率失真代价对应的失真
* @param costClasses[输出] : 最优率失真代价
*/
void SAO::estIterOffset(int typeIdx, int64_t lambda, int32_t count, 
int32_t offsetOrg, int32_t& offset, int32_t& distClasses, int64_t& costClasses);

/* 搜寻亮度最优SAO模式,得到最优率失真代价 */
void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int32_t addr, 
int64_t& rateDist, int64_t* lambda, int64_t &bestCost);

/* 搜寻色度最优SAO模式,得到最优率失真代价 */
void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int32_t addr, 
int64_t& rateDist, int64_t* lambda, int64_t &bestCost);

/* 统计某个CU内条带点数目及失真之和, count和stats分别记录了条带点计数和失真之和*/
void saoCuStatsBO_c(const int16_t *diff, const pixel *rec, intptr_t stride, 
int endX, int endY, int32_t *stats, int32_t *count);

/* 统计CU内的点在EO_0模式下的各种类点的数目及失真之和 */
void saoCuStatsE0_c(const int16_t *diff, const pixel *rec, intptr_t stride, 
int endX, int endY, int32_t *stats, int32_t *count)

/* 统计CU内的点在EO_1模式(垂直方向)下的各种类点的数目及失真之和 */
void saoCuStatsE1_c(const int16_t *diff, const pixel *rec, intptr_t stride, 
int8_t *upBuff1, int endX, int endY, int32_t *stats, int32_t *count);

/* 统计CU内的点在EO_2模式(135度方向)下的各种类点的数目及失真之和 */
void saoCuStatsE2_c(const int16_t *diff, const pixel *rec, intptr_t stride, int8_t 
    *upBuff1, int8_t *upBufft, int endX, int endY, int32_t *stats, int32_t *count);

/* 统计CU内的点在EO_3模式(45度方向)下的各种类点的数目及失真之和 */
void saoCuStatsE3_c(const int16_t *diff, const pixel *rec, intptr_t stride, 
int8_t *upBuff1, int endX, int endY, int32_t *stats, int32_t *count);

这里写图片描述
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/nk_wavelet/article/details/52662954