Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2235596
  • 博文数量: 668
  • 博客积分: 10016
  • 博客等级: 上将
  • 技术积分: 8588
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-29 19:22
文章分类

全部博文(668)

文章存档

2011年(1)

2010年(2)

2009年(273)

2008年(392)

分类:

2009-08-14 10:55:14

② 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系数以获得预测器,解码直流分量、交流分量,反量化、反变换。最后把解码的宏块数据更新到当前解码图像空间。
阅读(661) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~