📄 h263.c
字号:
int cbp = 0; for (i = 0; i < 6; i++) { if (s->block_last_index[i] >= 0) cbp |= 1 << (5 - i); } if(s->pict_type==B_TYPE){ static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ int mb_type= mb_type_table[s->mv_dir]; if(s->mb_x==0){ s->last_mv[0][0][0]= s->last_mv[0][0][1]= s->last_mv[1][0][0]= s->last_mv[1][0][1]= 0; } assert(s->dquant>=-2 && s->dquant<=2); assert((s->dquant&1)==0); assert(mb_type>=0); /* nothing to do if this MB was skiped in the next P Frame */ if(s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ... s->skip_count++; s->mv[0][0][0]= s->mv[0][0][1]= s->mv[1][0][0]= s->mv[1][0][1]= 0; s->mv_dir= MV_DIR_FORWARD; //doesnt matter s->qscale -= s->dquant; return; } if ((cbp | motion_x | motion_y | mb_type) ==0) { /* direct MB with MV={0,0} */ assert(s->dquant==0); put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */ if(interleaved_stats){ s->misc_bits++; s->last_bits++; } s->skip_count++; return; } put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we dont need it :) if(cbp) put_bits(&s->pb, 6, cbp); if(cbp && mb_type){ if(s->dquant) put_bits(&s->pb, 2, (s->dquant>>2)+3); else put_bits(&s->pb, 1, 0); }else s->qscale -= s->dquant; if(!s->progressive_sequence){ if(cbp) put_bits(&s->pb, 1, s->interlaced_dct); if(mb_type) // not diect mode put_bits(&s->pb, 1, 0); // no interlaced ME yet } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->misc_bits+= bits - s->last_bits; s->last_bits=bits; } switch(mb_type) { case 0: /* direct */ h263_encode_motion(s, motion_x, 1); h263_encode_motion(s, motion_y, 1); s->b_count++; s->f_count++; break; case 1: /* bidir */ h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); s->last_mv[0][0][0]= s->mv[0][0][0]; s->last_mv[0][0][1]= s->mv[0][0][1]; s->last_mv[1][0][0]= s->mv[1][0][0]; s->last_mv[1][0][1]= s->mv[1][0][1]; s->b_count++; s->f_count++; break; case 2: /* backward */ h263_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); h263_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); s->last_mv[1][0][0]= motion_x; s->last_mv[1][0][1]= motion_y; s->b_count++; break; case 3: /* forward */ h263_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); h263_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); s->last_mv[0][0][0]= motion_x; s->last_mv[0][0][1]= motion_y; s->f_count++; break; default: printf("unknown mb type\n"); return; } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->mv_bits+= bits - s->last_bits; s->last_bits=bits; } /* encode each block */ for (i = 0; i < 6; i++) { mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, NULL, &s->pb); } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->p_tex_bits+= bits - s->last_bits; s->last_bits=bits; } }else{ /* s->pict_type==B_TYPE */ if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { /* check if the B frames can skip it too, as we must skip it if we skip here why didnt they just compress the skip-mb bits instead of reusing them ?! */ if(s->max_b_frames>0){ int i; int x,y, offset; uint8_t *p_pic; x= s->mb_x*16; y= s->mb_y*16; if(x+16 > s->width) x= s->width-16; if(y+16 > s->height) y= s->height-16; offset= x + y*s->linesize; p_pic= s->new_picture[0] + offset; s->mb_skiped=1; for(i=0; i<s->max_b_frames; i++){ uint8_t *b_pic; int diff; if(s->coded_order[i+1].pict_type!=B_TYPE) break; b_pic= s->coded_order[i+1].picture[0] + offset; diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize); if(diff>s->qscale*70){ //FIXME check that 70 is optimal s->mb_skiped=0; break; } } }else s->mb_skiped=1; if(s->mb_skiped==1){ /* skip macroblock */ put_bits(&s->pb, 1, 1); if(interleaved_stats){ s->misc_bits++; s->last_bits++; } s->skip_count++; return; } } put_bits(&s->pb, 1, 0); /* mb coded */ if(s->mv_type==MV_TYPE_16X16){ cbpc = cbp & 3; if(s->dquant) cbpc+= 8; put_bits(&s->pb, inter_MCBPC_bits[cbpc], inter_MCBPC_code[cbpc]); cbpy = cbp >> 2; cbpy ^= 0xf; put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); if(s->dquant) put_bits(pb2, 2, dquant_code[s->dquant+2]); if(!s->progressive_sequence){ if(cbp) put_bits(pb2, 1, s->interlaced_dct); put_bits(pb2, 1, 0); // no interlaced ME yet } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->misc_bits+= bits - s->last_bits; s->last_bits=bits; } /* motion vectors: 16x16 mode */ h263_pred_motion(s, 0, &pred_x, &pred_y); h263_encode_motion(s, motion_x - pred_x, s->f_code); h263_encode_motion(s, motion_y - pred_y, s->f_code); }else{ cbpc = (cbp & 3)+16; put_bits(&s->pb, inter_MCBPC_bits[cbpc], inter_MCBPC_code[cbpc]); cbpy = cbp >> 2; cbpy ^= 0xf; put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); if(!s->progressive_sequence){ if(cbp) put_bits(pb2, 1, s->interlaced_dct); } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->misc_bits+= bits - s->last_bits; s->last_bits=bits; } for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ h263_pred_motion(s, i, &pred_x, &pred_y); h263_encode_motion(s, s->motion_val[ s->block_index[i] ][0] - pred_x, s->f_code); h263_encode_motion(s, s->motion_val[ s->block_index[i] ][1] - pred_y, s->f_code); } } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->mv_bits+= bits - s->last_bits; s->last_bits=bits; } /* encode each block */ for (i = 0; i < 6; i++) { mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, NULL, tex_pb); } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->p_tex_bits+= bits - s->last_bits; s->last_bits=bits; } s->f_count++; } } else { int cbp; int dc_diff[6]; //dc values with the dc prediction subtracted int dir[6]; //prediction direction int zigzag_last_index[6]; UINT8 *scan_table[6]; for(i=0; i<6; i++){ const int level= block[i][0]; UINT16 *dc_ptr; dc_diff[i]= level - ff_mpeg4_pred_dc(s, i, &dc_ptr, &dir[i]); if (i < 4) { *dc_ptr = level * s->y_dc_scale; } else { *dc_ptr = level * s->c_dc_scale; } } s->ac_pred= decide_ac_pred(s, block, dir); if(s->ac_pred){ for(i=0; i<6; i++){ UINT8 *st; int last_index; mpeg4_inv_pred_ac(s, block[i], i, dir[i]); if (dir[i]==0) st = s->intra_v_scantable.permutated; /* left */ else st = s->intra_h_scantable.permutated; /* top */ for(last_index=63; last_index>=0; last_index--) //FIXME optimize if(block[i][st[last_index]]) break; zigzag_last_index[i]= s->block_last_index[i]; s->block_last_index[i]= last_index; scan_table[i]= st; } }else{ for(i=0; i<6; i++) scan_table[i]= s->intra_scantable.permutated; } /* compute cbp */ cbp = 0; for (i = 0; i < 6; i++) { if (s->block_last_index[i] >= 1) 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]); } put_bits(pb2, 1, s->ac_pred); cbpy = cbp >> 2; put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); if(s->dquant) put_bits(dc_pb, 2, dquant_code[s->dquant+2]); if(!s->progressive_sequence){ put_bits(dc_pb, 1, s->interlaced_dct); } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->misc_bits+= bits - s->last_bits; s->last_bits=bits; } /* encode each block */ for (i = 0; i < 6; i++) { mpeg4_encode_block(s, block[i], i, dc_diff[i], scan_table[i], dc_pb, tex_pb); } if(interleaved_stats){ bits= get_bit_count(&s->pb); s->i_tex_bits+= bits - s->last_bits; s->last_bits=bits; } s->i_count++; /* restore ac coeffs & last_index stuff if we messed them up with the prediction */ if(s->ac_pred){ for(i=0; i<6; i++){ int j; INT16 *ac_val; ac_val = s->ac_val[0][0] + s->block_index[i] * 16; if(dir[i]){ for(j=1; j<8; j++) block[i][s->idct_permutation[j ]]= ac_val[j+8]; }else{ for(j=1; j<8; j++) block[i][s->idct_permutation[j<<3]]= ac_val[j ]; } s->block_last_index[i]= zigzag_last_index[i]; } } }}void h263_encode_mb(MpegEncContext * s, DCTELEM block[6][64], int motion_x, int motion_y){ int cbpc, cbpy, i, cbp, pred_x, pred_y; INT16 pred_dc; INT16 rec_intradc[6]; UINT16 *dc_ptr[6]; const int dquant_code[5]= {1,0,9,2,3}; //printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); if (!s->mb_intra) { /* compute cbp */ cbp = 0; for (i = 0; i < 6; i++) { if (s->block_last_index[i] >= 0) cbp |= 1 << (5 - i); } if ((cbp | motion_x | motion_y | s->dquant) == 0) { /* skip macroblock */ put_bits(&s->pb, 1, 1); return; } put_bits(&s->pb, 1, 0); /* mb coded */ cbpc = cbp & 3; if(s->dquant) cbpc+= 8; put_bits(&s->pb, inter_MCBPC_bits[cbpc], inter_MCBPC_code[cbpc]); cbpy = cbp >> 2; cbpy ^= 0xf; 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]); /* motion vectors: 16x16 mode only now */ h263_pred_motion(s, 0, &pred_x, &pred_y); if (!s->umvplus) { h263_encode_motion(s, motion_x - pred_x, s->f_code); h263_encode_motion(s, motion_y - pred_y, s->f_code); } else { h263p_encode_umotion(s, motion_x - pred_x);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -