x265中除了传统的RD Cost外,还有Psy-RdCost和SSIM-RdCost,这三种RD Cost的使用是通过命令行参数控制的,如果不设置,则默认使用的是Psy-RDCost,相关命令行参数如下:

  • –[no-]psy-rd <0…5.0> Strength of psycho-visual rate distortion optimization, 0 to disable. Default 2.0
  • –[no-]psy-rdoq <0…50.0> Strength of psycho-visual optimization in RDO quantization, 0 to disable. Default 0.0
  • –[no-]ssim-rd Enable ssim rate distortion optimization, 0 to disable. Default disabled
  • –dynamic-rd <0…4.0> Strength of dynamic RD, 0 to disable. Default 0.00

一、Psycho-visual Rate Distortion

x265中计算Psy-RD Cost的公式如下:

其中D指的是重建块的失真,psyRD表示的是psy-RDCost的强度,psyCost是指的是重建块和原始块AC能量的差,Rate指的是编码当前块所需的码率,x265中计算PsyRDCost的代码如下:

 inline uint64_t calcPsyRdCost(sse_t distortion, uint32_t bits, uint32_t psycost) const{
#if X265_DEPTH < 10X265_CHECK((bits <= (UINT64_MAX / m_lambda2)) && (psycost <= UINT64_MAX / (m_lambda * m_psyRd)),"calcPsyRdCost wrap detected dist: %u, bits: %u, lambda: " X265_LL ", lambda2: " X265_LL "\n",distortion, bits, m_lambda, m_lambda2);
#elseX265_CHECK((bits <= (UINT64_MAX / m_lambda2)) && (psycost <= UINT64_MAX / (m_lambda * m_psyRd)),"calcPsyRdCost wrap detected dist: " X265_LL ", bits: %u, lambda: " X265_LL ", lambda2: " X265_LL "\n",distortion, bits, m_lambda, m_lambda2);
#endifreturn distortion + ((m_lambda * m_psyRd * psycost) >> 24) + ((bits * m_lambda2) >> 8);}

即psy-RD Cost比传统的RD Cost计算多了一项m_lambda * m_psyRd * psycost,其中m_lambda和QP有关,m_psyRd由命令行参数psy-rd控制,表示Psy-RD Cost的强度

 /* Scale PSY RD factor by a slice type factor */
static const uint32_t psyScaleFix8[3] = { 300, 256, 96 }; /* B, P, I */
m_psyRd = (m_psyRdBase * psyScaleFix8[slice.m_sliceType]) >> 8;
m_rdCost.setPsyRdScale(param.psyRd);
void setPsyRdScale(double scale)                { m_psyRdBase = (uint32_t)floor(65536.0 * scale * 0.33); }

psyRDCost的计算代码如下:

这里的psyRD表示重建块的AC energy和原始块的AC energy之差,即(这里不理解为什么像素块和0的SATD减去下其和0的SAD表示AC能量)

template<int size>
int psyCost_pp(const pixel* source, intptr_t sstride, const pixel* recon, intptr_t rstride)
{static pixel zeroBuf[8] /* = { 0 } */;if (size){int dim = 1 << (size + 2);uint32_t totEnergy = 0;for (int i = 0; i < dim; i += 8){for (int j = 0; j < dim; j+= 8){/* AC energy, measured by sa8d (AC + DC) minus SAD (DC) */int sourceEnergy = sa8d_8x8(source + i * sstride + j, sstride, zeroBuf, 0) - (sad<8, 8>(source + i * sstride + j, sstride, zeroBuf, 0) >> 2);int reconEnergy =  sa8d_8x8(recon + i * rstride + j, rstride, zeroBuf, 0) - (sad<8, 8>(recon + i * rstride + j, rstride, zeroBuf, 0) >> 2);totEnergy += abs(sourceEnergy - reconEnergy);}}return totEnergy;}else{/* 4x4 is too small for sa8d */int sourceEnergy = satd_4x4(source, sstride, zeroBuf, 0) - (sad<4, 4>(source, sstride, zeroBuf, 0) >> 2);int reconEnergy = satd_4x4(recon, rstride, zeroBuf, 0) - (sad<4, 4>(recon, rstride, zeroBuf, 0) >> 2);return abs(sourceEnergy - reconEnergy);}
}

二、SSIM Rate Distortion

x265中计算SSIM RD Cost的公式如下:

x265中的计算代码如下:

    inline uint64_t calcSsimRdCost(uint64_t distortion, uint32_t bits, uint32_t ssimCost) const{
#if X265_DEPTH < 10X265_CHECK((bits <= (UINT64_MAX / m_lambda2)) && (ssimCost <= UINT64_MAX / m_lambda),"calcPsyRdCost wrap detected dist: " X265_LL " bits: %u, lambda: " X265_LL ", lambda2: " X265_LL "\n",distortion, bits, m_lambda, m_lambda2);
#elseX265_CHECK((bits <= (UINT64_MAX / m_lambda2)) && (ssimCost <= UINT64_MAX / m_lambda),"calcPsyRdCost wrap detected dist: " X265_LL ", bits: %u, lambda: " X265_LL ", lambda2: " X265_LL "\n",distortion, bits, m_lambda, m_lambda2);
#endifreturn distortion + ((m_lambda * ssimCost) >> 14) + ((bits * m_lambda2) >> 8);}

其中SSIMCost为SSIM指标下的失真,SSIMCost的计算公式推导参考论文

x265中的计算如下

uint64_t Quant::ssimDistortion(const CUData& cu, const pixel* fenc, uint32_t fStride, const pixel* recon, intptr_t rstride, uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx)
{static const int ssim_c1 = (int)(.01 * .01 * PIXEL_MAX * PIXEL_MAX * 64 + .5); // 416static const int ssim_c2 = (int)(.03 * .03 * PIXEL_MAX * PIXEL_MAX * 64 * 63 + .5); // 235963int shift = (X265_DEPTH - 8);int trSize = 1 << log2TrSize;uint64_t ssDc = 0, ssBlock = 0, ssAc = 0;// Calculation of (X(0) - Y(0)) * (X(0) - Y(0)), DCssDc = 0; //ssDc 表示整个块内所有4x4为块的左上角像素差值的平方和for (int y = 0; y < trSize; y += 4){for (int x = 0; x < trSize; x += 4){int temp = fenc[y * fStride + x] - recon[y * rstride + x]; // copy of residual coeffssDc += temp * temp;}}// Calculation of (X(k) - Y(k)) * (X(k) - Y(k)), ACssBlock = 0; //ssBlock 表示整个块内的原始像素-重建像素的差值的平方和uint64_t ac_k = 0; //ac_k表示整个块内原始像素的平方和primitives.cu[log2TrSize - 2].ssimDist(fenc, fStride, recon, rstride, &ssBlock, shift, &ac_k);ssAc = ssBlock - ssDc;// 1. Calculation of fdc'// Calculate numerator of dc normalization factor 计算dc归一化因子的分子uint64_t fDc_num = 0;// 2. Calculate dc componentuint64_t dc_k = 0; //表示整个块内所有4x4为块的左上角像素平方和for (int block_yy = 0; block_yy < trSize; block_yy += 4){for (int block_xx = 0; block_xx < trSize; block_xx += 4){uint32_t temp = fenc[block_yy * fStride + block_xx] >> shift;dc_k += temp * temp;}}fDc_num = (2 * dc_k)  + (trSize * trSize * ssim_c1); // 16 pixels -> for each 4x4 blockfDc_num /= ((trSize >> 2) * (trSize >> 2));// 1. Calculation of fac'// Calculate numerator of ac normalization factoruint64_t fAc_num = 0;// 2. Calculate ac componentac_k -= dc_k;double s = 1 + 0.005 * cu.m_qp[absPartIdx];fAc_num = ac_k + uint64_t(s * ac_k) + ssim_c2;fAc_num /= ((trSize >> 2) * (trSize >> 2));// Calculate dc and ac normalization factoruint64_t ssim_distortion = ((ssDc * cu.m_fDc_den[ttype]) / fDc_num) + ((ssAc * cu.m_fAc_den[ttype]) / fAc_num);return ssim_distortion;
}

三、Rd SATD Cost

RD SATD Cost主要是用于帧内预测模式粗选的时候,为了降低复杂度,使用残差的哈达玛变换近似代替失真,这种方法省去了变换、量化、反量化、反变换等过程,可以大大降低复杂度。其计算公式如下:

其中,SATD表示原始块和预测块残差的SATD,Rmdoe仅为编码当前模式所需的比特数。

    inline uint64_t calcRdSADCost(uint32_t sadCost, uint32_t bits) const{X265_CHECK(bits <= (UINT64_MAX - 128) / m_lambda,"calcRdSADCost wrap detected dist: %u, bits %u, lambda: " X265_LL "\n", sadCost, bits, m_lambda);return sadCost + ((bits * m_lambda + 128) >> 8);}

x265中计算RD Cost的几种方式相关推荐

  1. Shell脚本中计算字符串长度的5种方法

    这篇文章主要介绍了Shell脚本中计算字符串长度的5种方法,来自于个人Shell脚本长期的开发经验,需要的朋友可以参考下 有时在Linux操作系统中需要计算某个字符串的长度,通过查询资料整理了下目前S ...

  2. html中获取modelandview中的json数据_从Bitmap中获取YUV数据的两种方式

    从Bitmap中我们能获取到的是RGB颜色分量,当需要获取YUV数据的时候,则需要先提取R,G,B分量的值,然后将RGB转化为YUV(根据具体的YUV的排列格式做相应的Y,U,V分量的排列) 所以这篇 ...

  3. python用于导入模块或模块中的对象_在 Python 中导入模块中的对象有哪几种方式? (5.0分)_学小易找答案...

    [判断题]尽管可以使用 import 语句一次导入任意多个标准库或扩展库,但是仍建议每次只导入一个标准库或扩展库. (2.0分) [填空题]表达式 int(str(34)) == 34 的值为 ___ ...

  4. 指针数组下标JAVA_Java语言中可用下标和指针两种方式表示数组元素。

    [判断题]一行可以写多条预处理命令 [判断题]如果一个java程序中有多个类,编译后只生成一个字节码文件,其名字同主类名一致. [判断题]Protected类型的实例变量只能在本类中使用,其他类中不可 ...

  5. 面试中sql调优的几种方式_面试方式

    面试中sql调优的几种方式 The first question I ask someone in an interview for a cybersecurity position is, &quo ...

  6. c语言中按照“|”字符串截取,shell中取字符串子串的几种方式 截取substr

    echo "123456789" | awk '{print substr($0,5,2)}' 截取 1)awk中函数substr substr(源字符串,开始索引,长度)   开 ...

  7. JavaScript——关于JavaScript、在HTML中嵌入JS代码的三种方式、变量

    文章目录 JavaScript 01 关于JavaScript 1.1 JS的发展历史 1.2 JS的特性 1.3 JS的组成 1.4 JSP和JS的区别 02 在HTML中嵌入JS代码的三种方式 2 ...

  8. Google Adsense收入计算以及提高的5种方式

    Google Adsense赚钱在资深博主圈已经很普及了,本站也投放了Google Adsense广告,每月自动结算,曾经我在本站分享了"在博客上启用Adsense自动广告获利(https: ...

  9. 把一个数组的值存入二叉树中,然后利用前序、中序、后序3种方式进行遍历(完整代码以及运行结果)(Java)

    把一个数组的值存入二叉树中,然后利用前序.中序.后序3种方式进行遍历(完整代码以及运行结果) 在最近的面试过程中,听说有小伙伴被面试官要求创建二叉树,然后对该二叉树进行遍历,感觉这一直以来都是一个大家 ...

最新文章

  1. 北纬39°54上的采访
  2. 设计模式之代理模式学习笔记
  3. JVM 垃圾回收算法 -可达性分析算法!!!高频面试!!!
  4. 有上下界的网络流1-无源汇带上下界网络流SGU194
  5. php中append,插入节点append()、insertAfter()的特殊用法:对原有DOM元素进行移动
  6. 域名可以转让注册人吗_网店可以转让吗?
  7. Python 基本数据类型 (二) - 字符串
  8. python没有tkinter_Python升级提示Tkinter模块找不到的解决方法
  9. 定时更换超级连接的代码
  10. Java JDBC Statement
  11. 程序包sun.misc不存在
  12. AWS的下一站:3.8万亿美元的企业IT市场
  13. 【食品加工技术】第一章 食品加工技术概述 笔记
  14. MOSFET管驱动电路的设计
  15. NCBI|宏基因组原始数据上传
  16. Thinkphp中的assign() 和 display()
  17. python 中文字符转换
  18. 3389常用命令操作
  19. python使用loaddata_Python data.load_data方法代码示例
  20. 不得了了!刚刚腾讯官宣 Python 开发人才这样选

热门文章

  1. Android 利用系统下载管理器下载apk
  2. JS实现简易ATM机
  3. 二维火收银系统服务器超时,二维火收银系统,改变的不止是你的收银模式!
  4. iso镜像添加软件包_Linux系统自定义制作ISO安装镜像
  5. 自定义View之仿淘宝详情页
  6. 记录一个数学知识:求向量在指定平面上的垂直向量
  7. Python数据分析与可视化——NumPy数组
  8. S5P4418:RTC芯片HYM8563驱动移植
  9. datagrip mysql 驱动_Datagrip2020下载MySQL驱动失败的问题
  10. 数字图像学笔记——14. 图像退化与复原(线性退化)