【HEVC】2、HM-16.7编码一个CU(帧内部分) 1.帧内预测相邻参考像素获取
HEVC帧内预测的35中预测模式是在PU基础上定义的,实际帧内预测的过程则以TU为单位。PU以四叉树划分TU,一个PU内所有TU共享同一种预测模式。帧内预测分3个步骤:
(1) 判断当前TU相邻像素点是否可用并做相应的处理
(2) 对参考像素进行滤波
(3) 根据滤波后的参考像素计算当前TU的预测像素值。
HM-16.7中fillReferenceSamples()主要实现第一个步骤,真正进行帧内预测之前,使用重建后的Yuv图像对当前PU的相邻样点进行赋值,为接下来进行的角度预测提供参考样点值,对应于draft 8.4.4.2.2的内容。主要过程是:
(1)如果所有相邻点均不可用,则参考样点值均被赋值为DC值;
iDCValue = 1 << (bitDepth - 1),对于8bit像素,该值为128。
(2)如果所有相邻点均可用,则参考样点值都会被赋值为重建Yuv图像中与其位置相同的样点值;
(3)如果不满足上述两个条件,则按照从左下往左上,从左上往右上的扫描顺序进行遍历,如果第一个点不可用,则使用下一个可用点对应的重建Yuv样点值对其进行赋值;对于除第一个点外的其它邻点,如果该点不可用,则使用它的前一个样点值进行赋值(前一个步骤保证了前一个样点值一定是存在的),直到遍历完毕。
Void fillReferenceSamples( const Int bitDepth,
#if O0043_BEST_EFFORT_DECODING
const Int bitDepthDelta,
#endif
const Pel* piRoiOrigin,
Pel* piIntraTemp,
const Bool* bNeighborFlags,
const Int iNumIntraNeighbor,
const Int unitWidth,
const Int unitHeight,
const Int iAboveUnits,
const Int iLeftUnits,
const UInt uiWidth,
const UInt uiHeight,
const Int iPicStride )
{
const Pel* piRoiTemp;//piRoiOrgin指向重建Yuv图像对应于当前PU所在位置的首地址,piRoiTemp用于指向所感兴趣的重建Yuv的位置
Int i, j;
Int iDCValue = << (bitDepth - );//参考像素不可用时的填充值,8bit时候为128.
const Int iTotalUnits = iAboveUnits + iLeftUnits + ; //+1 for top-left //以4个像素点为单位标记,其中左上角单独标记 if (iNumIntraNeighbor == ) // all samples are not available
{
// Fill border with DC value
for (i=; i<uiWidth; i++) //!< AboveLeft + Above + AboveRight
{
piIntraTemp[i] = iDCValue;
}
for (i=; i<uiHeight; i++)//!< Left + BelowLeft
{
piIntraTemp[i*uiWidth] = iDCValue;
}
}
else if (iNumIntraNeighbor == iTotalUnits)// all samples are available
{
// Fill top-left border and top and top right with rec. samples
piRoiTemp = piRoiOrigin - iPicStride - ; //!< AboveLeft for (i=; i<uiWidth; i++)
{
#if O0043_BEST_EFFORT_DECODING
piIntraTemp[i] = piRoiTemp[i] << bitDepthDelta;
#else
piIntraTemp[i] = piRoiTemp[i];
#endif
} // Fill left and below left border with rec. samples
piRoiTemp = piRoiOrigin - ; for (i=; i<uiHeight; i++)
{
#if O0043_BEST_EFFORT_DECODING
piIntraTemp[i*uiWidth] = (*(piRoiTemp)) << bitDepthDelta;
#else
piIntraTemp[i*uiWidth] = *(piRoiTemp);//!< 每个参考样点赋值为对应位置重建Yuv样点值
#endif
piRoiTemp += iPicStride;//!< 指向重建Yuv下一行
}
}
else // reference samples are partially available
{
// all above units have "unitWidth" samples each, all left/below-left units have "unitHeight" samples each
//!< neighboring samples的总数
const Int iTotalSamples = (iLeftUnits * unitHeight) + ((iAboveUnits + ) * unitWidth);
Pel piIntraLine[ * MAX_CU_SIZE];
Pel *piIntraLineTemp;//!<临时存储用于填充neighboring samples的样点值
const Bool *pbNeighborFlags;//保存以四个像素点为单位的可用性 // Initialize
for (i=; i<iTotalSamples; i++)
{
piIntraLine[i] = iDCValue;
} // Fill top-left sample
piRoiTemp = piRoiOrigin - iPicStride - ;//!< 指向重建Yuv左上角
piIntraLineTemp = piIntraLine + (iLeftUnits * unitHeight);//!< piAdiLine的扫描顺序为左下到左上,再从左到右上
pbNeighborFlags = bNeighborFlags + iLeftUnits;//!< 标记neighbor可用性的数组同样移动至左上角
if (*pbNeighborFlags)//!< 如果左上角可用,则左上角4个像素点均赋值为重建Yuv左上角的样点值
{
#if O0043_BEST_EFFORT_DECODING
Pel topLeftVal=piRoiTemp[] << bitDepthDelta;
#else
Pel topLeftVal=piRoiTemp[];
#endif
for (i=; i<unitWidth; i++)
{
piIntraLineTemp[i] = topLeftVal;
}
} // Fill left & below-left samples (downwards)
piRoiTemp += iPicStride;//!< piRoiTemp指向重建Yuv的左边界
piIntraLineTemp--;//移动指针至左边界
pbNeighborFlags--;//移动指针至左边界 for (j=; j<iLeftUnits; j++)//从左向左下扫描
{
if (*pbNeighborFlags)//如果可用
{
for (i=; i<unitHeight; i++)//!< 每个4x4块里的4个样点分别被赋值为对应位置的重建Yuv的样点值
{
#if O0043_BEST_EFFORT_DECODING
piIntraLineTemp[-i] = piRoiTemp[i*iPicStride] << bitDepthDelta;
#else
piIntraLineTemp[-i] = piRoiTemp[i*iPicStride];
#endif
}
}
piRoiTemp += unitHeight*iPicStride;//!< 指针挪到下一个行(以4x4块为单位,即实际上下移了4行)
piIntraLineTemp -= unitHeight;//!< 指针下移
pbNeighborFlags--;//!< 指针下移
} // Fill above & above-right samples (left-to-right) (each unit has "unitWidth" samples)
piRoiTemp = piRoiOrigin - iPicStride;//!< piRoiTemp 指向重建Yuv的上边界
// offset line buffer by iNumUints2*unitHeight (for left/below-left) + unitWidth (for above-left)
piIntraLineTemp = piIntraLine + (iLeftUnits * unitHeight) + unitWidth;
pbNeighborFlags = bNeighborFlags + iLeftUnits + ;
for (j=; j<iAboveUnits; j++) //!< 从左扫描至右上
{
if (*pbNeighborFlags)//如果可用
{
for (i=; i<unitWidth; i++)//!< 每个4x4块里的4个样点分别被赋值为对应位置的重建Yuv的样点值
{
#if O0043_BEST_EFFORT_DECODING
piIntraLineTemp[i] = piRoiTemp[i] << bitDepthDelta;
#else
piIntraLineTemp[i] = piRoiTemp[i];
#endif
}
}
piRoiTemp += unitWidth;//!< 指针右移,实际是右移了4
piIntraLineTemp += unitWidth;//!< 指针右移,实际是右移了4
pbNeighborFlags++;//!< 指针右移,以4个像素点为单位标记可用性
} // Pad reference samples when necessary
Int iCurrJnit = ;
Pel *piIntraLineCur = piIntraLine;//!< 指向左下角(纵坐标最大的那个位置,即扫描起点)
const UInt piIntraLineTopRowOffset = iLeftUnits * (unitHeight - unitWidth); if (!bNeighborFlags[])
{
// very bottom unit of bottom-left; at least one unit will be valid.
{
Int iNext = ;
while (iNext < iTotalUnits && !bNeighborFlags[iNext])
{
iNext++;
}
Pel *piIntraLineNext = piIntraLine + ((iNext < iLeftUnits) ? (iNext * unitHeight) : (piIntraLineTopRowOffset + (iNext * unitWidth)));
const Pel refSample = *piIntraLineNext;
// Pad unavailable samples with new value
Int iNextOrTop = std::min<Int>(iNext, iLeftUnits);
// fill left column
while (iCurrJnit < iNextOrTop) //!< 遍历所有neighboring samples
{
for (i=; i<unitHeight; i++)
{
piIntraLineCur[i] = refSample;
}
piIntraLineCur += unitHeight;
iCurrJnit++;
}
// fill top row
while (iCurrJnit < iNext)
{
for (i=; i<unitWidth; i++)
{
piIntraLineCur[i] = refSample;
}
piIntraLineCur += unitWidth;
iCurrJnit++;
}
}
} // pad all other reference samples.
while (iCurrJnit < iTotalUnits)
{
if (!bNeighborFlags[iCurrJnit]) // samples not available
{
{
const Int numSamplesInCurrUnit = (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
const Pel refSample = *(piIntraLineCur-);
for (i=; i<numSamplesInCurrUnit; i++)
{
piIntraLineCur[i] = refSample;
}
piIntraLineCur += numSamplesInCurrUnit;
iCurrJnit++;
}
}
else
{
piIntraLineCur += (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
iCurrJnit++;
}
} // Copy processed samples piIntraLineTemp = piIntraLine + uiHeight + unitWidth - ;
// top left, top and top right samples
for (i=; i<uiWidth; i++)
{
piIntraTemp[i] = piIntraLineTemp[i];
} piIntraLineTemp = piIntraLine + uiHeight - ;
for (i=; i<uiHeight; i++)
{
piIntraTemp[i*uiWidth] = piIntraLineTemp[-i];
}
}
}
【HEVC】2、HM-16.7编码一个CU(帧内部分) 1.帧内预测相邻参考像素获取的更多相关文章
- 【HEVC】4、HM-16.7编码一个CU(帧内部分) 3.帧内预测各种模式实现
HEVC中一共定义了35中帧内编码预测模式,编号分别以0-34定义.其中模式0定义为平面模式(INTRA_PLANAR),模式1定义为均值模式(INTRA_DC),模式2~34定义为角度预测模式(IN ...
- HM中字典编码分析
LZ77算法基本过程 http://jpkc.zust.edu.cn/2007/dmt/course/MMT03_05_2.htm LZ77压缩算法详解 http://wenku.baidu.com/ ...
- JSON C# Class Generator是一个从JSON文本中生成C#内的应用程序
JSON C# Class Generator是一个从JSON文本中生成C#内的应用程序 .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator ...
- 判断一个IP地址是否是本局域网内地址
// /// <summary> /// 判断一个IP地址是否是本局域网内地址,是返回true 否则返回false, /// </summa ...
- TensorFlow-Bitcoin-Robot:一个基于 TensorFlow LSTM 模型的 Bitcoin 价格预测机器人
简介 TensorFlow-Bitcoin-Robot:一个基于 TensorFlow LSTM 模型的 Bitcoin 价格预测机器人. 文章包括一下几个部分: 1.为什么要尝试做这个项目? 2.为 ...
- TensorFlow-Bitcoin-Robot:一个基于 TensorFlow LSTM 模型的 Bitcoin 价格预测机器人。
简介 TensorFlow-Bitcoin-Robot:一个基于 TensorFlow LSTM 模型的 Bitcoin 价格预测机器人. 文章包括一下几个部分: 1.为什么要尝试做这个项目? 2.为 ...
- 【python系统学习16】编码基础知识
编码 计算机是怎么传输和存储数据的? 就是把人类认识的中英文字.其他国家语言.数字甚至运算符等符号转成二进制的0.1,并进行存储和传输. 编码 人类语言:中英文字.其他国家语言.数字甚至运算符等符号 ...
- CI Weekly #16 | 从另一个角度看开发效率:flow.ci 数据统计功能上线
很开心的告诉大家,flow.ci 数据统计功能已正式上线. 进入 flow.ci 控制台,点击「数据分析」按钮,你可以按照时间日期筛选,flow.ci 将多维度地展示「组织与项目」的构建数据指标与模型 ...
- 13.14.15.16.17&《一个程序猿的生命周期》读后感
13.TDS 的标准是什么,怎么样才能认为他是一个标准的TDS?? 14.软件的质量包括哪些方面,如何权衡软件的质量? 15.如何解决功能与时间的矛盾,优秀的软件团队会发布有已知缺陷的软件么? 16. ...
随机推荐
- dapper 学习
上一篇, 提到Query<Test>查询的时候, 如果Test中包含自定义class, Dapper不会给自定义class完成映射, 而是直接给null, 其实是可以实现的, 答案就在下面 ...
- vs2010配置boost编程环境(照抄并简化)
第一步:下载boost,我下载的方法是从http://www.boost.org/上找最新的下载.名字叫boost_1_50_0.7z. 第二步:在D盘(我C盘空间不大,准备出至少10G的空间吧)创建 ...
- 获取应用程序信息.h
//// 获取应用程序信息.h// IOS笔记// 一般会用来判断是否有新版本.是否需要强制更新 iOS的版本号,一个叫做Version,一个叫做Build,这两个值都可以在Xcode 中选中ta ...
- ie 8 下post提交提交了两次
擦你吗呀,IE8! 老子写一个登录功能,IE他妈的给我登录了两次,导致权限校验错误,什么他妈的鬼问题,调了两天....fuck,都是泪水. 解决方案:提交按钮加返回值<input type=&q ...
- nwjs 配置文件package.json 转载
配置文件package.json nw在启动应用程序时,首先要读取package.json文件,初始化基本属性,下面我们看看package.json的完整参数.每个参数配置都标有注释. { /**指定 ...
- Win8.1离线安装.NET3.5
Win8.1离线安装.NET3.5 dism.exe /online /enable-feature /featurename:NetFX3 /Source:H:\sources\sxs 其中H为盘符 ...
- 你应该知道的那些Android小经验
原文出处:http://jayfeng.com/ 做Android久了,就会踩很多坑,被坑的多了就有经验了,闲暇之余整理了部分,现挑选一些重要或者偏门的“小”经验做个记录. 查看SQLite日志 ad ...
- html5 EvnetSource 与 JSP页面结合使用
最近一直在研究前端的技术,特别是html5的技术,本人觉得html5的发展将越来越好,废话少说.看到了EventSource,根据官方的说法是服务器向客户端的推送服务.自己想找一些例子看看,发现都是P ...
- 关于回溯与n个数的全排列
今天要讲的题目是全排列的问题:有1.2.3.....n这样一个数列,要求输出其全排列. 那么,显然,这道题目非常之简单,用一个标志数组变量,标记数字的使用情况,然后根据它挑选数字即可.由于题目很简单, ...
- VS高效开发快捷键
Ctrl + Tab 标签切换 Ctrl + '-'向后导航 Ctrl + Shift+'-'向前导航 Ctrl +Shift +空格 提示函数参数 Ctrl +F4 退出本标签 Ctrl+F 查找 ...