📄 decoder.c
字号:
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);
stop_transfer_timer();
}
static void decoder_iframe(DECODER * dec, Bitstream * bs, int quant, int intra_dc_threshold)
{
uint32_t x, y;
for (y = 0; y < dec->mb_height; y++)
{
for (x = 0; x < dec->mb_width; x++)
{
MACROBLOCK * mb = &dec->mbs[y*dec->mb_width + x];
uint32_t mcbpc;
uint32_t cbpc;
uint32_t acpred_flag;
uint32_t cbpy;
uint32_t cbp;
mcbpc = get_mcbpc_intra(bs);
mb->mode = mcbpc & 7;
cbpc = (mcbpc >> 4);
acpred_flag = BitstreamGetBit(bs);
if (mb->mode == MODE_STUFFING)
{
DEBUG("-- STUFFING ?");
continue;
}
cbpy = get_cbpy(bs, 1);
cbp = (cbpy << 2) | cbpc;
if (mb->mode == MODE_INTRA_Q)
{
quant += dquant_table[BitstreamGetBits(bs,2)];
if (quant > 31)
{
quant = 31;
}
else if (quant < 1)
{
quant = 1;
}
}
mb->quant = quant;
if (dec->interlacing)
{
mb->field_dct = BitstreamGetBit(bs);
DEBUG1("deci: field_dct: ", mb->field_dct);
}
decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold);
}
}
}
static void get_motion_vector(DECODER *dec, Bitstream *bs, int x, int y, int k, VECTOR * mv, int fcode)
{
int scale_fac = 1 << (fcode - 1);
int high = (32 * scale_fac) - 1;
int low = ((-32) * scale_fac);
int range = (64 * scale_fac);
VECTOR pmv[4];
uint32_t psad[4];
int mv_x, mv_y;
int pmv_x, pmv_y;
get_pmvdata(dec->mbs, x, y, dec->mb_width, k, pmv, psad);
pmv_x = pmv[0].x;
pmv_y = pmv[0].y;
mv_x = get_mv(bs, fcode);
mv_y = get_mv(bs, fcode);
mv_x += pmv_x;
mv_y += pmv_y;
if (mv_x < low)
{
mv_x += range;
}
else if (mv_x > high)
{
mv_x -= range;
}
if (mv_y < low)
{
mv_y += range;
}
else if (mv_y > high)
{
mv_y -= range;
}
mv->x = mv_x;
mv->y = mv_y;
}
static
void decoder_pframe(DECODER * dec, Bitstream * bs, int rounding, int quant, int fcode, int intra_dc_threshold)
{
uint32_t x, y;
image_swap(&dec->cur, &dec->refn);
start_timer();
image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing);
stop_edges_timer();
for (y = 0; y < dec->mb_height; y++)
{
for (x = 0; x < dec->mb_width; x++)
{
MACROBLOCK * mb = &dec->mbs[y*dec->mb_width + x];
if (!BitstreamGetBit(bs)) // not_coded
{
uint32_t mcbpc;
uint32_t cbpc;
uint32_t acpred_flag;
uint32_t cbpy;
uint32_t cbp;
uint32_t intra;
mcbpc = get_mcbpc_inter(bs);
mb->mode = mcbpc & 7;
cbpc = (mcbpc >> 4);
acpred_flag = 0;
intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);
if (intra)
{
acpred_flag = BitstreamGetBit(bs);
}
if (mb->mode == MODE_STUFFING)
{
DEBUG("-- STUFFING ?");
continue;
}
cbpy = get_cbpy(bs, intra);
cbp = (cbpy << 2) | cbpc;
if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q)
{
quant += dquant_table[BitstreamGetBits(bs,2)];
if (quant > 31)
{
quant = 31;
}
else if (mb->quant < 1)
{
quant = 1;
}
}
mb->quant = quant;
if (dec->interlacing)
{
mb->field_dct = BitstreamGetBit(bs);
DEBUG1("decp: field_dct: ", mb->field_dct);
if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
{
mb->field_pred = BitstreamGetBit(bs);
DEBUG1("decp: field_pred: ", mb->field_pred);
if (mb->field_pred)
{
mb->field_for_top = BitstreamGetBit(bs);
DEBUG1("decp: field_for_top: ", mb->field_for_top);
mb->field_for_bot = BitstreamGetBit(bs);
DEBUG1("decp: field_for_bot: ", mb->field_for_bot);
}
}
}
if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
{
if (dec->interlacing && mb->field_pred)
{
get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode);
}
else
{
get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x;
mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y;
}
}
else if (mb->mode == MODE_INTER4V /* || mb->mode == MODE_INTER4V_Q */)
{
get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode);
get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode);
get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode);
}
else // MODE_INTRA, MODE_INTRA_Q
{
mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold);
continue;
}
decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant, rounding);
}
else // not coded
{
mb->mode = MODE_NOT_CODED;
mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
// copy macroblock directly from ref to cur
start_timer();
transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x),
dec->refn.y + (16*y)*dec->edged_width + (16*x),
dec->edged_width);
transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8),
dec->refn.y + (16*y)*dec->edged_width + (16*x+8),
dec->edged_width);
transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x),
dec->refn.y + (16*y+8)*dec->edged_width + (16*x),
dec->edged_width);
transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8),
dec->refn.y + (16*y+8)*dec->edged_width + (16*x+8),
dec->edged_width);
transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x),
dec->refn.u + (8*y)*dec->edged_width/2 + (8*x),
dec->edged_width/2);
transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x),
dec->refn.v + (8*y)*dec->edged_width/2 + (8*x),
dec->edged_width/2);
stop_transfer_timer();
}
}
}
}
int decoder_decode(DECODER * dec, XVID_DEC_FRAME * frame)
{
Bitstream bs;
uint32_t rounding;
uint32_t quant;
uint32_t fcode;
uint32_t intra_dc_threshold;
start_global_timer();
BitstreamInit(&bs, frame->bitstream, frame->length);
switch (BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold, 0))
{
case P_VOP :
decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold);
break;
case I_VOP :
//DEBUG1("",intra_dc_threshold);
decoder_iframe(dec, &bs, quant, intra_dc_threshold);
break;
case B_VOP : // ignore
break;
case N_VOP : // vop not coded
break;
default :
return XVID_ERR_FAIL;
}
frame->length = BitstreamPos(&bs) / 8;
start_timer();
image_output(&dec->cur, dec->width, dec->height, dec->edged_width,
frame->image, frame->stride, frame->colorspace);
stop_conv_timer();
emms();
stop_global_timer();
return XVID_ERR_OK;
}
int decoder_find_vol (DECODER * dec,
XVID_DEC_FRAME * frame,
XVID_DEC_PARAM * param)
{
Bitstream bs;
uint32_t rounding;
uint32_t quant;
uint32_t fcode;
uint32_t intra_dc_threshold;
int ret;
BitstreamInit(&bs, frame->bitstream, frame->length);
ret = BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold, 1);
frame->length = BitstreamPos(&bs) / 8;
if (ret > 0) {
param->width = dec->width;
param->height = dec->height;
return decoder_initialize(dec);
}
if (ret < 0) return XVID_ERR_FORMAT;
return XVID_ERR_FAIL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -