📄 fame_syntax_mpeg4.c
字号:
mv[0].dx = mv_pred[0].dx; mv[0].dy = mv_pred[0].dy; }}static void inline mpeg4_arithmetic_bit(fame_syntax_cae_t *cae, unsigned char bit){ *cae->sequence++ = bit; /* avoid start code emulation */ if (bit == 0) { cae->nzeros--; if (cae->nzeros == 0) { *cae->sequence++ = 1; cae->nonzero = 1; cae->nzeros = CAE_MAX_MIDDLE; } } else { cae->nonzero = 1; cae->nzeros = CAE_MAX_MIDDLE; }}static void inline mpeg4_arithmetic_follow(fame_syntax_cae_t *cae, unsigned char bit){ if (!cae->first_bit) mpeg4_arithmetic_bit(cae, bit); else cae->first_bit = 0; while(cae->bits_to_follow > 0) { mpeg4_arithmetic_bit(cae, !bit); cae->bits_to_follow--; }}static void inline mpeg4_arithmetic_renormalize(fame_syntax_cae_t *cae) { while (cae->range < CAE_1_4) { if (cae->lower >= CAE_1_2) { mpeg4_arithmetic_follow(cae, 1); cae->lower -= CAE_1_2; } else { if (cae->lower + cae->range <= CAE_1_2) mpeg4_arithmetic_follow(cae, 0); else { cae->bits_to_follow++; cae->lower -= CAE_1_4; } } cae->lower += cae->lower; cae->range += cae->range; }}static void inline mpeg4_arithmetic_enter(fame_syntax_cae_t *cae){ cae->lower = 0; cae->range = CAE_1_2 - 1; cae->bits_to_follow = 0; cae->first_bit = 1; cae->nzeros = CAE_MAX_HEADING; cae->nonzero = 0; cae->sequence = cae->buffer;}static void inline mpeg4_arithmetic_leave(fame_syntax_cae_t *cae){ int a = (cae->lower) >> 29; int b = (cae->range + cae->lower) >> 29; int nbits, bits, i; if (b == 0) b = 8; if (b - a >= 4 || (b - a == 3 && (a & 1))) { nbits = 2; bits = (a >> 1) + 1; } else { nbits = 3; bits = a + 1; } for (i = 1; i <= nbits; i++) mpeg4_arithmetic_follow(cae, (bits >> (nbits - i)) & 1); if (cae->nzeros < CAE_MAX_MIDDLE - CAE_MAX_TRAILING || cae->nonzero == 0) { mpeg4_arithmetic_follow(cae, 1); } *cae->sequence++ = 0xff;}static void inline mpeg4_arithmetic_code(fame_syntax_cae_t *cae, int cLPS){ signed long rLPS; rLPS = (cae->range >> 16) * cLPS; if (rLPS > 0) { cae->lower += cae->range - rLPS; cae->range = rLPS; } else cae->range += rLPS; mpeg4_arithmetic_renormalize(cae);}static void inline mpeg4_write_intra_bab(fame_syntax_t *syntax, int mb_x, int mb_y, unsigned char *bab, unsigned char *prev_bab, fame_bab_t bab_type){ fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax); int i, j; int line; unsigned char *ptr_h, *ptr_v; int pitch = syntax_mpeg4->mb_width + 2; int addr; int prev_addr[4]; /* initialize arithmetic encoders */ mpeg4_arithmetic_enter(syntax_mpeg4->cae_h); mpeg4_arithmetic_enter(syntax_mpeg4->cae_v); /* compute current bab address, add 1 for borders */ addr = mb_y * pitch + pitch + mb_x + 1; /* compute addresses of previous babs */ prev_addr[0] = addr - 1; prev_addr[1] = addr - pitch + 1; prev_addr[2] = addr - pitch; prev_addr[3] = addr - pitch - 1; /* compute context number for vlc table indexation */ /* bab = 0 if not_coded */ /* bab = 1 if all_coded */ /* bab = 2 if cae_coded */ /* context = 27*bab[i-1,j-1]+9*bab[i,j-1]+3*bab[i+1,j-1]+bab[i-1,j] */ /* TODO: fix context computation in case of multiple slice */ /* TODO: wrong for P frames */ i = 0; for(j = 0; j < 4; j++) { switch(prev_bab[prev_addr[j]]) { case bab_not_coded: break; case bab_all_coded: i += bab_type_intra_context_weight[j]; break; case bab_border_16x16: case bab_border_8x8: case bab_border_4x4: i += bab_type_intra_context_weight[j]; i += bab_type_intra_context_weight[j]; break; } } /* save current bab_type for further context computing */ prev_bab[addr] = bab_type; /* write vlc */ switch(bab_type) { case bab_not_coded: bitbuffer_write(&syntax_mpeg4->buffer, 1, bab_type_intra_vl[i][0]); return; case bab_all_coded: bitbuffer_write(&syntax_mpeg4->buffer, 1, bab_type_intra_vl[i][1]); return; case bab_border_16x16: case bab_border_8x8: case bab_border_4x4: bitbuffer_write(&syntax_mpeg4->buffer, 1, bab_type_intra_vl[i][2]); break; } /* no MVDs */ /* horizontal raster order context */#define CIH0 ((*(ptr_h ))<<0)#define CIH1 ((*(ptr_h -1))<<1)#define CIH2 ((*(ptr_h -2))<<2)#define CIH3 ((*(ptr_h-1*line+2))<<3)#define CIH4 ((*(ptr_h-1*line+1))<<4)#define CIH5 ((*(ptr_h-1*line ))<<5)#define CIH6 ((*(ptr_h-1*line-1))<<6)#define CIH7 ((*(ptr_h-1*line-2))<<7)#define CIH8 ((*(ptr_h-2*line+1))<<8)#define CIH9 ((*(ptr_h-2*line ))<<9)#define CIH10 ((*(ptr_h-2*line-1))<<10)#define CIH (CIH0|CIH1|CIH2|CIH3|CIH4|CIH5|CIH6|CIH7|CIH8|CIH9|CIH10) /* vertical raster order context */#define CIV0 ((*(ptr_v ))<<0)#define CIV1 ((*(ptr_v -1*line))<<1)#define CIV2 ((*(ptr_v -2*line))<<2)#define CIV3 ((*(ptr_v-1+2*line))<<3)#define CIV4 ((*(ptr_v-1+1*line))<<4)#define CIV5 ((*(ptr_v-1 ))<<5)#define CIV6 ((*(ptr_v-1-1*line))<<6)#define CIV7 ((*(ptr_v-1-2*line))<<7)#define CIV8 ((*(ptr_v-2+1*line))<<8)#define CIV9 ((*(ptr_v-2 ))<<9)#define CIV10 ((*(ptr_v-2-1*line))<<10)#define CIV (CIV0|CIV1|CIV2|CIV3|CIV4|CIV5|CIV6|CIV7|CIV8|CIV9|CIV10) switch(bab_type) { case bab_border_16x16: if(!syntax_mpeg4->change_conv_ratio_disable) bitbuffer_write(&syntax_mpeg4->buffer, 0, 1); /* CR = 1 */ line = 20; ptr_h = ptr_v = bab+2*line+2; /* skip border */ for(i = 0; i < 16; i++) { for(j = 0; j < 16; j++) { mpeg4_arithmetic_code(syntax_mpeg4->cae_h, syntax_mpeg4->symbol[CIH]); mpeg4_arithmetic_code(syntax_mpeg4->cae_v, syntax_mpeg4->symbol[CIV]); ptr_h++; ptr_v+=line; } ptr_h += 4; ptr_v += -(line<<4) + 1; } break; case bab_border_8x8: bitbuffer_write(&syntax_mpeg4->buffer, 2, 2); /* CR = 2 */ line = 12; ptr_h = ptr_v = bab+2*line+2; /* skip border */ for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { mpeg4_arithmetic_code(syntax_mpeg4->cae_h, syntax_mpeg4->symbol[CIH]); mpeg4_arithmetic_code(syntax_mpeg4->cae_v, syntax_mpeg4->symbol[CIV]); ptr_h++; ptr_v+=line; } ptr_h += 4; ptr_v += -(line<<3) + 1; } break; case bab_border_4x4: bitbuffer_write(&syntax_mpeg4->buffer, 3, 2); /* CR = 4 */ line = 8; ptr_h = ptr_v = bab+2*line+2; /* skip border */ for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { mpeg4_arithmetic_code(syntax_mpeg4->cae_h, syntax_mpeg4->symbol[CIH]); mpeg4_arithmetic_code(syntax_mpeg4->cae_v, syntax_mpeg4->symbol[CIV]); ptr_h++; ptr_v+=line; } ptr_h += 4; ptr_v += -(line<<2) + 1; } break; default: break; } mpeg4_arithmetic_leave(syntax_mpeg4->cae_h); mpeg4_arithmetic_leave(syntax_mpeg4->cae_v); /* keep the smallest code */ syntax_mpeg4->cae_h->sequence = syntax_mpeg4->cae_h->buffer; syntax_mpeg4->cae_v->sequence = syntax_mpeg4->cae_v->buffer; for(i = 0; syntax_mpeg4->cae_h->sequence[i] != 0xff; i++); for(j = 0; syntax_mpeg4->cae_v->sequence[j] != 0xff; j++); if(i <= j) { /* horizontal */ bitbuffer_write(&syntax_mpeg4->buffer, 1, 1); /* don't transpose */ for(j = 0; j < i; j++) { bitbuffer_write(&syntax_mpeg4->buffer, syntax_mpeg4->cae_h->sequence[j], 1); } } else { /* vertical */ bitbuffer_write(&syntax_mpeg4->buffer, 0, 1); /* transpose */ for(i = 0; i < j; i++) { bitbuffer_write(&syntax_mpeg4->buffer, syntax_mpeg4->cae_v->sequence[i], 1); } }}static void mpeg4_block_intra(fame_syntax_t *syntax, short *block, fame_vlc_t const *table, short v, unsigned char *zigzag, unsigned char coded){ fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax); short i; 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; /* encode DC coefficient */ fast_bitbuffer_write(data, shift, table[v+255].code, table[v+255].length); /* encode AC coefficients */ if(coded) { i = 1; last = 1; /* i < 64 checking not needed as all-zero block is not coded */ while((v = block[zigzag[i]]) == 0) i++; do { /* count zeroes */ vlc = syntax_mpeg4->intra_table + (mpeg4_table_clip[v] << 6) + i - last; last = ++i; while(i < 64 && (v = block[zigzag[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 int mpeg4_write_intra_mb(fame_syntax_t *syntax, int mb_x, int mb_y, short *blocks[6], unsigned char *bab, unsigned char *bab_map, fame_bab_t bab_type, int dquant, unsigned char pattern){ fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax); int coded[6]; int i, j; int cbp, bc; short *a, *b, *c; short *p[6]; short ys, cs, qs; short *d[6]; short o[6]; short ac_sad; unsigned char *zigzag[6]; int retval; p[0] = syntax_mpeg4->pred[0]; p[1] = syntax_mpeg4->pred[1]; p[2] = syntax_mpeg4->pred[2]; p[3] = syntax_mpeg4->pred[3]; p[4] = syntax_mpeg4->pred[4]; p[5] = syntax_mpeg4->pred[5]; d[0] = syntax_mpeg4->diff[0]; d[1] = syntax_mpeg4->diff[1]; d[2] = syntax_mpeg4->diff[2]; d[3] = syntax_mpeg4->diff[3]; d[4] = syntax_mpeg4->diff[4]; d[5] = syntax_mpeg4->diff[5]; o[0] = o[1] = o[3] = o[4] = o[4] = o[5] = TOP_PREDICTED; FASTCOPY16(p[0], syntax_mpeg4->pred_default); FASTCOPY16(p[2], syntax_mpeg4->pred_default); FASTCOPY16(p[1], syntax_mpeg4->pred_default); FASTCOPY16(p[3], syntax_mpeg4->pred_default); FASTCOPY16(p[4], syntax_mpeg4->pred_default); FASTCOPY16(p[5], syntax_mpeg4->pred_default); if(syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_Rectangular) mpeg4_write_intra_bab(syntax, mb_x, mb_y, bab, bab_map, bab_type); if(bab_type != bab_not_coded) { /* not transparent */ if(syntax_mpeg4->vop_coding_type != MPEG4_I_FRAME) bitbuffer_write(&syntax_mpeg4->buffer, 0, 1); syntax_mpeg4->quant_scale += dquant; qs = syntax_mpeg4->quant_scale; ys = syntax_mpeg4->y_dc_scaler[qs]; cs = syntax_mpeg4->c_dc_scaler[qs]; /* prediction */ if(!mb_x) { /* start of line, reset horizontal predictors */ FASTCOPY16(syntax_mpeg4->y_pred_h[0], syntax_mpeg4->pred_default); 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->cb_pred_h[0], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cb_pred_h[1], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cr_pred_h[0], syntax_mpeg4->pred_default); FASTCOPY16(syntax_mpeg4->cr_pred_h[1], syntax_mpeg4->pred_default); } ac_sad = 0; /* Y (0,0) block */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -