Predict::initAdiPattern()

/*
	在进行帧内预测前,对PU的边界参考像素进行填充及平滑滤波

	过程:
		1.得到tu的size即size*2
		2.取reconYUV
		3.对neighbor不可用参考像素进行填充
		4.分别取topLeft、topLast、leftLast像素
		5.进行平滑滤波
			·若tusize为32x32,且允许强平滑滤波,则使用强平滑滤波
				1.计算阈值,并分别取topMiddle和leftMiddle像素值
				2.若若上边的 (最左边+最右边)-中间*2小于阈值,且左边的 (最上边+最下边)-中间*2 小于 阈值,则使用强双线性差值进行平滑滤波
			·否则,进行常规平滑滤波
*/
void Predict::initAdiPattern(const CUData& cu, const CUGeom& cuGeom, uint32_t puAbsPartIdx, const IntraNeighbors& intraNeighbors, int dirMode)
{
	//得到tu的像素size
    int tuSize = 1 << intraNeighbors.log2TrSize;
	//得到tu的像素的两倍
    int tuSize2 = tuSize << 1;

	//取reconPic
    PicYuv* reconPic = cu.m_encData->m_reconPic;
    pixel* adiOrigin = reconPic->getLumaAddr(cu.m_cuAddr, cuGeom.absPartIdx + puAbsPartIdx);
    intptr_t picStride = reconPic->m_stride;

	//进行neighbor不可用参考像素进行填充,输出到intraNeighbourBuf[0]中
    fillReferenceSamples(adiOrigin, picStride, intraNeighbors, intraNeighbourBuf[0]);

    pixel* refBuf = intraNeighbourBuf[0];	//unfiltered参考像素
    pixel* fltBuf = intraNeighbourBuf[1];	//filtered参考像素

	//取左上角像素、上边的最右边像素、左边的最下边像素
    pixel topLeft = refBuf[0], topLast = refBuf[tuSize2], leftLast = refBuf[tuSize2 + tuSize2];

	/*	若所有帧内预测方向都允许 && tuSize为8/16/32之间一种,
		或当前tuSize的当前预测方向允许平滑滤波,
		则进行平滑滤波	*/
    if (dirMode == ALL_IDX ? (8 | 16 | 32) & tuSize : g_intraFilterFlags[dirMode] & tuSize)
    {
        // generate filtered intra prediction samples

		//使用强帧内预测平滑 && tusize为32x32pixel,则进行强平滑滤波
        if (cu.m_slice->m_sps->bUseStrongIntraSmoothing && tuSize == 32)
        {
			//计算阈值
            const int threshold = 1 << (X265_DEPTH - 5);

			//取上边的中间像素,左边的中间像素
            pixel topMiddle = refBuf[32], leftMiddle = refBuf[tuSize2 + 32];

			/*	若上边的 (最左边+最右边)-中间*2 小于 阈值,
				且左边的 (最上边+最下边)-中间*2 小于 阈值,
				则使用强双线性差值进行平滑滤波	*/
            if (abs(topLeft + topLast  - (topMiddle  << 1)) < threshold &&
                abs(topLeft + leftLast - (leftMiddle << 1)) < threshold)
            {
                // "strong" bilinear interpolation 使用强双线性插值
                const int shift = 5 + 1;
                int init = (topLeft << shift) + tuSize;
                int deltaL, deltaR;

				//Δleft = 左边最下边-左边最上边,Δtop = 上边最右边-上边最左边
                deltaL = leftLast - topLeft; deltaR = topLast - topLeft;

				//最左上角,即左边最上,上边最左,像素不进行平滑滤波,直接输出
                fltBuf[0] = topLeft;
				//遍历2倍size长度边界参考像素
                for (int i = 1; i < tuSize2; i++)
                {
					//左边平滑滤波,输出到fltBuf中
                    fltBuf[i + tuSize2] = (pixel)((init + deltaL * i) >> shift); // Left Filtering
                    //上边平滑滤波,输出到fltBuf中
					fltBuf[i] = (pixel)((init + deltaR * i) >> shift);           // Above Filtering
                }
				//上边最下不进行平滑滤波
                fltBuf[tuSize2] = topLast;
				//左边最下不进行平滑滤波
                fltBuf[tuSize2 + tuSize2] = leftLast;
                return;
            }
        }

		//对参考像素refBuf进行常规的平滑过滤,输出到fltBuf中
        primitives.cu[intraNeighbors.log2TrSize - 2].intra_filter(refBuf, fltBuf);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值