📄 mvvolvop.c
字号:
dec->top_field_first = 0;
dec->alternate_vertical_scan = 0;
if (dec->interlacing)
{
dec->top_field_first = BitstreamGetBit(bs);
dec->alternate_vertical_scan = BitstreamGetBit(bs);
}
}
if ((dec->sprite_enable == SPRITE_STATIC || dec->sprite_enable== SPRITE_GMC) && coding_type == S_VOP)
{
int i;
for (i = 0 ; i < dec->sprite_warping_points; i++)
{
int length;
int x = 0, y = 0;
/* sprite code borowed from ffmpeg; thx Michael Niedermayer <michaelni@gmx.at> */
length = bs_get_spritetrajectory(bs);
if(length)
{
x= BitstreamGetBits(bs, length);
if ((x >> (length - 1)) == 0) /* if MSB not set it is negative*/
x = - (x ^ ((1 << length) - 1));
}
READ_MARKER();
length = bs_get_spritetrajectory(bs);
if(length)
{
y = BitstreamGetBits(bs, length);
if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/
y = - (y ^ ((1 << length) - 1));
}
READ_MARKER();
gmc_warp->duv[i].x = x;
gmc_warp->duv[i].y = y;
}
if (dec->sprite_brightness_change)
{
/* XXX: brightness_change_factor() */
}
if (dec->sprite_enable == SPRITE_STATIC)
{
/* XXX: todo */
}
}
if ((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1) /* vop_quant */
*quant = 1;
if (coding_type != I_VOP)
{
*fcode_forward = BitstreamGetBits(bs, 3); /* fcode_forward */
}
if (coding_type == B_VOP)
{
*fcode_backward = BitstreamGetBits(bs, 3); /* fcode_backward */
}
/*if (!dec->scalability)
{
if ((dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) &&
(coding_type != I_VOP))
{
BitstreamSkip(bs, 1); // vop_shape_coding_type
}
}*/
return coding_type;
}
int read_video_packet_header(Bitstream *bs,
DECODER * dec,
const int addbits,
int * quant,
int * fcode_forward,
int * fcode_backward,
int * intra_dc_threshold)
{
int startcode_bits = NUMBITS_VP_RESYNC_MARKER + addbits;
int mbnum_bits = log2bin(dec->mb_width * dec->mb_height - 1);
int mbnum;
int hec = 0;
BitstreamSkip(bs, BitstreamNumBitsToByteAlign(bs));
BitstreamSkip(bs, startcode_bits);
mbnum = BitstreamGetBits(bs, mbnum_bits); /* macroblock_number */
if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
{
*quant = BitstreamGetBits(bs, dec->quant_bits); /* quant_scale */
}
if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR)
hec = BitstreamGetBit(bs); /* header_extension_code */
if (hec)
{
int time_base;
int time_increment;
int coding_type;
for (time_base=0; BitstreamGetBit(bs)!=0; time_base++); /* modulo_time_base */
READ_MARKER();
if (dec->time_inc_bits)
time_increment = (BitstreamGetBits(bs, dec->time_inc_bits)); /* vop_time_increment */
READ_MARKER();
coding_type = BitstreamGetBits(bs, 2);
if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
{
*intra_dc_threshold = intra_dc_threshold_table[BitstreamGetBits(bs, 3)];
if (dec->sprite_enable == SPRITE_GMC && coding_type == S_VOP &&
dec->sprite_warping_points > 0)
{
/* TODO: sprite trajectory */
}
if (dec->reduced_resolution_enable &&
dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR &&
(coding_type == P_VOP || coding_type == I_VOP))
{
BitstreamSkip(bs, 1); /* XXX: vop_reduced_resolution */
}
if (coding_type != I_VOP && fcode_forward)
{
*fcode_forward = BitstreamGetBits(bs, 3);
}
if (coding_type == B_VOP && fcode_backward)
{
*fcode_backward = BitstreamGetBits(bs, 3);
}
}
}
if (dec->newpred_enable)
{
int vop_id;
int vop_id_for_prediction;
vop_id = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15));
if (BitstreamGetBit(bs)) /* vop_id_for_prediction_indication */
{
vop_id_for_prediction = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15));
}
READ_MARKER();
}
return mbnum;
}
/*
void decoder_bf_interpolate_mbinter(DECODER * dec,
IMAGE forward,
IMAGE backward,
MACROBLOCK * pMB,
const uint32_t x_pos,
const uint32_t y_pos,
Bitstream * bs,
const int direct)
{
uint32_t stride = dec->edged_width;
uint32_t stride2 = stride / 2;
int uv_dx, uv_dy;
int b_uv_dx, b_uv_dy;
uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
const uint32_t cbp = pMB->cbp;
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);
validate_vector(pMB->mvs, x_pos, y_pos, dec);
validate_vector(pMB->b_mvs, x_pos, y_pos, dec);
if (!direct)
{
uv_dx = pMB->mvs[0].x;
uv_dy = pMB->mvs[0].y;
b_uv_dx = pMB->b_mvs[0].x;
b_uv_dy = pMB->b_mvs[0].y;
if (dec->quarterpel)
{
if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING)
{
uv_dx = (uv_dx>>1) | (uv_dx&1);
uv_dy = (uv_dy>>1) | (uv_dy&1);
b_uv_dx = (b_uv_dx>>1) | (b_uv_dx&1);
b_uv_dy = (b_uv_dy>>1) | (b_uv_dy&1);
}
else
{
uv_dx /= 2;
uv_dy /= 2;
b_uv_dx /= 2;
b_uv_dy /= 2;
}
}
uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3];
b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];
}
else
{
if (dec->quarterpel)
{
if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING)
{
int z;
uv_dx = 0; uv_dy = 0;
b_uv_dx = 0; b_uv_dy = 0;
for (z = 0; z < 4; z++)
{
uv_dx += ((pMB->mvs[z].x>>1) | (pMB->mvs[z].x&1));
uv_dy += ((pMB->mvs[z].y>>1) | (pMB->mvs[z].y&1));
b_uv_dx += ((pMB->b_mvs[z].x>>1) | (pMB->b_mvs[z].x&1));
b_uv_dy += ((pMB->b_mvs[z].y>>1) | (pMB->b_mvs[z].y&1));
}
}
else
{
uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);
uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);
b_uv_dx = (pMB->b_mvs[0].x / 2) + (pMB->b_mvs[1].x / 2) + (pMB->b_mvs[2].x / 2) + (pMB->b_mvs[3].x / 2);
b_uv_dy = (pMB->b_mvs[0].y / 2) + (pMB->b_mvs[1].y / 2) + (pMB->b_mvs[2].y / 2) + (pMB->b_mvs[3].y / 2);
}
}
else
{
uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;
b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;
}
uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];
uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];
b_uv_dx = (b_uv_dx >> 3) + roundtab_76[b_uv_dx & 0xf];
b_uv_dy = (b_uv_dy >> 3) + roundtab_76[b_uv_dy & 0xf];
}
if(dec->quarterpel)
{
if(!direct)
{
interpolate16x16_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
}
else
{
interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,
pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,
pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,
pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);
}
}
else
{
interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos,
pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos,
pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8,
pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos + 8,
pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);
}
interpolate8x8_switch(dec->cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx,
uv_dy, stride2, 0);
interpolate8x8_switch(dec->cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx,
uv_dy, stride2, 0);
if(dec->quarterpel)
{
if(!direct)
{
interpolate16x16_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
}
else
{
interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,
pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,
pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,
pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
}
}
else
{
interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos, 16 * y_pos,
pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,
16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos,
16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,
16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
}
interpolate8x8_add_switch(dec->cur.u, backward.u, 8 * x_pos, 8 * y_pos,
b_uv_dx, b_uv_dy, stride2, 0);
interpolate8x8_add_switch(dec->cur.v, backward.v, 8 * x_pos, 8 * y_pos,
b_uv_dx, b_uv_dy, stride2, 0);
if (cbp)
decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
}
*/
void decoder_iframe(DECODER * dec,
Bitstream * bs,
int quant,
int intra_dc_threshold)
{
uint32_t bound;
uint32_t x, y;
const uint32_t mb_width = dec->mb_width;
const uint32_t mb_height = dec->mb_height;
bound = 0;
for (y = 0; y < mb_height; y++) {
for (x = 0; x < mb_width; x++) {
MACROBLOCK *mb;
uint32_t mcbpc;
uint32_t cbpc;
uint32_t acpred_flag;
uint32_t cbpy;
uint32_t cbp;
while (BitstreamShowBits(bs, 9) == 1)
BitstreamSkip(bs, 9);
if (check_resync_marker(bs, 0))
{
bound = read_video_packet_header(bs, dec, 0,
&quant, 0, 0, &intra_dc_threshold);
x = bound % mb_width;
y = bound / mb_width;
}
mb = &dec->mbs[y * dec->mb_width + x];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -