关于SAO的原理和流程的解析,已经在我转载的一篇博客HEVC中SAO--自适应样点补偿 详细分析解读有了比较清楚的介绍了,本文就不再重复这个过程,而把主要精力放在具体函数实现的解析上。在我自己的一篇博客HEVC学习(八) —— 以SAO为例浅析跟踪代码方法里其实也作了相关的铺垫了,当中重点放在跟踪代码的方法上,本文在此基础上对重要的函数进行解析,它们的调用位置这里就不提了,有关这部分的内容请参考前述的两篇博客。
本文首先介绍
m_cEncSAO.create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, _uiMaxCUDepth );
该函数为SAO的相关参数分配内存和初始化。
/** create SampleAdaptiveOffset memory.
* \param
*/
Void TComSampleAdaptiveOffset::create( UInt uiSourceWidth, UInt uiSourceHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth)
{
m_iPicWidth = uiSourceWidth;
m_iPicHeight = uiSourceHeight;
m_uiMaxCUWidth = uiMaxCUWidth;
m_uiMaxCUHeight = uiMaxCUHeight;
m_iNumCuInWidth = m_iPicWidth / m_uiMaxCUWidth;
m_iNumCuInWidth += ( m_iPicWidth % m_uiMaxCUWidth ) ? 1 : 0;
m_iNumCuInHeight = m_iPicHeight / m_uiMaxCUHeight;
m_iNumCuInHeight += ( m_iPicHeight % m_uiMaxCUHeight ) ? 1 : 0;
//! 以下四句根据CU的实际尺寸计算可划分的最大深度
Int iMaxSplitLevelHeight = (Int)(logf((Float)m_iNumCuInHeight)/logf(2.0));
Int iMaxSplitLevelWidth = (Int)(logf((Float)m_iNumCuInWidth )/logf(2.0));
m_uiMaxSplitLevel = (iMaxSplitLevelHeight < iMaxSplitLevelWidth)?(iMaxSplitLevelHeight):(iMaxSplitLevelWidth);
m_uiMaxSplitLevel = (m_uiMaxSplitLevel< m_uiMaxDepth)?(m_uiMaxSplitLevel):(m_uiMaxDepth);
/* various structures are overloaded to store per component data.
* m_iNumTotalParts must allow for sufficient storage in any allocated arrays */
/*
const Int TComSampleAdaptiveOffset::m_aiNumCulPartsLevel[5] =
{
1, //level 0
5, //level 1
21, //level 2
85, //level 3
341, //level 4
};
*/
m_iNumTotalParts = max(3,m_aiNumCulPartsLevel[m_uiMaxSplitLevel]);
UInt uiPixelRangeY = 1 << g_bitDepthY; //!< Y分量的像素范围(256 for 8it-depth)
UInt uiBoRangeShiftY = g_bitDepthY - SAO_BO_BITS; //!< Band Offset (BO)中每个band的宽度(3 for 8bit-depth,即1<<3 = 8)(Y分量)
m_lumaTableBo = new Pel [uiPixelRangeY]; //!< Y分量在BO模式下的索引表,根据像素值可以索引到对应的band序号
for (Int k2=0; k2<uiPixelRangeY; k2++)
{
m_lumaTableBo[k2] = 1 + (k2>>uiBoRangeShiftY); //!< 总共分了32个band(1~32)
}
UInt uiPixelRangeC = 1 << g_bitDepthC; //!< CbCr分量的像素范围(256 for 8it-depth)
UInt uiBoRangeShiftC = g_bitDepthC - SAO_BO_BITS; //!< Band Offset (BO)中每个band的宽度(3 for 8bit-depth,即1<<3 = 8)(CbCr分量)
m_chromaTableBo = new Pel [uiPixelRangeC]; //!< CbCr分量在BO模式下的索引表,根据像素值可以索引到对应的band序号
for (Int k2=0; k2<uiPixelRangeC; k2++)
{
m_chromaTableBo[k2] = 1 + (k2>>uiBoRangeShiftC); //!< 总共分了32个band(1~32)
}
m_iUpBuff1 = new Int[m_iPicWidth+2];
m_iUpBuff2 = new Int[m_iPicWidth+2];
m_iUpBufft = new Int[m_iPicWidth+2];
m_iUpBuff1++;
m_iUpBuff2++;
m_iUpBufft++;
Pel i;
UInt uiMaxY = (1 << g_bitDepthY) - 1; //!< Y分量像素最大值(255 for 8bit-depth)
UInt uiMinY = 0;
Int iCRangeExt = uiMaxY>>1; //!< 对范围进行扩展
m_pClipTableBase = new Pel[uiMaxY+2*iCRangeExt];
m_iOffsetBo = new Int[uiMaxY+2*iCRangeExt];
for(i=0;i<(uiMinY+iCRangeExt);i++)
{
m_pClipTableBase[i] = uiMinY;
}
for(i=uiMinY+iCRangeExt;i<(uiMaxY+ iCRangeExt);i++)
{
m_pClipTableBase[i] = i-iCRangeExt;
}
for(i=uiMaxY+iCRangeExt;i<(uiMaxY+2*iCRangeExt);i++)
{
m_pClipTableBase[i] = uiMaxY;
}
//! 0 0 0 ... 0 1 2 3 4 ... 255 255 ... 255//!
m_pClipTable = &(m_pClipTableBase[iCRangeExt]); //!< 查找表
UInt uiMaxC = (1 << g_bitDepthC) - 1; //!< CbCr分量像素最大值(255 for 8bit-depth)
UInt uiMinC = 0;
Int iCRangeExtC = uiMaxC>>1; //!< 对范围进行扩展
m_pChromaClipTableBase = new Pel[uiMaxC+2*iCRangeExtC];
m_iChromaOffsetBo = new Int[uiMaxC+2*iCRangeExtC];
for(i=0;i<(uiMinC+iCRangeExtC);i++)
{
m_pChromaClipTableBase[i] = uiMinC;
}
for(i=uiMinC+iCRangeExtC;i<(uiMaxC+ iCRangeExtC);i++)
{
m_pChromaClipTableBase[i] = i-iCRangeExtC;
}
for(i=uiMaxC+iCRangeExtC;i<(uiMaxC+2*iCRangeExtC);i++)
{
m_pChromaClipTableBase[i] = uiMaxC;
}
//! 0 0 0 ... 0 ! 1 2 3 4 ... 255 255 ... 255 //!
m_pChromaClipTable = &(m_pChromaClipTableBase[iCRangeExtC]); //!< 查找表,实际上与Y分量是相同的
m_iLcuPartIdx = new Int [m_iNumCuInHeight*m_iNumCuInWidth];
m_pTmpL1 = new Pel [m_uiMaxCUHeight+1];
m_pTmpL2 = new Pel [m_uiMaxCUHeight+1];
m_pTmpU1 = new Pel [m_iPicWidth];
m_pTmpU2 = new Pel [m_iPicWidth];
}
直观起见,不妨把m_lumaTableBo和m_pClipTable的内容打印出来,
/* m_lumaTableBo */
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9
10 10 10 10 10 10 10 10
11 11 11 11 11 11 11 11
12 12 12 12 12 12 12 12
13 13 13 13 13 13 13 13
14 14 14 14 14 14 14 14
15 15 15 15 15 15 15 15
16 16 16 16 16 16 16 16
17 17 17 17 17 17 17 17
18 18 18 18 18 18 18 18
19 19 19 19 19 19 19 19
20 20 20 20 20 20 20 20
21 21 21 21 21 21 21 21
22 22 22 22 22 22 22 22
23 23 23 23 23 23 23 23
24 24 24 24 24 24 24 24
25 25 25 25 25 25 25 25
26 26 26 26 26 26 26 26
27 27 27 27 27 27 27 27
28 28 28 28 28 28 28 28
29 29 29 29 29 29 29 29
30 30 30 30 30 30 30 30
31 31 31 31 31 31 31 31
32 32 32 32 32 32 32 32
/* m_pClipTable */
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
更直观的做法就是绘制出像素值vs索引值的曲线图来,不过根据这些数据,相信大家很容易就能想象出这两条曲线是何种形状的了,这里就不必要画出图来了。