📄 h263.c
字号:
h263p_encode_umotion(s, motion_y - pred_y); if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) /* To prevent Start Code emulation */ put_bits(&s->pb,1,1); } } else { int li = s->h263_aic ? 0 : 1; cbp = 0; for(i=0; i<6; i++) { /* Predict DC */ if (s->h263_aic && s->mb_intra) { INT16 level = block[i][0]; pred_dc = h263_pred_dc(s, i, &dc_ptr[i]); level -= pred_dc; /* Quant */ if (level < 0) level = (level + (s->qscale >> 1))/(s->y_dc_scale); else level = (level - (s->qscale >> 1))/(s->y_dc_scale); /* AIC can change CBP */ if (level == 0 && s->block_last_index[i] == 0) s->block_last_index[i] = -1; else if (level < -127) level = -127; else if (level > 127) level = 127; block[i][0] = level; /* Reconstruction */ rec_intradc[i] = (s->y_dc_scale*level) + pred_dc; /* Oddify */ rec_intradc[i] |= 1; //if ((rec_intradc[i] % 2) == 0) // rec_intradc[i]++; /* Clipping */ if (rec_intradc[i] < 0) rec_intradc[i] = 0; else if (rec_intradc[i] > 2047) rec_intradc[i] = 2047; /* Update AC/DC tables */ *dc_ptr[i] = rec_intradc[i]; } /* compute cbp */ if (s->block_last_index[i] >= li) cbp |= 1 << (5 - i); } cbpc = cbp & 3; if (s->pict_type == I_TYPE) { if(s->dquant) cbpc+=4; put_bits(&s->pb, intra_MCBPC_bits[cbpc], intra_MCBPC_code[cbpc]); } else { if(s->dquant) cbpc+=8; put_bits(&s->pb, 1, 0); /* mb coded */ put_bits(&s->pb, inter_MCBPC_bits[cbpc + 4], inter_MCBPC_code[cbpc + 4]); } if (s->h263_aic) { /* XXX: currently, we do not try to use ac prediction */ put_bits(&s->pb, 1, 0); /* no AC prediction */ } cbpy = cbp >> 2; put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); if(s->dquant) put_bits(&s->pb, 2, dquant_code[s->dquant+2]); } for(i=0; i<6; i++) { /* encode each block */ h263_encode_block(s, block[i], i); /* Update INTRADC for decoding */ if (s->h263_aic && s->mb_intra) { block[i][0] = rec_intradc[i]; } }}#endifstatic int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr){ int x, y, wrap, a, c, pred_dc, scale; INT16 *dc_val, *ac_val; /* find prediction */ if (n < 4) { x = 2 * s->mb_x + 1 + (n & 1); y = 2 * s->mb_y + 1 + ((n & 2) >> 1); wrap = s->mb_width * 2 + 2; dc_val = s->dc_val[0]; ac_val = s->ac_val[0][0]; scale = s->y_dc_scale; } else { x = s->mb_x + 1; y = s->mb_y + 1; wrap = s->mb_width + 2; dc_val = s->dc_val[n - 4 + 1]; ac_val = s->ac_val[n - 4 + 1][0]; scale = s->c_dc_scale; } /* B C * A X */ a = dc_val[(x - 1) + (y) * wrap]; c = dc_val[(x) + (y - 1) * wrap]; /* No prediction outside GOB boundary */ if (s->first_slice_line && ((n < 2) || (n > 3))) c = 1024; pred_dc = 1024; /* just DC prediction */ if (a != 1024 && c != 1024) pred_dc = (a + c) >> 1; else if (a != 1024) pred_dc = a; else pred_dc = c; /* we assume pred is positive */ //pred_dc = (pred_dc + (scale >> 1)) / scale; *dc_val_ptr = &dc_val[x + y * wrap]; return pred_dc;}void h263_pred_acdc(MpegEncContext * s, INT16 *block, int n){ int x, y, wrap, a, c, pred_dc, scale, i; INT16 *dc_val, *ac_val, *ac_val1; /* find prediction */ if (n < 4) { x = 2 * s->mb_x + 1 + (n & 1); y = 2 * s->mb_y + 1 + ((n & 2) >> 1); wrap = s->mb_width * 2 + 2; dc_val = s->dc_val[0]; ac_val = s->ac_val[0][0]; scale = s->y_dc_scale; } else { x = s->mb_x + 1; y = s->mb_y + 1; wrap = s->mb_width + 2; dc_val = s->dc_val[n - 4 + 1]; ac_val = s->ac_val[n - 4 + 1][0]; scale = s->c_dc_scale; } ac_val += ((y) * wrap + (x)) * 16; ac_val1 = ac_val; /* B C * A X */ a = dc_val[(x - 1) + (y) * wrap]; c = dc_val[(x) + (y - 1) * wrap]; /* No prediction outside GOB boundary */ if (s->first_slice_line && ((n < 2) || (n > 3))) c = 1024; pred_dc = 1024; if (s->ac_pred) { if (s->h263_aic_dir) { /* left prediction */ if (a != 1024) { ac_val -= 16; for(i=1;i<8;i++) { block[s->idct_permutation[i<<3]] += ac_val[i]; } pred_dc = a; } } else { /* top prediction */ if (c != 1024) { ac_val -= 16 * wrap; for(i=1;i<8;i++) { block[s->idct_permutation[i ]] += ac_val[i + 8]; } pred_dc = c; } } } else { /* just DC prediction */ if (a != 1024 && c != 1024) pred_dc = (a + c) >> 1; else if (a != 1024) pred_dc = a; else pred_dc = c; } /* we assume pred is positive */ block[0]=block[0]*scale + pred_dc; if (block[0] < 0) block[0] = 0; else if (!(block[0] & 1)) block[0]++; /* Update AC/DC tables */ dc_val[(x) + (y) * wrap] = block[0]; /* 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 ]];}INT16 *h263_pred_motion(MpegEncContext * s, int block, int *px, int *py){ int xy, wrap; INT16 *A, *B, *C, *mot_val; static const int off[4]= {2, 1, 1, -1}; wrap = s->block_wrap[0]; xy = s->block_index[block]; mot_val = s->motion_val[xy]; A = s->motion_val[xy - 1]; /* special case for first (slice) line */ if (s->first_slice_line && block<3) { // we cant just change some MVs to simulate that as we need them for the B frames (and ME) // and if we ever support non rectangular objects than we need to do a few ifs here anyway :( if(block==0){ //most common case if(s->mb_x == s->resync_mb_x){ //rare *px= *py = 0; }else if(s->mb_x + 1 == s->resync_mb_x){ //rare C = s->motion_val[xy + off[block] - wrap]; if(s->mb_x==0){ *px = C[0]; *py = C[1]; }else{ *px = mid_pred(A[0], 0, C[0]); *py = mid_pred(A[1], 0, C[1]); } }else{ *px = A[0]; *py = A[1]; } }else if(block==1){ if(s->mb_x + 1 == s->resync_mb_x){ //rare C = s->motion_val[xy + off[block] - wrap]; *px = mid_pred(A[0], 0, C[0]); *py = mid_pred(A[1], 0, C[1]); }else{ *px = A[0]; *py = A[1]; } }else{ /* block==2*/ B = s->motion_val[xy - wrap]; C = s->motion_val[xy + off[block] - wrap]; if(s->mb_x == s->resync_mb_x) //rare A[0]=A[1]=0; *px = mid_pred(A[0], B[0], C[0]); *py = mid_pred(A[1], B[1], C[1]); } } else { B = s->motion_val[xy - wrap]; C = s->motion_val[xy + off[block] - wrap]; *px = mid_pred(A[0], B[0], C[0]); *py = mid_pred(A[1], B[1], C[1]); } return mot_val;}#ifdef CONFIG_ENCODERSstatic void h263_encode_motion(MpegEncContext * s, int val, int f_code){ int range, l, bit_size, sign, code, bits; if (val == 0) { /* zero vector */ code = 0; put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); } else { bit_size = f_code - 1; range = 1 << bit_size; /* modulo encoding */ l = range * 32;#if 1 val+= l; val&= 2*l-1; val-= l; sign = val>>31; val= (val^sign)-sign; sign&=1;#else if (val < -l) { val += 2*l; } else if (val >= l) { val -= 2*l; } assert(val>=-l && val<l); if (val >= 0) { sign = 0; } else { val = -val; sign = 1; }#endif val--; code = (val >> bit_size) + 1; bits = val & (range - 1); put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); } }}/* Encode MV differences on H.263+ with Unrestricted MV mode */static void h263p_encode_umotion(MpegEncContext * s, int val){ short sval = 0; short i = 0; short n_bits = 0; short temp_val; int code = 0; int tcode; if ( val == 0) put_bits(&s->pb, 1, 1); else if (val == 1) put_bits(&s->pb, 3, 0); else if (val == -1) put_bits(&s->pb, 3, 2); else { sval = ((val < 0) ? (short)(-val):(short)val); temp_val = sval; while (temp_val != 0) { temp_val = temp_val >> 1; n_bits++; } i = n_bits - 1; while (i > 0) { tcode = (sval & (1 << (i-1))) >> (i-1); tcode = (tcode << 1) | 1; code = (code << 2) | tcode; i--; } code = ((code << 1) | (val < 0)) << 1; put_bits(&s->pb, (2*n_bits)+1, code); //printf("\nVal = %d\tCode = %d", sval, code); }}static void init_mv_penalty_and_fcode(MpegEncContext *s){ int f_code; int mv; if(mv_penalty==NULL) mv_penalty= av_mallocz( sizeof(UINT16)*(MAX_FCODE+1)*(2*MAX_MV+1) ); for(f_code=1; f_code<=MAX_FCODE; f_code++){ for(mv=-MAX_MV; mv<=MAX_MV; mv++){ int len; if(mv==0) len= mvtab[0][1]; else{ int val, bit_size, range, code; bit_size = s->f_code - 1; range = 1 << bit_size; val=mv; if (val < 0) val = -val; val--; code = (val >> bit_size) + 1; if(code<33){ len= mvtab[code][1] + 1 + bit_size; }else{ len= mvtab[32][1] + 2 + bit_size; } } mv_penalty[f_code][mv+MAX_MV]= len; } } for(f_code=MAX_FCODE; f_code>0; f_code--){ for(mv=-(16<<f_code); mv<(16<<f_code); mv++){ fcode_tab[mv+MAX_MV]= f_code; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -