讨论对象:I帧在I16MB划分模式下的编码
执行函数:currMB->cbp = currSlice->mode_decision_for_I16x16_MB (currMB, lambda);
算法思想描述
- 对于给定的划分,存在多种预测模式,因此首先要选择最佳的预测模式使得预测失真最小。执行函数:find_best_mode_I16x16_MB (currMB, lambda, DISTBLK_MAX);
- 在最佳预测模式下对亮度的预测残差进行变换、量化、编码以及重构。执行函数:currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_Y);
算法实现
计算预测失真度。执行函数:distblk find_sad_16x16_JM(Macroblock *currMB)。
I 帧16X16的预测模式有四种,具体参考《The H.264 Advanced Video Compression Standard》2ed 表6.1。
- 针对各种合法的预测模式(与当前宏块的位置有关)计算预测值;
- 计算预测残差,并将16X16的残差块分成4X4的子块;
- 对16个4X4的残差子块进行hadamard4x4变换,计算各子块的直交流系数绝对值之和;16个直流系数组成4X4的直流子块,进行hadamard4x4变换,计算各系数绝对值之和;
- 由各系数绝对值之和计算失真度current_intra_sad_2,以此为依据确定最佳的预测模式。
亮度残差的编码。执行函数:currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_Y);
- 求最佳预测模式下亮度分量的残差(16X16大小,但在作变换时分成16个4X4的子块);
- 进行4X4的DCT变换(forward 4x4 integer transform),具体参考《The H.264 Advanced Video Compression Standard》2ed,变换核为(7.5),正变换公式为(7.4);
- 取出16个子块的直流系数组成一个4X4的子块,进行hadamard4x4变换(hadamard of DC coefficients);
- 对DCT直流系数的hadamard4x4的系数进行量化。执行函数:nonzero = currSlice->quant_dc4x4(currMB, &currSlice->tblk4x4[0], qp, DCLevel, DCRun, &quant_methods.q_params[0][0], pos_scan);
- 哈达反变换得到DCT直流系数。执行函数:ihadamard4x4(currSlice->tblk4x4, currSlice->tblk4x4);
- 交流系数量化(Quantization process)。执行函数:nonzero = currSlice->quant_ac4x4(currMB, &currSlice->tblk16x16[jpos], &quant_methods);
- DCT反变换(inverse transform)。执行函数:inverse4x4(currSlice->tblk16x16, currSlice->tblk16x16, jpos, ipos);
- 样值重构(Reconstruct samples)。执行函数:sample_reconstruct (&img_enc[currMB->pix_y], curr_mpr_16x16[new_intra_mode], currSlice->tblk16x16, 0, currMB->pix_x, 16, 16, max_imgpel_value, DQ_BITS);
色度残差的编码。执行函数:currSlice->chroma_residual_coding (currMB);
- 计算最佳预测模式下的预测残差。执行函数:compute_residue(&p_Vid->pImgOrg[uv + 1][currMB->opix_c_y ], currSlice->mb_pred[ uv + 1], currSlice->mb_ores[uv + 1], 0, currMB->pix_c_x, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
- 残差的DCT、量化、反量化、反变换以及样值重构。执行函数:chroma_cbp = currMB->residual_transform_quant_chroma_4x4[uv] (currMB, uv, chroma_cbp);
亮度、色度分量的残差编码之后,计算失真度。执行函数:distortion = currSlice->getDistortion(currMB);
保存编码状态,主要是一些比特流状态、编码上下文。
写宏块级比特流。执行函数:rate = currSlice->write_MB_layer (currMB, 1, &coeff_rate);
R E S T O R E C O D I N G S T A T E。执行函数:currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
U P D A T E M I N I M U M C O S T。记录最佳模式下的一些参数。
保存宏块参数。执行函数:store_macroblock_parameters (currMB, mode);