/* decode an intra macroblock */ static void decoder_mbintra(DECODER * dec, MACROBLOCK * pMB, const uint32_t x_pos, const uint32_t y_pos, const uint32_t acpred_flag, const uint32_t cbp, Bitstream * bs, const uint32_t quant, const uint32_t intra_dc_threshold, const unsigned int bound) { DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE); /*DCT系数*/ DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE); /*图像数据*/ uint32_t stride = dec->edged_width; /*图像边做扩展的图像Y宽度*/ uint32_t stride2 = stride / 2; /*图像边做扩展的图像U宽度*/ uint32_t next_block = stride * 8; /*修改指向块的横跨宽度*/ uint32_t i; uint32_t iQuant = pMB->quant; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; /*获取指向图像空间的指针*/ pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3); memset(block, 0, 6 * 64 * sizeof(int16_t)); /* 图像DCT系数清空 */ /*循环对6个块处理*/ for (i = 0; i < 6; i++) { uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4); /*获取DC分量的量化步长*/ int16_t predictors[8]; /*预测器*/ int start_coeff; /*预测DCT系数,得到预测器*/ predict_acdc(dec->mbs,x_pos,y_pos,dec->mb_width,i, &block[i * 64],iQuant, iDcScaler, predictors, bound); if (!acpred_flag) pMB->acpred_directions[i] = 0; /*得到DCT的直流分量*/ if (quant < intra_dc_threshold) { int dc_size; int dc_dif; dc_size = i < 4 ? get_dc_size_lum(bs) : get_dc_size_chrom(bs); dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0; if (dc_size > 8) BitstreamSkip(bs, 1); /* marker */ block[i * 64 + 0] = dc_dif; start_coeff = 1; } else start_coeff = 0; if (cbp & (1 << (5 - i))) /* 宏块做编码标识*/ { int direction = dec->alternate_vertical_scan ? 2 : pMB->acpred_directions[i]; get_intra_block(bs, &block[i * 64], direction, start_coeff); /*获取当前块的系数*/ } /*使用预测器,恢复编码前系数值*/ add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors, dec->bs_version); /*H.263反量化*/ dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices); /*反DCT变换*/ idct((short * const)&data[i * 64]); }/*循环对6个块处理*/ /*把解码后的宏块图像复制到当前解码图像空间*/ transfer_16to8copy(pY_Cur, &data[0 * 64], stride); transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride); transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride); transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride); transfer_16to8copy(pU_Cur, &data[4 * 64], stride2); transfer_16to8copy(pV_Cur, &data[5 * 64], stride2); } |