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

全部博文(668)

文章存档

2011年(1)

2010年(2)

2009年(273)

2008年(392)

分类:

2009-08-14 10:56:27

④ decoder_mbinter对Inter块实现解码

Inter块解码支持1/2像素精度,Inter块的decoder_mbinter()的流程如图14-10所示。

 
图14-10  decoder_mbinter ()
流程图
根据该流程,代码实现如下。
void decoder_mbinter(DECODER * dec, const MACROBLOCK * pMB,
const uint32_t x_pos, const uint32_t y_pos,
const uint32_t cbp, Bitstream * bs,
const uint32_t rounding, const int ref, const int bvop)
{
uint32_t stride = dec->edged_width;
uint32_t stride2 = stride / 2;
uint32_t i;
uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
int uv_dx, uv_dy;
VECTOR mv[4]; /* local copy of mvs */
/*获取指向图像空间的指针*/
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);
for (i = 0; i < 4; i++)   mv[i] = pMB->mvs[i]; /*获取运动向量*/
validate_vector(mv, x_pos, y_pos, dec);       /*检查运动向量的合法性*/
/******************************运动补偿*****************************/
if ((pMB->mode != MODE_INTER4V))
{ /* 编码模式是INTER、INTER_Q、NOT_CODED、FORWARD、BACKWARD */
uv_dx = mv[0].x;
uv_dy = mv[0].y;
uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
/*亮度插值*/
interpolate16x16_switch(dec->cur.y,dec->refn[ref]
.y,16*x_pos,16*y_pos,mv[0].x, mv[0].y, stride, rounding);
}
/*色度插值 */
interpolate8x8_switch(dec->cur.u, dec->refn[ref]
.u, 8 * x_pos, 8 * y_pos,uv_dx, uv_dy, stride2, rounding);
interpolate8x8_switch(dec->cur.v, dec->refn[ref].
v, 8 * x_pos, 8 * y_pos,uv_dx, uv_dy, stride2, rounding);
/******************************运动补偿*****************************/
/*根据cbp*/
if (cbp) decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
}

上述代码实现Inter块的解码,首先作运动补偿,然后根据cbp编码模式决定是否做宏块解码。

⑥ decoder_mb_decode实现宏块的实际解码工作

首先VLD熵解码、反量化和IDCT变换,最后根据CBP编码模式决定块是否更新到当前解码帧图像。

Inter块的decoder_ mb_decode ()的流程如图14-11所示。

 
图14-11  decoder_mb_decode()流程图

根据该流程,代码实现如下。

void decoder_mb_decode(DECODER * dec, const uint32_t cbp, Bitstream * bs,
uint8_t * pY_Cur, uint8_t * pU_Cur, uint8_t * pV_Cur,
const int reduced_resolution,const MACROBLOCK * pMB)
{
DECLARE_ALIGNED_MATRIX(block, 1, 64, int16_t, CACHE_LINE); /*系数*/
DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);  /*图像*/
int stride = dec->edged_width;   /*图像边扩展后的宽度*/
int next_block = stride * 8;    /*亮度的下一个块*/
const int stride2 = stride/2;    /*色度的下一个快*/
int i;
const uint32_t iQuant = pMB->quant;  /*量化步长*/
const int direction = dec->alternate_vertical_scan ? 2 : 0;  /*AC扫描方式*/
for (i = 0; i < 6; i++) {
if (cbp & (1 << (5 - i))) {       /*块做了编码*/
memset(block, 0, 64 * sizeof(int16_t));   /*清零*/
get_inter_block(bs, block, direction);   /*VLD熵解码*/
dequant_h263_inter (&data[i * 64], block, iQuant, NULL);/*H263反量化*/
idct(&data[i * 64]);        /*IDCT变换*/
}
}
/*根据CBP值决定是否加到当前图像*/
if (cbp & 32) transfer_16to8add(pY_Cur, &data[0 * 64], stride);
if (cbp & 16) transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);
if (cbp & 8)  transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);
if (cbp & 4)  transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);
if (cbp & 2)  transfer_16to8add(pU_Cur, &data[4 * 64], stride2);
if (cbp & 1)  transfer_16to8add(pV_Cur, &data[5 * 64], stride2);
}

上述代码实现Inter块的解码工作,根据cbp值决定是否做解码。首先解码宏块空间block清零,VLD熵解码,然后反量化、反变换。最后根据cbp值决定是否更新当前解码帧图像。

为了提高解码器解码速度,解码器的最底层模块get_inter_block、dequant_h263_inter、idct、transfer_16to8add等,要使用平台的汇编来优化和设计。下一节将介绍这些核心模块的MMX/SSE/DM642汇编优化。

阅读(927) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~