AVS3码流结构解析

AVS3编码学习过程中,很重要的一部分是捋清码流结构。通过学习AVS3-P2(FCD 2.0)-20200403_N2805.pdf,博主整理了AVS3的码流结构思维导图,并将编码树、编码单元、变换单元三个重要的结构抽取出来,以C语言的形式进行注释分析。本文中的图片、源码可以到https://download.csdn.net/download/leelitian3/14102746中免费下载。

码流结构导图:uAVS3e_structure

编码树:coding_unit_tree

/* LCU的起始像素,划分次数,划分模式,LCU的大小,是否支持QT划分,划分模式 */
coding_unit_tree(x0, y0, split, width, height, qt, mode)
{
    // 判定边界
	isBoundary = ((x0 + width) > PicWidthInLuma) || ((y0 + height) > PicHeightInLuma);
	rightBoundary = ((x0 + width) > PicWidthInLuma) && ((y0 + height) <= PicHeightInLuma);
	bottomBoundary = ((x0 + width) <= PicWidthInLuma) && ((y0 + height) > PicHeightInLuma);

    // 允许的划分标志
	allowNoSplit = 0;
	allowSplitQt = 0;
	allowSplitBtVer = 0;
	allowSplitBtHor = 0;
	allowSplitEqtVer = 0;
	allowSplitEqtHor = 0;

    // 如果是边界
	if (isBoundary)
	{
		allowNoSplit = 0;
        // I帧:128x128
		if ((PictureType == 0) && (width > 64) && (height > 64))
		{
			allowSplitQt = 1;   // QT
			allowNoSplit = 1;   // NO_SPLIT
		}
        // 64x128,128x64
		else if ((width == 64 && height > 64) || (height == 64 && width > 64))
		{
			allowSplitBtHor = 1;    // BT_HOR
			allowSplitBtVer = 1;    // BT_VER
		}
        // 右下角的那一块
		else if (!rightBoundary && !bottomBoundary)
		{
			allowSplitQt = 1;       // QT
		}
        // 右边界
		else if (rightBoundary)
		{
			allowSplitBtVer = 1;    // BT_VER
		}
        // 下边界
		else if (bottomBoundary)
		{
			allowSplitBtHor = 1;    // BT_HOR
		}
	}
    // 不是边界的情况
	else
	{
        // 64x128,128x64
		if (((width == 64) && (height > 64)) || ((height == 64) && (width > 64)))
		{
			allowSplitBtHor = 1;    // BT_HOR
			allowSplitBtVer = 1;    // BT_VER
			allowNoSplit = 1;       // NO_SPLIT
		}
        // 如果划分次数太高了
		else if (split >= MaxSplitTimes)
		{
			allowNoSplit = 1;       // NO_SPLIT
		}
        // I帧:128x128
		else if ((PictureType == 0) && (width == 128) && (height == 128))
		{
			allowSplitQt = 1;       // QT
			allowNoSplit = 1;       // NO_SPLIT
		}
		else
		{
            // 当前CU在宽高比8:1的划分范围内
			if ((width <= height * MaxPartRatio) && (height <= width * MaxPartRatio))
				allowNoSplit = 1;   // NO_SPLIT
            // 符合QT划分最小尺寸
			if ((width > MinQtSize) && qt)
				allowSplitQt = 1;   // QT

            // 在BT划分大小范围内,且划分后宽高比符合要求
			if ((width <= MaxBtSize) && (height <= MaxBtSize) && (width > MinBtSize) && (height < MaxPartRatio * width))
				allowSplitBtVer = 1;    // BT_VER
			if ((width <= MaxBtSize) && (height <= MaxBtSize) && (height > MinBtSize) && (width < MaxPartRatio * height))
				allowSplitBtHor = 1;    // BT_HOR

            // 在EQT划分大小范围内,且划分后宽高比符合要求
			if ((width <= MaxEqtSize) && (height <= MaxEqtSize) && (height >= MinEqtSize * 2) && (width >= MinEqtSize * 4) && (height * 4 <= MaxPartRatio * width))
				allowSplitEqtVer = 1;   // EQT_VER
			if ((width <= MaxEqtSize) && (height <= MaxEqtSize) && (width >= MinEqtSize * 2) && (height >= MinEqtSize * 4) && (width * 4 <= MaxPartRatio * height))
				allowSplitEqtHor = 1;   // EQT_HOR
		}
	}
    
    allowSplitBt = allowSplitBtVer || allowSplitBtHor;
    allowSplitEqt = allowSplitEqtVer || allowSplitEqtHor;

    // QT && ( NO_SPLIT || BT || EQT )
    if (allowSplitQt && (allowNoSplit || allowSplitBt || allowSplitEqt))
	{
		qt_split_flag;  // 是否使用QT划分
	}
	if (!QtSplitFlag)
	{
        // NO_SPLIT && ( BT || EQT )
		if (allowNoSplit && (allowSplitBt || allowSplitEqt))
		{
			bet_split_flag;     // 是否使用BT/EQT划分
		}
		if (BetSplitFlag)
		{
            // BT && EQT
			if (allowSplitBt && allowSplitEqt)
				bet_split_type_flag;    // 0:BT   1:EQT
			if ((!BetSplitTypeFlag && allowSplitBtHor && allowSplitBtVer) || (BetSplitTypeFlag && allowSplitEqtHor && allowSplitEqtVer))
				bet_split_dir_flag;     // 0:HOR  1:VER
		}
	}

    // B/P帧 && [ ( EQT / QT 64pixel ) || ( BT 128pixel ) ]
	if ((PictureType != 0) && ((((BetSplitFlag && !BetSplitTypeFlag) || QtSplitFlag) && (width * height == 64)) || (BetSplitTypeFlag && (width * height == 128))))
	{
		root_cu_mode;        //  0: PRED_Intra_Only  1: PRED_Inter_Only
		modeChild = root_cu_mode ? 'PRED_Intra_Only' : 'PRED_Inter_Only';
	}
	else
	{
		modeChild = mode;   // 子编码单元的pred_mode继承父编码单元
	}
	if (ChildSizeOccur4)    // 划分后CU的宽或高为4 ( 详见 AVS3-FCD2.0 P80 )
	{
		if (Component == 0)
		{
			LumaWidth = width;
			LumaHeight = height;
			Component = 1;	// 设置为仅编码亮度分量
		}
	}

    // QT划分模式
	if (BlockSplitMode == 'SPLIT_QT')
	{
        // 子CU的大小
		QtWidth = width / 2;
		QtHeight = height / 2;

        // 中间点的像素坐标
		x1 = x0 + QtWidth;
		y1 = y0 + QtHeight;

        // coding_unit_tree:左上角块
		coding_unit_tree(x0, y0, split + 1, QtWidth, QtHeight, 1, modeChild);
        // 右上角块
		if (x1 < PicWidthInLuma)
            coding_unit_tree(x1, y0, split + 1, QtWidth, QtHeight, 1, modeChild);
        // 左下角块
        if (y1 < PicHeightInLuma)
            coding_unit_tree(x0, y1, split + 1, QtWidth, QtHeight, 1, modeChild);
        // 右下角块
		if ((x1 < PicWidthInLuma) && (y1 < PicHeightInLuma))
			coding_unit_tree(x1, y1, split + 1, QtWidth, QtHeight, 1, modeChild);
        
        // 若ChildSizeOccur4,则为色度CU编码
		if ((LumaWidth == width) && (LumaHeight = height) && ChildSizeOccur4)
		{
			coding_unit(x0, y0, width, height, 'PRED_No_Constraint', 'COMPONENT_Chroma');	// 以上4块仅编码luma(line134),本块仅编码chroma
			Component = 0;	// 恢复为编码luma_chroma
		}
	}
    // BT_VER划分模式
	else if (BlockSplitMode == 'SPLIT_BT_VER')
	{
		x1 = x0 + width / 2;
        // 左边块
		coding_unit_tree(x0, y0, split + 1, width / 2, height, 0, modeChild);
        // 右边块
		if (x1 < PicWidthInLuma)
			coding_unit_tree(x1, y0, split + 1, width / 2, height, 0, modeChild);

        // 色度块
		if ((LumaWidth == width) && (LumaHeight = height) && ChildSizeOccur4)
		{
			coding_unit(x0, y0, width, height, 'PRED_No_Constraint', 'COMPONENT_Chroma');
            Component = 0;
        }
	}
    // BT_HOR划分模式
	else if (BlockSplitMode == 'SPLIT_BT_HOR')
	{
		y1 = y0 + height / 2;
		coding_unit_tree(x0, y0, split + 1, width, height / 2, 0, modeChild);
		if (y1 < PicHeightInLuma)
			coding_unit_tree(x0, y1, split + 1, width, height / 2, 0, modeChild);

		if ((LumaWidth == width) && (LumaHeight = height) && ChildSizeOccur4)
		{
			coding_unit(x0, y0, width, height, 'PRED_No_Constraint', 'COMPONENT_Chroma');
            Component = 0;
        }
	}
    // EQT_VER划分模式
	else if (BlockSplitMode == 'SPLIT_EQT_VER')
	{
		x1 = x0 + width / 4;
		x2 = x0 + (3 * width / 4);
		y1 = y0 + height / 2;

		coding_unit_tree(x0, y0, split + 1, width / 4, height, 0, modeChild);
		coding_unit_tree(x1, y0, split + 1, width / 2, height / 2, 0, modeChild);
		coding_unit_tree(x1, y1, split + 1, width / 2, height / 2, 0, modeChild);
		coding_unit_tree(x2, y0, split + 1, width / 4, height, 0, modeChild);

		if ((LumaWidth == width) && (LumaHeight = height) && ChildSizeOccur4)
		{
			coding_unit(x0, y0, width, height, 'PRED_No_Constraint', 'COMPONENT_Chroma');
			Component = 0;
		}
	}
    // EQT_HOR划分模式
	else if (BlockSplitMode == 'SPLIT_EQT_HOR')
	{
		x1 = x0 + width / 2;
		y1 = y0 + height / 4;
		y2 = y0 + (3 * height / 4);

		coding_unit_tree(x0, y0, split + 1, width, height / 4, 0, modeChild);
		coding_unit_tree(x0, y1, split + 1, width / 2, height / 2, 0, modeChild);
		coding_unit_tree(x1, y1, split + 1, width / 2, height / 2, 0, modeChild);
		coding_unit_tree(x0, y2, split + 1, width, height / 4, 0, modeChild);

		if ((LumaWidth == width) && (LumaHeight = height) && ChildSizeOccur4)
		{
			coding_unit(x0, y0, width, height, 'PRED_No_Constraint', 'COMPONENT_Chroma');
			Component = 0;
		}
	}
    // NO_SPLIT划分模式
	else
	{
        // 可包含亮度分量和色度分量
		if (Component == 0)
		{
            coding_unit(x0, y0, width, height, mode, 'COMPONENT_LUMACHROMA');
        }
        // 仅有亮度分量
		else if (Component == 1)
		{
            coding_unit(x0, y0, width, height, mode, 'COMPONENT_LUMA');
        }
	}
}

  编码单元:coding_unit

/* CU的像素坐标,CU大小,预测模式,分量 */
coding_unit(x0, y0, width, height, mode, component)
{
	// 色度分量
	if (component == 'COMPONENT_Chroma')
	{
		// priorCuMode:当前色度块对应的亮度块右下角4x4的子块为帧内模式
		if ((priorCuMode == 1) && (chroma_format != '00'))
			intra_chroma_pred_mode;		// 帧内色度预测模式

		NumOfTransBlocks = 3;
		ctp_y[0] = 0;
		CuCtp += ctp_y[0];
		
		// 若色度预测模式不是PCM
		if (IntraChromaPredMode != 'Intra_Chroma_PCM')
		{
			ctp_u;
			CuCtp += (ctp_u << 1);
			ctp_v;
			CuCtp += (ctp_v << 2);
		}

		// 编码U、V变换块
		for (i = NumOfTransBlocks - 2; i < NumOfTransBlocks; i++)
		{
			IsPcmMode[i] = (IntraChromaPredMode == 'Intra_Chroma_PCM');
			IsChroma = 0;
			if (i == NumOfTransBlocks - 1 || i == NumOfTransBlocks - 2)
			{
				IsChroma = 1;
			}
			// 变换块
			block(i, width, height, CuCtp, IsChroma, IsPcmMode[i], component);
		}
	}
	// LUMA或LUMACHROMA
	else
	{
		// 若不是I帧
		if (PictureType != 0)
		{
			if (mode != 'PRED_Intra_Only')
			{
				skip_flag;		// Skip模式标志
			}
			// Skip模式下:编码umve和affine模式
			if (SkipFlag)
			{
				if (UmveEnableFlag)
					umve_flag;
				// affine与umve不能共存,且需要宽高都大于16
				if (AffineEnableFlag && !UmveFlag && (width >= 16) && (height >= 16))
					affine_flag;
			}
			// 非Skip模式下
			if (!SkipFlag)
			{
				if (mode != 'PRED_Intra_Only')
				{
					direct_flag;	// direct模式标志
				}
				// Direct模式下:编码umve和affine模式
				if (DirectFlag)
				{
					if (UmveEnableFlag)
						umve_flag;
					if (AffineEnableFlag && !UmveFlag && (width >= 16) && (height >= 16))
						affine_flag;
				}
				// 非Direct模式下:
				if (!DirectFlag && (mode == 'PRED_No_Constraint'))
					intra_cu_flag;	// 0:帧间模式	1:帧内模式
			}
		}

		PartSize = 'SIZE_2Mx2N';

		// 若衍生模式和帧内模式
		if (DtEnableFlag && IntraCuFlag)
		{
			// CU符合DT划分的要求( 其中DtMinSize的值等于16 )
			allowDtHorSplit = (height >= DtMinSize) && (height <= DtMaxSize) && (width / height < 4) && (width <= DtMaxSize);
			allowDtVerSplit = (width >= DtMinSize) && (width <= DtMaxSize) && (height / width < 4) && (height <= DtMaxSize);
			if (allowDtHorSplit || allowDtVerSplit)
			{
				dt_split_flag;		// 是否进行衍生划分
				if (DtSplitFlag)
				{
					if (allowDtHorSplit && allowDtVerSplit)
					{
						dt_split_dir;	// 0:垂直划分  1:水平划分
					}
					else if (allowDtHorSplit)
					{
						DtSplitDir = 1;
					}
					else
					{
						DtSplitDir = 0;
					}
					if (DtSplitDir)
					{
						dt_split_hqt_flag;		// 水平四叉划分:0表示不进行,1表示进行
						if (!DtSplitHqtFlag)
						{
							dt_split_hadt_flag;	// 水平非对称划分:0表示up,1表示down
						}
					}
					else
					{
						dt_split_vqt_flag;
						if (!DtSplitVqtFlag)
						{
							dt_split_vadt_flag;
						}
					}
				}
			}
		}

		// umve标识
		if (UmveFlag)
		{
			umve_mv_idx;
			umve_step_idx;
			umve_dir_idx;
		}
		// skip/direct前提下的affine
		else if ((SkipFlag || DirectFlag) && AffineFlag)
		{
			cu_affine_cand_idx;
		}
		// skip/direct
		else if (SkipFlag || DirectFlag)
		{
			cu_subtype_index;	// CU子类型索引
		}

		// 非Skip,非Direct
		if (!SkipFlag && !DirectFlag)
		{
			// 普通inter模式
			if (!IntraCuFlag)
			{
				// affine
				if (AffineEnableFlag && (width >= 16) && (height >= 16))
					affine_flag;
				// amvr
				if (AmvrEnableFlag)
				{
					if (EmvrEnableFlag && !AffineFlag)
					{
						extend_mvr_flag;	// emvr
					}
					if (AffineFlag)
						affine_amvr_index;
					else
						amvr_index;
				}
				// B帧预测参考模式:list 0/1/01
				if (PictureType == 2)
				{
					inter_pred_ref_mode;
				}
				// smvd
				if (SmvdEnableFlag && SmvdApplyFlag && !AffineFlag && (InterPredRefMode == 2) && !ExtendMvrFlag)
				{
					smvd_flag;
				}
				// MvExistL0:这部分暂时不懂
				if (MvExistL0)
				{
					if (!SmvdFlag && NumRefActive[0] > 1)
						pu_reference_index_l0;
					mv_diff_x_abs_l0;
					if (MvDiffXAbsL0)
						mv_diff_x_sign_l0;
					mv_diff_y_abs_l0;
					if (MvDiffYAbsL0)
						mv_diff_y_sign_l0;
					if (AffineFlag)
					{
						mv_diff_x_abs_l0_affine;
						if (MvDiffXAbsL0Affine)
							mv_diff_x_sign_l0_affine;
						mv_diff_y_abs_l0_affine;
						if (MvDiffYAbsL0Affine)
							mv_diff_y_sign_l0_affine;
					}
				}
				if (MvExistL1 && !SmvdFlag)
				{
					if (NumRefActive[1] > 1)
						pu_reference_index_l1;
					mv_diff_x_abs_l1;
					if (MvDiffXAbsL1)
						mv_diff_x_sign_l1;
					mv_diff_y_abs_l1;
					if (MvDiffYAbsL1)
						mv_diff_y_sign_l1;
					if (AffineFlag)
					{
						mv_diff_x_abs_l1_affine;
						if (MvDiffXAbsL1Affine)
							mv_diff_x_sign_l1_affine;
						mv_diff_y_abs_l1_affine;
						if (MvDiffYAbsL1Affine)
							mv_diff_y_sign_l1_affine;
					}
				}
			}
			// 帧内模式
			else
			{
				TuOrder = 0;
				// NumOfIntraPredBlock由衍生模式确定
				for (i = 0; i < NumOfIntraPredBlock; i++)
				{
					intra_luma_pred_mode;	// 每个亮度PU的预测模式
				}

				if (PartSize == 'SIZE_2Mx2N')
				{
					IsPcmMode[TuOrder] = (IntraLumaPredMode == 'Intra_Luma_PCM');
					TuOrder++;
				}
				else
				{
					IsPcmMode[0] = 0;
					IsPcmMode[1] = 0;
					IsPcmMode[2] = 0;
					IsPcmMode[3] = 0;
					TuOrder = 3;
				}

				// 若为COMPONENT_LUMACHROMA
				if (IntraCuFlag && (chroma_format != '00') && (component == 'COMPONENT_LUMACHROMA'))
				{
					intra_chroma_pred_mode;		// 色度PU的预测模式
					IsPcmMode[TuOrder + 1] = (IntraChromaPredMode == 'Intra_Chroma_PCM');
					IsPcmMode[TuOrder + 2] = (IntraChromaPredMode == 'Intra_Chroma_PCM');
				}

				if (IpfEnableFlag && (PartSize == 'SIZE_2Mx2N') && (!IsPcmMode[0]))
				{
					ipf_flag;		// IPF滤波标志
				}
			}
		}

		// 非帧内,非Skip 
		if (!IntraCuFlag && !SkipFlag)
		{
			if (!DirectFlag && component == 'COMPONENT_LUMACHROMA')
				ctp_zero_flag;	// 1:变换块系数全为0
			CuCtp = 0;
			if (!CtpZeroFlag)
			{
				// 宽高在8~32,宽高比小于4
				if (PbtEnableFlag && (width / height < 4) && (height / width < 4) && (width >= 8) && (width <= 32) && (height >= 8) && (height <= 32))
				{
					pbt_cu_flag;	// 基于位置的变换标志
				}
				// 不使用pbt变换,NumOfTransBlocks = 3
				if (!PbtCuFlag)
				{
					if (component == 'COMPONENT_LUMACHROMA')
					{
						ctp_u;
						ctp_v;
					}
					CuCtp = ctp_u << (NumOfTransBlocks - 2);
					CuCtp += (ctp_v << (NumOfTransBlocks - 1));
					if (((ctp_u != 0) || (ctp_v != 0)) || (component != 'COMPONENT_LUMACHROMA'))
					{
						ctp_y[0];
						CuCtp += ctp_y[0];
					}
					else
					{
						CuCtp += ctp_y[0];
					}
				}
				// 使用pbt变换,NumOfTransBlocks = 6
				else
				{
					if (component == 'COMPONENT_LUMACHROMA')
					{
						ctp_u;
						ctp_v;
					}
					CuCtp = ctp_u << (NumOfTransBlocks - 2);
					CuCtp += (ctp_v << (NumOfTransBlocks - 1));
					for (i = 0; i < NumOfTransBlocks - 2; i++)
					{
						ctp_y[i];
						CuCtp += (ctp_y[i] << i);
					}
					// 此时CuCtp为 YYYYUV
				}
			}
		}
		// 帧内模式
		else if (!SkipFlag)
		{
			CuCtp = 0;
			if (!IsPcmMode[0])
			{
				for (i = 0; i < NumOfTransBlocks - 2; i++)
				{
					ctp_y[i];
					CuCtp += (ctp_y[i] << i);
				}
			}
			if ((component == 'COMPONENT_LUMACHROMA') && (IntraChromaPredMode != 'Intra_Chroma_PCM'))
			{
				ctp_u;
				ctp_v;
			}
			CuCtp += (ctp_u << (NumOfTransBlocks - 2));
			CuCtp += (ctp_v << (NumOfTransBlocks - 1));
		}

		// 变换块
		for (i = 0; i < NumOfTransBlocks; i++)
		{
			if (i < NumOfTransBlocks)
			{
				// TransformSplitDirection:0不划分,1pbt,2水平,3垂直
				blockWidth = ((TransformSplitDirection == 0) || (TransformSplitDirection == 2)) ? width : (TransformSplitDirection == 1 ? width >> 1 : width >> 2);
				blockHeight = ((TransformSplitDirection == 0) || (TransformSplitDirection == 3)) ? height : (TransformSplitDirection == 1 ? height >> 1 : height >> 2);
				blockX = x0 + (((TransformSplitDirection == 0) || (TransformSplitDirection == 2)) ? 0 : (TransformSplitDirection == 1 ? ((blockWidth >> 1) * (i % 2)) : ((blockWidth >> 2) * i)));
				blockY = y0 + (((TransformSplitDirection == 0) || (TransformSplitDirection == 3)) ? 0 : (TransformSplitDirection == 1 ? ((blockHeight >> 1) * (i / 2)) : ((blockHeight >> 2) * i)))
			}
			IsChroma = 0;
			if (i == NumOfTransBlocks - 1 || i == NumOfTransBlocks - 2)
			{
				IsChroma = 1;
			}
			block(i, blockWidth, blockHeight, CuCtp, IsChroma, IsPcmMode[i], component);
		}
	}
}

 变换单元:block

/* 块编号,块大小,该块是否含有编码数据,是否为色度分量,是否使用PCM,分量信息 */
block(i, blockWidth, blockHeight, CuCtp, isChroma, isPcm, component)
{
    M1 = blockWidth;
    M2 = blockHeight;
    // 初始化量化系数矩阵为0
    for (x = 0; x < M1; x++)
    {
        for (y = 0; y < M2; y++)
            QuantCoeffMatrix[x][y] = 0;
    }
    // 非PCM模式
    if (!isPcm)
    {
        // i号块有编码数据
        if (CuCtp & (1 << i))
        {
            blockWidth = isChroma ? blockWidth / 2 : blockWidth;
            blockHeight = isChroma ? blockHeight / 2 : blockHeight;
            idxW = Log(blockWidth) – 1;
            idxH = Log(blockHeight) – 1;
            NumOfCoeff = blockWidth * blockHeight;
            ScanPosOffset = 0;
            do
            {
                coeff_run;              // run
                coeff_level_minus1;     // level
                coeff_sign;             // level_sign
                AbsLevel = coeff_level_minus1 + 1;
                ScanPosOffset = ScanPosOffset + coeff_run;
                PosxInBlk = InvScanCoeffInBlk[idxW][idxH][ScanPosOffset][0];
                PosyInBlk = InvScanCoeffInBlk[idxW][idxH][ScanPosOffset][1];
                QuantCoeffMatrix[PosxInBlk][PosyInBlk] = coeff_sign ? –AbsLevel : AbsLevel;
                if (ScanPosOffset >= NumOf Coeff – 1)
                {
                    break;
                }
                coeff_last;             // coeff_last
                ScanPosOffset = ScanPosOffset + 1;
            } while (!coeff_last)
        }
    }
    // PCM模式
    else
    {
        // 填充位
        if ((component != 'COMPONENT_CHROMA' && i == 0) || (component == 'COMPONENT_CHROMA' && i == 1))
        {
            aec_ipcm_stuffing_bit;
            while (!byte_aligned())
            {
                aec_byte_alignment_bit0;
            }
        }
        // 色度TU大小为一半
        M1 = isChroma ? blockWidth / 2 : blockWidth;
        M2 = isChroma ? blockHeight / 2 : blockHeight;
        xMin = Min(32, M1);
        yMin = Min(32, M2);
        // 分为32x32的块依次编码
        for (yStep = 0; yStep < M2 / yMin; yStep++)
        {
            for (xStep = 0; xStep < M1 / xMin; xStep++)
            {
                for (y = 0; y < yMin; y++)
                {
                    for (x = 0; x < xMin; x++)
                    {
                        pcm_coeff;
                        QuantCoeffMatrix[x + xStep * xMin][y + yStep * yMin] = pcm_coeff;
                    }
                }
            }
        }
    }
}

如果文章对您有帮助,记得点个赞哦 o(* ̄▽ ̄*)ブ

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值