ALL-intra模式,图片832X480,BasketballDrill_832x480_50.yuv。
从compressCTU进入conpressCu(),第一个CTU为128 x 128
1.当前CTU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | *tempCS | {area={x = 0, y = 0, width = 128, height = 128} picture=0x00000292d80d4e40 {x = 0, y = 0, width = 832, height = 480} …} | CodingStructure |
initCULevel():
名称 | 值 | 类型 | |
---|---|---|---|
maxDepth | 4 | unsigned int |
VTM1.0代码阅读:EncModeCtrl类_矛盾统一的博客-CSDN博客
m_ComprCUCtxList:先加入QT.CU-DONT-SPLIT再加入intra模式
但注意:intra模式在 initCULevel()函数最后一段的tryModeMaster()中被跳过了,所以现在栈里只有QT划分模式
具体流程看
VTM图像划分过程的tryModeMaster()函数,getImplicitSplit()(隐式分割)如何在CTU初划分时跳过intra_青椒鸡汤的博客-CSDN博客
其中 CU-DONT-SPLIT模式的消除具体看,中间有一小段写了(其中的trymode函数还没写)
xcompressCU函数中划分模式的确定_青椒鸡汤的博客-CSDN博客
isModeSplit( currTestMode):根据当前栈顶模式选择,当前为QT。
signalModeConsVal:0,跟随父节点。表明当前块的modetype应与父节点相同
xCheckModeSplit():
splitCurrArea():将CTU划分并取得划分后各个CU的位置与长宽信息
图像划分过程中的splitCurrArea()函数以及其中的getCUSubPartitions()函数_青椒鸡汤的博客-CSDN博客
initSubStructure()函数_青椒鸡汤的博客-CSDN博客
首先进行压缩的是划分后的第一个CU,当前为
{x = 0, y = 0, width = 64, height = 64}
然后根据当前要压缩的区域推出新的
tempSubCS
和
bestSubCS
,还有newMaxCostAllowed,在调用xCompressCU()函数时传入,变为新区域的
tempCS
和
bestCS
,
maxcostallowed
。
2.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | *tempCS | {area={x = 0, y = 0, width = 64, height = 64} picture=0x000001e025765e40 {x = 0, y = 0, width = 832, height = 480} …} | CodingStructure |
initCULevel():先加入QT.CD再加入intra模式。此CU未执行nextmode()函数,intra模式在栈顶
intra模式运行完后用while循环里的nextmode()去除栈顶的intra,现在为QT划分模式
xCheckModeSplit():继续QT划分
当前为
{x = 0, y = 0, width = 32, height = 32}
3.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | cs | {area={x = 0, y = 0, width = 32, height = 32} picture=0x000001e025765e40 {x = 0, y = 0, width = 832, height = 480} …} | const CodingStructure & |
initCULevel():加入TH,TV,BV,BH,QT,CD, intra栈顶
signalModeConsVal:0
xCheckModeSplit():继续QT划分
4.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | *tempCS | {area={x = 0, y = 0, width = 16, height = 16} picture=0x000001e025765e40 {x = 0, y = 0, width = 832, height = 480} …} | CodingStructure |
initCULevel():加入QT,TV,YJ,BV,BH ,CD intra栈顶
signalModeConsVal:0
xCheckModeSplit():BH划分
5.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 0, y = 0, width = 16, height = 8} | const UnitArea & |
initCULevel():加入QT,TV,BV,BH ,CD intra栈顶
xCheckModeSplit():BH划分
6.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
◢ | subCUArea | {x = 0, y = 0, width = 16, height = 4} | const UnitArea & |
initCULevel():加入QT,TV,BV ,CDONT intra栈顶
xCheckModeSplit():BV划分
7.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 0, y = 0, width = 8, height = 4} | const UnitArea & |
initCULevel():加入QT,CDONT intra栈顶
此时intra模式测试完后,在while循环nextmode()中的tryModeMaster()里的tryMode()函数满足条件,使得栈里剩下来的QT,CDONT 模式都被消除
当前栈中没有测试的模式
所以当前CU不再划分,转到上一个xCheckModeSplit()中,
当前CU依然是{x = 0, y = 0, width = 8, height = 4}
经过一系列检验,最后在while循环里的nextpart()函数进入当前
父CU{x = 0, y = 0, width = 16, height = 4}
划分的下一个子CU中开始测试
QTBTPartitioner::nextPart()和exitCurrSplit()函数解析_青椒鸡汤的博客-CSDN博客
xCheckModeSplit()中的useSubStructure()函数,releaseIntermediateData()函数解析(getBuf()函数没看)_青椒鸡汤的博客-CSDN博客
8
.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 8, y = 0, width = 8, height = 4} | const UnitArea & |
initCULevel():加入QT,CDONT intra栈顶
和上面一样,QT,CDONT被取消
回到xCheckModeSplit()中继续运行,因为当前
父CU{x = 0, y = 0, width = 16, height = 4}
划分的两个子CU都已经测试完,所以xCheckModeSplit()中的while循环也结束了。此时运行partitioner.exitCurrSplit()
下面就是关于RDcost的一些计算,计算当前
CU{x = 0, y = 0, width = 16, height = 4}
BV划分方式的RDcost是否上传到bestCS中
xCheckBestMode()和useModeResult()函数解析 (未写完,6.11写)_青椒鸡汤的博客-CSDN博客
xCheckModeSplit()函数中的RDcost(还没写,6.11写)_青椒鸡汤的博客-CSDN博客
然后到xCompressCU()函数,在for循环(869行)完以后,i++,因为numRoundRdo = 1,所以跳出for循环
进入while循环的nextMode()函数,先更新m_ComprCUCtxList中的
lastTestMode
,从
intra
变为当前的
BV
。再把BV从testModes中去掉,此时要测试的模式就变成了
TV
9
.当前CU
{area={x = 0, y = 0, width = 16, height = 4}
,
signalModeConsVal:0
要测试的模式为:TV
xCheckModeSplit():在splitCurrArea()函数中更新了m_partStack中的split和parts
此时已分成三个CU
10
.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 0, y = 0, width = 4, height = 4} | const UnitArea & |
initCULevel():加入QT,CDONT intra栈顶
和上面一样,QT,CDONT被取消
xCheckModeSplit():循环到下一个CU
11.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 4, y = 0, width = 8, height = 4} | const UnitArea & |
initCULevel():加入QT,CDONT intra栈顶
和上面一样,QT,CDONT被取消
xCheckModeSplit():循环到下一个CU
12.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 12, y = 0, width = 4, height = 4} | const UnitArea & |
initCULevel():加入QT,CDONT intra栈顶
和上面一样,QT,CDONT被取消
xCheckModeSplit():当前{area={x = 0, y = 0, width = 16, height = 4} 的三个子CU已经测试完,跳出循环。测试下一个模式
13
.当前CU
{area={x = 0, y = 0, width = 16, height = 4}
,
进入while循环的nextMode()函数,因为满足了条件,栈里的QT也被消去,所以跳出while循环,这个CU就把所有模式都测试完了
进入
finishCULevel
():在运行完以后,m_ComprCUCtxList的size减少了1.原本的那层已没有其他模式,所以当前CU已经算测试完了,就把栈中这个CU的信息消去,返回上一层父CU
xCheckModeSplit():循环到当前层的下一个CU
14
.当前CU
名称 | 值 | 类型 | |
---|---|---|---|
▶ | subCUArea | {x = 0, y = 4, width = 16, height = 4} | const UnitArea & |
然后循环下去。总的来说,就是每个块的不同划分模式都做一遍,最后比较效果。QT划分的块,测试顺序是光栅扫描顺序,即Z字形。
之后有进度再补充