📄 fame_syntax_mpeg4.c
字号:
if(pattern & 1) { a = syntax_mpeg4->y_pred_h[1]; /* left block */ b = syntax_mpeg4->y_pred_h[0]; /* top left block */ c = syntax_mpeg4->y_pred_v[0][mb_x]; /* top block */ /* choose between vertical and horizontal prediction */ if(abs(*a - *b) < abs(*b - *c)) { FASTAC8H(d[0], blocks[0]); FASTSCALE8H(p[0], c, qs); FASTSAD8H(ac_sad, p[0], d[0]); o[0] = TOP_PREDICTED; *p[0] = (*p[0] + (ys>>1)) / ys; FASTDIFF8H(d[0], p[0]); *d[0] = mpeg4_table_clip[*d[0]]; FASTSUM8H(p[0], d[0]); *p[0] *= ys; } else { FASTAC8V(d[0], blocks[0]); FASTSCALE8V(p[0], a, qs); FASTSAD8V(ac_sad, p[0], d[0]); o[0] = LEFT_PREDICTED; *p[0] = (*p[0] + (ys>>1)) / ys; FASTDIFF8V(d[0], p[0]); *d[0] = mpeg4_table_clip[*d[0]]; FASTSUM8V(p[0], d[0]); *p[0] *= ys; } p[0][FASTQS] = qs; } /* Y (0,1) block */ if(pattern & 2) { a = p[0]; /* left block */ b = syntax_mpeg4->y_pred_v[0][mb_x]; /* top left block */ c = syntax_mpeg4->y_pred_v[1][mb_x]; /* top block */ /* choose between vertical and horizontal prediction */ if(abs(*a - *b) < abs(*b - *c)) { FASTAC8H(d[1], blocks[1]); FASTSCALE8H(p[1], c, qs); FASTSAD8H(ac_sad, p[1], d[1]); o[1] = TOP_PREDICTED; *p[1] = (*p[1] + (ys>>1)) / ys; FASTDIFF8H(d[1], p[1]); *d[1] = mpeg4_table_clip[*d[1]]; FASTSUM8H(p[1], d[1]); *p[1] *= ys; } else { FASTAC8V(d[1], blocks[1]); FASTSCALE8V(p[1], a, qs); FASTSAD8V(ac_sad, p[1], d[1]); o[1] = LEFT_PREDICTED; *p[1] = (*p[1] + (ys>>1)) / ys; FASTDIFF8V(d[1], p[1]); *d[1] = mpeg4_table_clip[*d[1]]; FASTSUM8V(p[1], d[1]); *p[1] *= ys; } p[1][FASTQS] = qs; } /* Y (1,0) block */ if(pattern & 4) { a = syntax_mpeg4->y_pred_h[2]; /* left block */ b = syntax_mpeg4->y_pred_h[1]; /* top left block */ c = p[0]; /* top block */ /* choose between vertical and horizontal prediction */ if(abs(*a - *b) < abs(*b - *c)) { FASTAC8H(d[2], blocks[2]); FASTSCALE8H(p[2], c, qs); FASTSAD8H(ac_sad, p[2], d[2]); o[2] = TOP_PREDICTED; *p[2] = (*p[2] + (ys>>1)) / ys; FASTDIFF8H(d[2], p[2]); *d[2] = mpeg4_table_clip[*d[2]]; FASTSUM8H(p[2], d[2]); *p[2] *= ys; } else { FASTAC8V(d[2], blocks[2]); FASTSCALE8V(p[2], a, qs); FASTSAD8V(ac_sad, p[2], d[2]); o[2] = LEFT_PREDICTED; *p[2] = (*p[2] + (ys>>1)) / ys; FASTDIFF8V(d[2], p[2]); *d[2] = mpeg4_table_clip[*d[2]]; FASTSUM8V(p[2], d[2]); *p[2] *= ys; } p[2][FASTQS] = qs; } /* Y (1,1) block */ if(pattern & 8) { a = p[2]; /* left block */ b = p[0]; /* top left block */ c = p[1]; /* top block */ /* choose between vertical and horizontal prediction */ if(abs(*a - *b) < abs(*b - *c)) { FASTAC8H(d[3], blocks[3]); FASTSCALE8H(p[3], c, qs); FASTSAD8H(ac_sad, p[3], d[3]); o[3] = TOP_PREDICTED; *p[3] = (*p[3] + (ys>>1)) / ys; FASTDIFF8H(d[3], p[3]); *d[3] = mpeg4_table_clip[*d[3]]; FASTSUM8H(p[3], d[3]); *p[3] *= ys; } else { FASTAC8V(d[3], blocks[3]); FASTSCALE8V(p[3], a, qs); FASTSAD8V(ac_sad, p[3], d[3]); o[3] = LEFT_PREDICTED; *p[3] = (*p[3] + (ys>>1)) / ys; FASTDIFF8V(d[3], p[3]); *d[3] = mpeg4_table_clip[*d[3]]; FASTSUM8V(p[3], d[3]); *p[3] *= ys; } p[3][FASTQS] = qs; } /* Cb block */ a = syntax_mpeg4->cb_pred_h[1]; /* left block */ b = syntax_mpeg4->cb_pred_h[0]; /* top left block */ c = syntax_mpeg4->cb_pred_v[mb_x]; /* top block */ /* choose between vertical and horizontal prediction */ if(abs(*a - *b) < abs(*b - *c)) { FASTAC8H(d[4], blocks[4]); FASTSCALE8H(p[4], c, qs); FASTSAD8H(ac_sad, p[4], d[4]); o[4] = TOP_PREDICTED; *p[4] = (*p[4] + (cs>>1)) / cs; FASTDIFF8H(d[4], p[4]); *d[4] = mpeg4_table_clip[*d[4]]; FASTSUM8H(p[4], d[4]); *p[4] *= cs; } else { FASTAC8V(d[4], blocks[4]); FASTSCALE8V(p[4], a, qs); FASTSAD8V(ac_sad, p[4], d[4]); o[4] = LEFT_PREDICTED; *p[4] = (*p[4] + (cs>>1)) / cs; FASTDIFF8V(d[4], p[4]); *d[4] = mpeg4_table_clip[*d[4]]; FASTSUM8V(p[4], d[4]); *p[4] *= cs; } p[4][FASTQS] = qs; /* Cr block */ a = syntax_mpeg4->cr_pred_h[1]; /* left block */ b = syntax_mpeg4->cr_pred_h[0]; /* top left block */ c = syntax_mpeg4->cr_pred_v[mb_x]; /* top block */ /* choose between vertical and horizontal prediction */ if(abs(*a - *b) < abs(*b - *c)) { FASTAC8H(d[5], blocks[5]); FASTSCALE8H(p[5], c, qs); FASTSAD8H(ac_sad, p[5], d[5]); o[5] = TOP_PREDICTED; *p[5] = (*p[5] + (cs>>1)) / cs; FASTDIFF8H(d[5], p[5]); *d[5] = mpeg4_table_clip[*d[5]]; FASTSUM8H(p[5], d[5]); *p[5] *= cs; } else { FASTAC8V(d[5], blocks[5]); FASTSCALE8V(p[5], a, qs); FASTSAD8V(ac_sad, p[5], d[5]); o[5] = LEFT_PREDICTED; *p[5] = (*p[5] + (cs>>1)) / cs; FASTDIFF8V(d[5], p[5]); *d[5] = mpeg4_table_clip[*d[5]]; FASTSUM8V(p[5], d[5]); *p[5] *= cs; } p[5][FASTQS] = qs; /* AC/DC adjust blocks */ if(ac_sad > 0) { for(i = 0; i < 6; i++) { if(o[i] == LEFT_PREDICTED) { zigzag[i] = mpeg4_zigzag_alternate_vertical_table; COPY8V(blocks[i], d[i]); } else { zigzag[i] = mpeg4_zigzag_alternate_horizontal_table; COPY8H(blocks[i], d[i]); } } } else { zigzag[0] = zigzag[1] = zigzag[2] = zigzag[3] = zigzag[4] = zigzag[5] = mpeg4_zigzag_table; } /* check for not coded blocks */ for(j = 0; j < 6; j++) { coded[j] = 0; for(i = 1; i < 64; i++) { coded[j] |= blocks[j][i]; } } /* write mcbpc */ cbp = 0; if(coded[4]) cbp |= 2; if(coded[5]) cbp |= 1; if(syntax_mpeg4->vop_coding_type == MPEG4_I_FRAME) { if(dquant) { bitbuffer_write(&syntax_mpeg4->buffer, mcbpc_I_dq[cbp].code, mcbpc_I_dq[cbp].length); } else { bitbuffer_write(&syntax_mpeg4->buffer, mcbpc_I[cbp].code, mcbpc_I[cbp].length); } } else { if(dquant) { bitbuffer_write(&syntax_mpeg4->buffer, mcbpc_P_intra_dq[cbp].code, mcbpc_P_intra_dq[cbp].length); } else { bitbuffer_write(&syntax_mpeg4->buffer, mcbpc_P_intra[cbp].code, mcbpc_P_intra[cbp].length); } } /* AC pred flag */ if(ac_sad > 0) { bitbuffer_write(&syntax_mpeg4->buffer, 1, 1); } else { bitbuffer_write(&syntax_mpeg4->buffer, 0, 1); } /* write cbpy */ bc = cbp = 0; for(i = 0; i < 4; i++) { if(pattern & (1<<i)) { bc++; /* number of non-transparent blocks */ cbp <<= 1; /* coded block pattern */ if(coded[i]) cbp |= 1; } } bitbuffer_write(&syntax_mpeg4->buffer, cbpy[bc-1][cbp].code, cbpy[bc-1][cbp].length); /* write dquant */ if(dquant) { static const int dquant_table[5] = { 1, 0, 0, 2, 3 }; bitbuffer_write(&syntax_mpeg4->buffer, dquant_table[dquant+2], 2); } if(pattern & 1) mpeg4_block_intra(syntax,blocks[0],encode_ydc_table,*d[0],zigzag[0],coded[0]); if(pattern & 2) mpeg4_block_intra(syntax,blocks[1],encode_ydc_table,*d[1],zigzag[1],coded[1]); if(pattern & 4) mpeg4_block_intra(syntax,blocks[2],encode_ydc_table,*d[2],zigzag[2],coded[2]); if(pattern & 8) mpeg4_block_intra(syntax,blocks[3],encode_ydc_table,*d[3],zigzag[3],coded[3]); mpeg4_block_intra(syntax,blocks[4],encode_cdc_table,*d[4],zigzag[4],coded[4]); mpeg4_block_intra(syntax,blocks[5],encode_cdc_table,*d[5],zigzag[5],coded[5]); if(ac_sad >= 0) { for(i = 0; i < 6; i++) { if(o[i] == LEFT_PREDICTED) { COPY8V(blocks[i], p[i]); } else { COPY8H(blocks[i], p[i]); } } } /* TODO: fill in predictors from block */ /* update predictors */ FASTCOPY16(syntax_mpeg4->y_pred_h[0], syntax_mpeg4->y_pred_v[1][mb_x]); FASTCOPY16(syntax_mpeg4->y_pred_h[1], p[1]); FASTCOPY16(syntax_mpeg4->y_pred_h[2], p[3]); FASTCOPY16(syntax_mpeg4->y_pred_v[0][mb_x], p[2]); FASTCOPY16(syntax_mpeg4->y_pred_v[1][mb_x], syntax_mpeg4->y_pred_h[2]); FASTCOPY16(syntax_mpeg4->cb_pred_h[0], syntax_mpeg4->cb_pred_v[mb_x]); FASTCOPY16(syntax_mpeg4->cr_pred_h[0], syntax_mpeg4->cr_pred_v[mb_x]); FASTCOPY16(syntax_mpeg4->cb_pred_v[mb_x], p[4]); FASTCOPY16(syntax_mpeg4->cr_pred_v[mb_x], p[5]); FASTCOPY16(syntax_mpeg4->cb_pred_h[1], syntax_mpeg4->cb_pred_v[mb_x]); FASTCOPY16(syntax_mpeg4->cr_pred_h[1], syntax_mpeg4->cr_pred_v[mb_x]); /* mark all vectors as valid */ syntax_mpeg4->mv_pred[0].count = 64; syntax_mpeg4->mv_pred[1].count = 64; syntax_mpeg4->mv_pred[2].count = 64; syntax_mpeg4->mv_pred[3].count = 64; retval = 0; } else { /* reset predictors */ FASTCOPY16(syntax_mpeg4->y_pred_h[0], syntax_mpeg4->y_pred_v[1][mb_x]); FASTCOPY16(syntax_mpeg4->y_pred_h[1], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->y_pred_h[2], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->y_pred_v[0][mb_x], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->y_pred_v[1][mb_x], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cb_pred_h[0], syntax_mpeg4->cb_pred_v[mb_x]); FASTCOPY16(syntax_mpeg4->cr_pred_h[0], syntax_mpeg4->cr_pred_v[mb_x]); FASTCOPY16(syntax_mpeg4->cb_pred_v[mb_x], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cr_pred_v[mb_x], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cb_pred_h[1], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cr_pred_h[1], syntax_mpeg4->pred_default); syntax_mpeg4->mv_pred[0].count = 0; syntax_mpeg4->mv_pred[1].count = 0; syntax_mpeg4->mv_pred[2].count = 0; syntax_mpeg4->mv_pred[3].count = 0; retval = dquant; /* cancel dquant */ } /* reset motion predictors */ syntax_mpeg4->mv_pred[0].dx = syntax_mpeg4->mv_pred[0].dy = 0; syntax_mpeg4->mv_pred[1].dx = syntax_mpeg4->mv_pred[1].dy = 0; syntax_mpeg4->mv_pred[2].dx = syntax_mpeg4->mv_pred[2].dy = 0; syntax_mpeg4->mv_pred[3].dx = syntax_mpeg4->mv_pred[3].dy = 0; syntax_mpeg4->mv_pred+=4; return(retval);}static void mpeg4_block_inter(fame_syntax_t *syntax, short *block){ fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax); short i, v; unsigned long last; fame_vlc_t const *vlc; fame_bitbuffer_t * const buffer = &syntax_mpeg4->buffer; unsigned char * data = buffer->data; unsigned long shift = buffer->shift; i = 0; last = 0; /* i < 64 checking not needed as all-zero block is not coded */ while((v = block[mpeg4_zigzag_table[i]]) == 0) i++; do { /* count zeroes */ vlc = syntax_mpeg4->inter_table + (mpeg4_table_clip[v] << 6) + i - last; last = ++i; while(i < 64 && (v = block[mpeg4_zigzag_table[i]]) == 0) i++; /* write code */ if(i != 64) { fast_bitbuffer_write(data, shift, vlc->code, vlc->length); } else { vlc += 64*511; fast_bitbuffer_write(data, shift, vlc->code, vlc->length); break; } } while(1); buffer->data = data; buffer->shift = shift;}static void inline mpeg4_write_vector(fame_syntax_t *syntax, short delta){ fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax); /* vectors are in half-sample units */ if (delta == 0) { bitbuffer_write(&syntax_mpeg4->buffer, mb_motion_table[32].code, mb_motion_table[32].length); } else { short length; short f_code; short code; short residual; f_code = syntax_mpeg4->vop_fcode_forward; length = 16 << f_code; f_code--; if(delta >= length) delta = delta - length - length; if(delta < -length) delta = delta + length + length; if(delta > 0) { delta--; residual = delta & ((1 << f_code) - 1); code = ((delta - residual) >> f_code) + 1; } else { delta = -delta; delta--; residual = delta & ((1 << f_code) - 1); code = ((delta - residual) >> f_code) + 1; code = -code; } code += 32; bitbuffer_write(&syntax_mpeg4->buffer, mb_motion_table[code].code, mb_motion_table[code].
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -