📄 mbcoding.c
字号:
} /* ac prediction flag */ if (pMB->acpred_directions[0]) BitstreamPutBits(bs, 1, 1); else BitstreamPutBits(bs, 0, 1); /* write cbpy */ BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); /* write dquant */ if (pMB->mode == MODE_INTRA_Q) BitstreamPutBits(bs, pMB->dquant, 2); /* write interlacing */ if (frame->global_flags & XVID_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))) { bits = BitstreamPos(bs);#ifdef BIGLUT CodeCoeff(bs, &qcoeff[i * 64], intra_table, scan_tables[pMB->acpred_directions[i]], 1);#else CodeCoeffIntra(bs, &qcoeff[i * 64], scan_tables[pMB->acpred_directions[i]]);#endif bits = BitstreamPos(bs) - bits; pStat->iTextBits += bits; } }}static voidCodeBlockInter(const FRAMEINFO * 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); /* write cbpy */ BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); /* write dquant */ if (pMB->mode == MODE_INTER_Q) BitstreamPutBits(bs, pMB->dquant, 2); /* interlacing */ if (frame->global_flags & XVID_INTERLACING) { if (pMB->cbp) { BitstreamPutBit(bs, pMB->field_dct); DPRINTF(DPRINTF_DEBUG, "codep: field_dct: %d", pMB->field_dct); } /* if inter block, write field ME flag */ if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { BitstreamPutBit(bs, pMB->field_pred); DPRINTF(DPRINTF_DEBUG, "codep: field_pred: %d", pMB->field_pred); /* write field prediction references */ if (pMB->field_pred) { BitstreamPutBit(bs, pMB->field_for_top); BitstreamPutBit(bs, pMB->field_for_bot); } } } /* code motion vector(s) */ for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) { CodeVector(bs, pMB->pmvs[i].x, frame->fcode, pStat); CodeVector(bs, pMB->pmvs[i].y, frame->fcode, pStat); } bits = BitstreamPos(bs); /* code block coeffs */ for (i = 0; i < 6; i++) if (pMB->cbp & (1 << (5 - i)))#ifdef BIGLUT CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0);#else CodeCoeffInter(bs, &qcoeff[i * 64], scan_tables[0]);#endif bits = BitstreamPos(bs) - bits; pStat->iTextBits += bits;}/***************************************************************************** * Macro Block bitstream encoding functions ****************************************************************************/voidMBCoding(const FRAMEINFO * frame, MACROBLOCK * pMB, int16_t qcoeff[6 * 64], Bitstream * bs, Statistics * pStat){ if (frame->coding_type == P_VOP) { BitstreamPutBit(bs, 0); /* coded */ } if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) CodeBlockIntra(frame, pMB, qcoeff, bs, pStat); else CodeBlockInter(frame, pMB, qcoeff, bs, pStat);}voidMBSkip(Bitstream * bs){ BitstreamPutBit(bs, 1); /* not coded */ return;}/***************************************************************************** * 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;}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 = CLIP(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;}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);}/***************************************************************************** * Local inlined function to "decode" written vlc codes ****************************************************************************/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; if (short_video_header) /* inter-VLCs will be used for both intra and inter blocks */ intra = 0; if (BitstreamShowBits(bs, 7) != ESCAPE) { reverse_event = &DCT3D[intra][BitstreamShowBits(bs, 12)]; if ((level = reverse_event->event.level) == 0) goto error; *last = reverse_event->event.last; *run = reverse_event->event.run; BitstreamSkip(bs, reverse_event->len); return BitstreamGetBits(bs, 1) ? -level : level; } BitstreamSkip(bs, 7); if (short_video_header) { /* escape mode 4 - H.263 type, only used if short_video_header = 1 */ *last = BitstreamGetBit(bs); *run = BitstreamGetBits(bs, 6); level = BitstreamGetBits(bs, 8); if (level == 0 || level == 128) DPRINTF(DPRINTF_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d", level); return (level << 24) >> 24; } mode = BitstreamShowBits(bs, 2); if (mode < 3) { BitstreamSkip(bs, (mode == 2) ? 2 : 1); reverse_event = &DCT3D[intra][BitstreamShowBits(bs, 12)]; if ((level = reverse_event->event.level) == 0) goto error; *last = reverse_event->event.last; *run = reverse_event->event.run; BitstreamSkip(bs, reverse_event->len); if (mode < 2) /* first escape mode, level is offset */ level += max_level[intra][*last][*run]; else /* second escape mode, run is offset */ *run += max_run[intra][*last][level] + 1; return BitstreamGetBits(bs, 1) ? -level : level; } /* third escape mode - fixed length codes */ BitstreamSkip(bs, 2); *last = BitstreamGetBits(bs, 1); *run = BitstreamGetBits(bs, 6); BitstreamSkip(bs, 1); /* marker */ level = BitstreamGetBits(bs, 12); BitstreamSkip(bs, 1); /* marker */ return (level << 20) >> 20; error: *run = VLC_ERROR; return 0;}/***************************************************************************** * MB reading functions ****************************************************************************/voidget_intra_block(Bitstream * bs, int16_t * block, int direction, int coeff){ const uint16_t *scan = scan_tables[direction]; int level; int run; int last; do { level = get_coeff(bs, &run, &last, 1, 0); if (run == -1) { DPRINTF(DPRINTF_DEBUG, "fatal: invalid run"); break; } coeff += run; block[scan[coeff]] = level; DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[coeff], level); /*DPRINTF(DPRINTF_COEFF,"block[%i] %i %08x", scan[coeff], level, BitstreamShowBits(bs, 32)); */ if (level < -2047 || level > 2047) { DPRINTF(DPRINTF_DEBUG, "warning: intra_overflow: %d", level); } coeff++; } while (!last);}voidget_inter_block(Bitstream * bs, int16_t * block){ const uint16_t *scan = scan_tables[0]; int p; int level; int run; int last; p = 0; do { level = get_coeff(bs, &run, &last, 0, 0); if (run == -1) { DPRINTF(DPRINTF_ERROR, "fatal: invalid run"); break; } p += run; block[scan[p]] = level; DPRINTF(DPRINTF_COEFF,"block[%i] %i", scan[p], level); if (level < -2047 || level > 2047) { DPRINTF(DPRINTF_DEBUG, "warning: inter_overflow: %d", level); } p++; } while (!last);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -