📄 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 voidCodeBlockInter(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 } } /* 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); } 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;}voidMBCoding(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 voidput_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 voidput_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 */ }}voidMBCodingBVOP(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 } } 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; } 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 */intcheck_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;}intget_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;}intget_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;}intget_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 intget_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;}intget_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;}intget_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;}intget_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;}intget_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 intget_coeff(Bitstream * bs, int *run, int *last, int intra, int short_video_header){ uint32_t mode; int32_t level; REVERSE_EVENT *reverse_event; uint32_t cache = BitstreamShowBits(bs, 32); if (short_video_header) /* inter-VLCs will be used for both intra and inter blocks */ intra = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -