📄 mbcoding.c
字号:
/* write dquant */
if (pMB->mode == MODE_INTRA_Q)
BitstreamPutBits(bs, DQ_VALUE2INDEX(pMB->dquant), 2);
/* write interlacing */
if (frame->vol_flags & XVID_VOL_INTERLACING) {
BitstreamPutBit(bs, pMB->field_dct);
}
/* code block coeffs */
for (i = 0; i < 6; i++) {
if (i < 4)
BitstreamPutBits(bs, dcy_tab[qcoeff[i * 64 + 0] + 255].code,
dcy_tab[qcoeff[i * 64 + 0] + 255].len);
else
BitstreamPutBits(bs, dcc_tab[qcoeff[i * 64 + 0] + 255].code,
dcc_tab[qcoeff[i * 64 + 0] + 255].len);
if (pMB->cbp & (1 << (5 - i))) {
const uint16_t *scan_table =
frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
scan_tables[2] : scan_tables[pMB->acpred_directions[i]];
bits = BitstreamPos(bs);
CodeCoeffIntra(bs, &qcoeff[i * 64], scan_table);
bits = BitstreamPos(bs) - bits;
pStat->iTextBits += bits;
}
}
}
static void
CodeBlockInter(const FRAMEINFO * const frame,
const MACROBLOCK * pMB,
int16_t qcoeff[6 * 64],
Bitstream * bs,
Statistics * pStat)
{
int32_t i;
uint32_t bits, mcbpc, cbpy;
mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3);
cbpy = 15 - (pMB->cbp >> 2);
/* write mcbpc */
BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code,
mcbpc_inter_tab[mcbpc].len);
if ( (frame->coding_type == S_VOP) && (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) )
BitstreamPutBit(bs, pMB->mcsel); /* mcsel: '0'=local motion, '1'=GMC */
/* write cbpy */
BitstreamPutBits(bs, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);
/* write dquant */
if (pMB->mode == MODE_INTER_Q)
BitstreamPutBits(bs, DQ_VALUE2INDEX(pMB->dquant), 2);
/* interlacing */
if (frame->vol_flags & XVID_VOL_INTERLACING) {
if (pMB->cbp) {
BitstreamPutBit(bs, pMB->field_dct);
DPRINTF(XVID_DEBUG_MB,"codep: field_dct: %i\n", pMB->field_dct);
}
/* if inter block, write field ME flag */
if ((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) && (pMB->mcsel == 0)) {
BitstreamPutBit(bs, 0 /*pMB->field_pred*/); /* not implemented yet */
DPRINTF(XVID_DEBUG_MB,"codep: field_pred: %i\n", pMB->field_pred);
/* write field prediction references */
#if 0 /* Remove the #if once field_pred is supported */
if (pMB->field_pred) {
BitstreamPutBit(bs, pMB->field_for_top);
BitstreamPutBit(bs, pMB->field_for_bot);
}
#endif
}
}
bits = BitstreamPos(bs);
/* code motion vector(s) if motion is local */
if (!pMB->mcsel)
for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) {
CodeVector(bs, pMB->pmvs[i].x, frame->fcode);
CodeVector(bs, pMB->pmvs[i].y, frame->fcode);
#ifdef _DEBUG
if (i == 0) /* for simplicity */ {
int coded_length = BitstreamPos(bs) - bits;
int estimated_length = d_mv_bits(pMB->pmvs[i].x, pMB->pmvs[i].y, zeroMV, frame->fcode, 0);
assert(estimated_length == coded_length);
d_mv_bits(pMB->pmvs[i].x, pMB->pmvs[i].y, zeroMV, frame->fcode, 0);
}
#endif
}
bits = BitstreamPos(bs) - bits;
pStat->iMVBits += bits;
bits = BitstreamPos(bs);
/* code block coeffs */
for (i = 0; i < 6; i++)
if (pMB->cbp & (1 << (5 - i))) {
const uint16_t *scan_table =
frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
scan_tables[2] : scan_tables[0];
CodeCoeffInter(bs, &qcoeff[i * 64], scan_table);
}
bits = BitstreamPos(bs) - bits;
pStat->iTextBits += bits;
}
void
MBCoding(const FRAMEINFO * const frame,
MACROBLOCK * pMB,
int16_t qcoeff[6 * 64],
Bitstream * bs,
Statistics * pStat)
{
if (frame->coding_type != I_VOP)
BitstreamPutBit(bs, 0); /* not_coded */
if (frame->vop_flags & XVID_VOP_GREYSCALE) {
pMB->cbp &= 0x3C; /* keep only bits 5-2 */
qcoeff[4*64+0]=0; /* for INTRA DC value is saved */
qcoeff[5*64+0]=0;
}
if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
CodeBlockIntra(frame, pMB, qcoeff, bs, pStat);
else
CodeBlockInter(frame, pMB, qcoeff, bs, pStat);
}
/***************************************************************
* bframe encoding start
***************************************************************/
/*
mbtype
0 1b direct(h263) mvdb
1 01b interpolate mc+q dbquant, mvdf, mvdb
2 001b backward mc+q dbquant, mvdb
3 0001b forward mc+q dbquant, mvdf
*/
static __inline void
put_bvop_mbtype(Bitstream * bs,
int value)
{
switch (value) {
case MODE_FORWARD:
BitstreamPutBit(bs, 0);
case MODE_BACKWARD:
BitstreamPutBit(bs, 0);
case MODE_INTERPOLATE:
BitstreamPutBit(bs, 0);
case MODE_DIRECT:
BitstreamPutBit(bs, 1);
default:
break;
}
}
/*
dbquant
-2 10b
0 0b
+2 11b
*/
static __inline void
put_bvop_dbquant(Bitstream * bs,
int value)
{
switch (value) {
case 0:
BitstreamPutBit(bs, 0);
return;
case -2:
BitstreamPutBit(bs, 1);
BitstreamPutBit(bs, 0);
return;
case 2:
BitstreamPutBit(bs, 1);
BitstreamPutBit(bs, 1);
return;
default:; /* invalid */
}
}
void
MBCodingBVOP(const FRAMEINFO * const frame,
const MACROBLOCK * mb,
const int16_t qcoeff[6 * 64],
const int32_t fcode,
const int32_t bcode,
Bitstream * bs,
Statistics * pStat)
{
int vcode = fcode;
unsigned int i;
const uint16_t *scan_table =
frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
scan_tables[2] : scan_tables[0];
int bits;
/* ------------------------------------------------------------------
when a block is skipped it is decoded DIRECT(0,0)
hence is interpolated from forward & backward frames
------------------------------------------------------------------ */
if (mb->mode == MODE_DIRECT_NONE_MV) {
BitstreamPutBit(bs, 1); /* skipped */
return;
}
BitstreamPutBit(bs, 0); /* not skipped */
if (mb->cbp == 0) {
BitstreamPutBit(bs, 1); /* cbp == 0 */
} else {
BitstreamPutBit(bs, 0); /* cbp == xxx */
}
put_bvop_mbtype(bs, mb->mode);
if (mb->cbp) {
BitstreamPutBits(bs, mb->cbp, 6);
}
if (mb->mode != MODE_DIRECT && mb->cbp != 0) {
put_bvop_dbquant(bs, 0); /* todo: mb->dquant = 0 */
}
if (frame->vol_flags & XVID_VOL_INTERLACING) {
if (mb->cbp) {
BitstreamPutBit(bs, mb->field_dct);
DPRINTF(XVID_DEBUG_MB,"codep: field_dct: %i\n", mb->field_dct);
}
/* if not direct block, write field ME flag */
if (mb->mode != MODE_DIRECT) {
BitstreamPutBit(bs, 0 /*mb->field_pred*/); /* field ME not implemented */
/* write field prediction references */
#if 0 /* Remove the #if once field_pred is supported */
if (mb->field_pred) {
BitstreamPutBit(bs, mb->field_for_top);
BitstreamPutBit(bs, mb->field_for_bot);
}
#endif
}
}
bits = BitstreamPos(bs);
switch (mb->mode) {
case MODE_INTERPOLATE:
CodeVector(bs, mb->pmvs[1].x, vcode); /* forward vector of interpolate mode */
CodeVector(bs, mb->pmvs[1].y, vcode);
case MODE_BACKWARD:
vcode = bcode;
case MODE_FORWARD:
CodeVector(bs, mb->pmvs[0].x, vcode);
CodeVector(bs, mb->pmvs[0].y, vcode);
break;
case MODE_DIRECT:
CodeVector(bs, mb->pmvs[3].x, 1); /* fcode is always 1 for delta vector */
CodeVector(bs, mb->pmvs[3].y, 1); /* prediction is always (0,0) */
default: break;
}
pStat->iMVBits += BitstreamPos(bs) - bits;
bits = BitstreamPos(bs);
for (i = 0; i < 6; i++) {
if (mb->cbp & (1 << (5 - i))) {
CodeCoeffInter(bs, &qcoeff[i * 64], scan_table);
}
}
pStat->iTextBits += BitstreamPos(bs) - bits;
}
/***************************************************************
* decoding stuff starts here *
***************************************************************/
/*
* for IVOP addbits == 0
* for PVOP addbits == fcode - 1
* for BVOP addbits == max(fcode,bcode) - 1
* returns true or false
*/
int
check_resync_marker(Bitstream * bs, int addbits)
{
uint32_t nbits;
uint32_t code;
uint32_t nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits;
nbits = BitstreamNumBitsToByteAlign(bs);
code = BitstreamShowBits(bs, nbits);
if (code == (((uint32_t)1 << (nbits - 1)) - 1))
{
return BitstreamShowBitsFromByteAlign(bs, nbitsresyncmarker) == RESYNC_MARKER;
}
return 0;
}
int
get_mcbpc_intra(Bitstream * bs)
{
uint32_t index;
index = BitstreamShowBits(bs, 9);
index >>= 3;
BitstreamSkip(bs, mcbpc_intra_table[index].len);
return mcbpc_intra_table[index].code;
}
int
get_mcbpc_inter(Bitstream * bs)
{
uint32_t index;
index = MIN(BitstreamShowBits(bs, 9), 256);
BitstreamSkip(bs, mcbpc_inter_table[index].len);
return mcbpc_inter_table[index].code;
}
int
get_cbpy(Bitstream * bs,
int intra)
{
int cbpy;
uint32_t index = BitstreamShowBits(bs, 6);
BitstreamSkip(bs, cbpy_table[index].len);
cbpy = cbpy_table[index].code;
if (!intra)
cbpy = 15 - cbpy;
return cbpy;
}
static __inline int
get_mv_data(Bitstream * bs)
{
uint32_t index;
if (BitstreamGetBit(bs))
return 0;
index = BitstreamShowBits(bs, 12);
if (index >= 512) {
index = (index >> 8) - 2;
BitstreamSkip(bs, TMNMVtab0[index].len);
return TMNMVtab0[index].code;
}
if (index >= 128) {
index = (index >> 2) - 32;
BitstreamSkip(bs, TMNMVtab1[index].len);
return TMNMVtab1[index].code;
}
index -= 4;
BitstreamSkip(bs, TMNMVtab2[index].len);
return TMNMVtab2[index].code;
}
int
get_mv(Bitstream * bs,
int fcode)
{
int data;
int res;
int mv;
int scale_fac = 1 << (fcode - 1);
data = get_mv_data(bs);
if (scale_fac == 1 || data == 0)
return data;
res = BitstreamGetBits(bs, fcode - 1);
mv = ((abs(data) - 1) * scale_fac) + res + 1;
return data < 0 ? -mv : mv;
}
int
get_dc_dif(Bitstream * bs,
uint32_t dc_size)
{
int code = BitstreamGetBits(bs, dc_size);
int msb = code >> (dc_size - 1);
if (msb == 0)
return (-1 * (code ^ ((1 << dc_size) - 1)));
return code;
}
int
get_dc_size_lum(Bitstream * bs)
{
int code, i;
code = BitstreamShowBits(bs, 11);
for (i = 11; i > 3; i--) {
if (code == 1) {
BitstreamSkip(bs, i);
return i + 1;
}
code >>= 1;
}
BitstreamSkip(bs, dc_lum_tab[code].len);
return dc_lum_tab[code].code;
}
int
get_dc_size_chrom(Bitstream * bs)
{
uint32_t code, i;
code = BitstreamShowBits(bs, 12);
for (i = 12; i > 2; i--) {
if (code == 1) {
BitstreamSkip(bs, i);
return i;
}
code >>= 1;
}
return 3 - BitstreamGetBits(bs, 2);
}
#define GET_BITS(cache, n) ((cache)>>(32-(n)))
static __inline int
get_coeff(Bitstream * bs,
int *run,
int *last,
int intra,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -