/* Nearly identical to wmv1 but that is just because we do not use the * useless M$ crap features. It is duplicated here in case someone wants * to add support for these crap features. */ void ff_wmv2_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y) { Wmv2Context *const w = (Wmv2Context *) s; int cbp, coded_cbp, i; int pred_x, pred_y; uint8_t *coded_block; ff_msmpeg4_handle_slices(s); 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); put_bits(&s->pb, ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][1], ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); s->misc_bits += get_bits_diff(s); /* motion vector */ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); s->mv_bits += get_bits_diff(s); } else { /* compute cbp */ cbp = 0; coded_cbp = 0; for (i = 0; i < 6; i++) { int val, pred; val = (s->block_last_index[i] >= 1); cbp |= val << (5 - i); if (i < 4) { /* predict value for close blocks only for luma */ pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); *coded_block = val; val = val ^ pred; } coded_cbp |= val << (5 - i); } if (s->pict_type == AV_PICTURE_TYPE_I) put_bits(&s->pb, ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); else put_bits(&s->pb, ff_wmv2_inter_table[w->cbp_table_index][cbp][1], ff_wmv2_inter_table[w->cbp_table_index][cbp][0]); put_bits(&s->pb, 1, 0); /* no AC prediction yet */ if (s->inter_intra_pred) { s->h263_aic_dir = 0; put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]); } s->misc_bits += get_bits_diff(s); } for (i = 0; i < 6; i++) ff_msmpeg4_encode_block(s, block[i], i); if (s->mb_intra) s->i_tex_bits += get_bits_diff(s); else s->p_tex_bits += get_bits_diff(s); }
/** * read the next MVs for OBMC. yes this is a ugly hack, feel free to send a patch :) */ static void preview_obmc(MpegEncContext *s){ GetBitContext gb= s->gb; int cbpc, i, pred_x, pred_y, mx, my; int16_t *mot_val; const int xy= s->mb_x + 1 + s->mb_y * s->mb_stride; const int stride= s->b8_stride*2; for(i=0; i<4; i++) s->block_index[i]+= 2; for(i=4; i<6; i++) s->block_index[i]+= 1; s->mb_x++; av_assert2(s->pict_type == AV_PICTURE_TYPE_P); do{ if (get_bits1(&s->gb)) { /* skip mb */ mot_val = s->current_picture.motion_val[0][s->block_index[0]]; mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= 0; mot_val[1 ]= mot_val[3 ]= mot_val[1+stride]= mot_val[3+stride]= 0; s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; goto end; } cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); }while(cbpc == 20); if(cbpc & 4){ s->current_picture.mb_type[xy] = MB_TYPE_INTRA; }else{ get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); if (cbpc & 8) { if(s->modified_quant){ if(get_bits1(&s->gb)) skip_bits(&s->gb, 1); else skip_bits(&s->gb, 5); }else skip_bits(&s->gb, 2); } if ((cbpc & 16) == 0) { s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else mx = ff_h263_decode_motion(s, pred_x, 1); if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else my = ff_h263_decode_motion(s, pred_y, 1); mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= mx; mot_val[1 ]= mot_val[3 ]= mot_val[1+stride]= mot_val[3+stride]= my; } else { s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else mx = ff_h263_decode_motion(s, pred_x, 1); if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else my = ff_h263_decode_motion(s, pred_y, 1); if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ mot_val[0] = mx; mot_val[1] = my; } } } end: for(i=0; i<4; i++) s->block_index[i]-= 2; for(i=4; i<6; i++) s->block_index[i]-= 1; s->mb_x--; s->gb= gb; }