设为首页 加入收藏

TOP

14.2.1 MPEG-4编/解码设计与剖析(8)
2013-10-07 00:42:01 来源: 作者: 【 】 浏览:63
Tags:14.2.1 MPEG-4 解码 设计 剖析

14.2.1  MPEG-4编/解码设计与剖析(8)

② decoder_mbintra对Intra宏块做正真的解码

该函数是Intra块的核心解码函数,进行熵解码、反量化、反变换,最后把解码后的宏块数据更新到当前解码图像空间。

Intra块的解码decoder_mbintra()的流程如图14-8所示。

 
图14-8  decoder_mbintra()流程图
根据该流程,代码实现如下。
/* 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);
}
上述代码实现Intra块的解码工作,首先初始化必要的参数和变量,解码得到DC直流分量的量化步长,接着预测DCT系数以获得预测器,解码直流分量、交流分量,反量化、反变换。最后把解码的宏块数据更新到当前解码图像空间。
【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇14.2.1 MPEG-4编/解码设计与剖析.. 下一篇14.2.2 MMX/SSE 2实现XviD CODEC..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: