📄 h263.c
字号:
while(time_incr--) put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 0); put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */ put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, 1, 1); /* vop coded */ if ( s->pict_type == P_TYPE || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE)) { s->no_rounding ^= 1; put_bits(&s->pb, 1, s->no_rounding); /* rounding type */ } put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */ if(!s->progressive_sequence){ put_bits(&s->pb, 1, s->top_field_first); put_bits(&s->pb, 1, s->alternate_scan); } //FIXME sprite stuff put_bits(&s->pb, 5, s->qscale); if (s->pict_type != I_TYPE) put_bits(&s->pb, 3, s->f_code); /* fcode_for */ if (s->pict_type == B_TYPE) put_bits(&s->pb, 3, s->b_code); /* fcode_back */ // printf("****frame %d\n", picture_number); s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; s->h_edge_pos= s->width; s->v_edge_pos= s->height;}/** * change qscale by given dquant and update qscale dependant variables. */static void change_qscale(MpegEncContext * s, int dquant){ s->qscale += dquant; if (s->qscale < 1) s->qscale = 1; else if (s->qscale > 31) s->qscale = 31; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];}static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr){ int a, b, c, wrap, pred, scale; UINT16 *dc_val; int dummy; /* find prediction */ if (n < 4) { scale = s->y_dc_scale; } else { scale = s->c_dc_scale; } wrap= s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; /* B C * A X */ a = dc_val[ - 1]; b = dc_val[ - 1 - wrap]; c = dc_val[ - wrap]; /* outside slice handling (we cant do that by memset as we need the dc for error resilience) */ if(s->first_slice_line && n!=3){ if(n!=2) b=c= 1024; if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024; } if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){ if(n==0 || n==4 || n==5) b=1024; } if (abs(a - b) < abs(b - c)) { pred = c; *dir_ptr = 1; /* top */ } else { pred = a; *dir_ptr = 0; /* left */ } /* we assume pred is positive */#ifdef ARCH_X86 asm volatile ( "xorl %%edx, %%edx \n\t" "mul %%ecx \n\t" : "=d" (pred), "=a"(dummy) : "a" (pred + (scale >> 1)), "c" (inverse[scale]) );#else pred = (pred + (scale >> 1)) / scale;#endif /* prepare address for prediction update */ *dc_val_ptr = &dc_val[0]; return pred;}void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, int dir){ int i; INT16 *ac_val, *ac_val1; /* find prediction */ ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val1 = ac_val; if (s->ac_pred) { if (dir == 0) { const int xy= s->mb_x-1 + s->mb_y*s->mb_width; /* left prediction */ ac_val -= 16; if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ /* same qscale */ for(i=1;i<8;i++) { block[s->idct_permutation[i<<3]] += ac_val[i]; } }else{ /* different qscale, we must rescale */ for(i=1;i<8;i++) { block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale); } } } else { const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; /* top prediction */ ac_val -= 16 * s->block_wrap[n]; if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ /* same qscale */ for(i=1;i<8;i++) { block[s->idct_permutation[i]] += ac_val[i + 8]; } }else{ /* different qscale, we must rescale */ for(i=1;i<8;i++) { block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale); } } } } /* left copy */ for(i=1;i<8;i++) ac_val1[i ] = block[s->idct_permutation[i<<3]]; /* top copy */ for(i=1;i<8;i++) ac_val1[8 + i] = block[s->idct_permutation[i ]];}static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, int dir){ int i; INT16 *ac_val; /* find prediction */ ac_val = s->ac_val[0][0] + s->block_index[n] * 16; if (dir == 0) { const int xy= s->mb_x-1 + s->mb_y*s->mb_width; /* left prediction */ ac_val -= 16; if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ /* same qscale */ for(i=1;i<8;i++) { block[s->idct_permutation[i<<3]] -= ac_val[i]; } }else{ /* different qscale, we must rescale */ for(i=1;i<8;i++) { block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale); } } } else { const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; /* top prediction */ ac_val -= 16 * s->block_wrap[n]; if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ /* same qscale */ for(i=1;i<8;i++) { block[s->idct_permutation[i]] -= ac_val[i + 8]; } }else{ /* different qscale, we must rescale */ for(i=1;i<8;i++) { block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale); } } }}static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n){#if 1// if(level<-255 || level>255) printf("dc overflow\n"); level+=256; if (n < 4) { /* luminance */ put_bits(s, uni_DCtab_lum[level][1], uni_DCtab_lum[level][0]); } else { /* chrominance */ put_bits(s, uni_DCtab_chrom[level][1], uni_DCtab_chrom[level][0]); }#else int size, v; /* find number of bits */ size = 0; v = abs(level); while (v) { v >>= 1; size++; } if (n < 4) { /* luminance */ put_bits(&s->pb, DCtab_lum[size][1], DCtab_lum[size][0]); } else { /* chrominance */ put_bits(&s->pb, DCtab_chrom[size][1], DCtab_chrom[size][0]); } /* encode remaining bits */ if (size > 0) { if (level < 0) level = (-level) ^ ((1 << size) - 1); put_bits(&s->pb, size, level); if (size > 8) put_bits(&s->pb, 1, 1); }#endif}#ifdef CONFIG_ENCODERSstatic inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, UINT8 *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ int i, last_non_zero;#if 0 //variables for the outcommented version int code, sign, last;#endif const RLTable *rl; UINT32 *bits_tab; UINT8 *len_tab; const int last_index = s->block_last_index[n]; if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away /* mpeg4 based DC predictor */ mpeg4_encode_dc(dc_pb, intra_dc, n); if(last_index<1) return; i = 1; rl = &rl_intra; bits_tab= uni_mpeg4_intra_rl_bits; len_tab = uni_mpeg4_intra_rl_len; } else { if(last_index<0) return; i = 0; rl = &rl_inter; bits_tab= uni_mpeg4_inter_rl_bits; len_tab = uni_mpeg4_inter_rl_len; } /* AC coefs */ last_non_zero = i - 1;#if 1 for (; i < last_index; i++) { int level = block[ scan_table[i] ]; if (level) { int run = i - last_non_zero - 1; level+=64; if((level&(~127)) == 0){ const int index= UNI_MPEG4_ENC_INDEX(0, run, level); put_bits(ac_pb, len_tab[index], bits_tab[index]); }else{ //ESC3 put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); } last_non_zero = i; } } /*if(i<=last_index)*/{ int level = block[ scan_table[i] ]; int run = i - last_non_zero - 1; level+=64; if((level&(~127)) == 0){ const int index= UNI_MPEG4_ENC_INDEX(1, run, level); put_bits(ac_pb, len_tab[index], bits_tab[index]); }else{ //ESC3 put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); } }#else for (; i <= last_index; i++) { const int slevel = block[ scan_table[i] ]; if (slevel) { int level; int run = i - last_non_zero - 1; last = (i == last_index); sign = 0; level = slevel; if (level < 0) { sign = 1; level = -level; } code = get_rl_index(rl, last, run, level); put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); if (code == rl->n) { int level1, run1; level1 = level - rl->max_level[last][run]; if (level1 < 1) goto esc2; code = get_rl_index(rl, last, run, level1); if (code == rl->n) { esc2: put_bits(ac_pb, 1, 1); if (level > MAX_LEVEL) goto esc3; run1 = run - rl->max_run[last][level] - 1; if (run1 < 0) goto esc3; code = get_rl_index(rl, last, run1, level); if (code == rl->n) { esc3: /* third escape */ put_bits(ac_pb, 1, 1); put_bits(ac_pb, 1, last); put_bits(ac_pb, 6, run); put_bits(ac_pb, 1, 1); put_bits(ac_pb, 12, slevel & 0xfff); put_bits(ac_pb, 1, 1); } else { /* second escape */ put_bits(ac_pb, 1, 0); put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); put_bits(ac_pb, 1, sign); } } else { /* first escape */ put_bits(ac_pb, 1, 0); put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); put_bits(ac_pb, 1, sign); } } else { put_bits(ac_pb, 1, sign); } last_non_zero = i; } }#endif}#endif/***********************************************//* decoding */static VLC intra_MCBPC_vlc;static VLC inter_MCBPC_vlc;static VLC cbpy_vlc;static VLC mv_vlc;static VLC dc_lum, dc_chrom;static VLC sprite_trajectory;static VLC mb_type_b_vlc;void init_rl(RLTable *rl){ INT8 max_level[MAX_RUN+1], max_run[MAX_LEVEL+1]; UINT8 index_run[MAX_RUN+1]; int last, run, level, start, end, i; /* compute max_level[], max_run[] and index_run[] */ for(last=0;last<2;last++) { if (last == 0) { start = 0; end = rl->last; } else { start = rl->last; end = rl->n; } memset(max_level, 0, MAX_RUN + 1); memset(max_run, 0, MAX_LEVEL + 1); memset(index_run, rl->n, MAX_RUN + 1); for(i=start;i<end;i++) { run = rl->table_run[i]; level = rl->table_level[i]; if (index_run[run] == rl->n) index_run[run] = i; if (level > max_level[run]) max_level[run] = level; if (run > max_run[level])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -