Commit fcfee63b authored by Michael Niedermayer's avatar Michael Niedermayer

split ff_h263_decode_mb() into h263 and mpeg4 versions

Originally committed as revision 2554 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 3615e2be
...@@ -3565,46 +3565,35 @@ int ff_h263_decode_mb(MpegEncContext *s, ...@@ -3565,46 +3565,35 @@ int ff_h263_decode_mb(MpegEncContext *s,
static int8_t quant_tab[4] = { -1, -2, 1, 2 }; static int8_t quant_tab[4] = { -1, -2, 1, 2 };
const int xy= s->mb_x + s->mb_y * s->mb_stride; const int xy= s->mb_x + s->mb_y * s->mb_stride;
if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) { assert(!s->h263_pred);
do{
if (get_bits1(&s->gb)) { if (s->pict_type == P_TYPE) {
/* skip mb */ do{
s->mb_intra = 0; if (get_bits1(&s->gb)) {
for(i=0;i<6;i++) /* skip mb */
s->block_last_index[i] = -1; s->mb_intra = 0;
s->mv_dir = MV_DIR_FORWARD; for(i=0;i<6;i++)
s->mv_type = MV_TYPE_16X16; s->block_last_index[i] = -1;
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ s->mv_dir = MV_DIR_FORWARD;
s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; s->mv_type = MV_TYPE_16X16;
s->mcsel=1;
s->mv[0][0][0]= get_amv(s, 0);
s->mv[0][0][1]= get_amv(s, 1);
s->mb_skiped = 0;
}else{
s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
s->mcsel=0;
s->mv[0][0][0] = 0; s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0; s->mv[0][0][1] = 0;
s->mb_skiped = !(s->obmc | s->loop_filter); s->mb_skiped = !(s->obmc | s->loop_filter);
goto end;
} }
goto end; cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
} //fprintf(stderr, "\tCBPC: %d", cbpc);
cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); if (cbpc < 0){
//fprintf(stderr, "\tCBPC: %d", cbpc); av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
if (cbpc < 0){ return -1;
av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); }
return -1; }while(cbpc == 20);
}
}while(cbpc == 20);
dquant = cbpc & 8; dquant = cbpc & 8;
s->mb_intra = ((cbpc & 4) != 0); s->mb_intra = ((cbpc & 4) != 0);
if (s->mb_intra) goto intra; if (s->mb_intra) goto intra;
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
s->mcsel= get_bits1(&s->gb);
else s->mcsel= 0;
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(s->alt_inter_vlc==0 || (cbpc & 3)!=3) if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
...@@ -3621,6 +3610,192 @@ int ff_h263_decode_mb(MpegEncContext *s, ...@@ -3621,6 +3610,192 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->qscale += quant_tab[get_bits(&s->gb, 2)]; s->qscale += quant_tab[get_bits(&s->gb, 2)];
change_qscale(s, 0); change_qscale(s, 0);
} }
s->mv_dir = MV_DIR_FORWARD;
if ((cbpc & 16) == 0) {
s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
/* 16x16 motion prediction */
s->mv_type = MV_TYPE_16X16;
h263_pred_motion(s, 0, &pred_x, &pred_y);
if (s->umvplus)
mx = h263p_decode_umotion(s, pred_x);
else
mx = h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff)
return -1;
if (s->umvplus)
my = h263p_decode_umotion(s, pred_y);
else
my = h263_decode_motion(s, pred_y, s->f_code);
if (my >= 0xffff)
return -1;
s->mv[0][0][0] = mx;
s->mv[0][0][1] = my;
if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
} else {
s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
s->mv_type = MV_TYPE_8X8;
for(i=0;i<4;i++) {
mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);
if (s->umvplus)
mx = h263p_decode_umotion(s, pred_x);
else
mx = h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff)
return -1;
if (s->umvplus)
my = h263p_decode_umotion(s, pred_y);
else
my = h263_decode_motion(s, pred_y, s->f_code);
if (my >= 0xffff)
return -1;
s->mv[0][i][0] = mx;
s->mv[0][i][1] = my;
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;
}
}
} else { /* I-Frame */
do{
cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
if (cbpc < 0){
av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
}while(cbpc == 8);
dquant = cbpc & 4;
s->mb_intra = 1;
intra:
s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
if (s->h263_aic) {
s->ac_pred = get_bits1(&s->gb);
if(s->ac_pred){
s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED;
s->h263_aic_dir = get_bits1(&s->gb);
}
}else
s->ac_pred = 0;
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(cbpy<0){
av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
cbp = (cbpc & 3) | (cbpy << 2);
if (dquant) {
if(s->modified_quant){
if(get_bits1(&s->gb))
s->qscale= modified_quant_tab[get_bits1(&s->gb)][ s->qscale ];
else
s->qscale= get_bits(&s->gb, 5);
}else
s->qscale += quant_tab[get_bits(&s->gb, 2)];
change_qscale(s, 0);
}
/* decode each block */
for (i = 0; i < 6; i++) {
if (h263_decode_block(s, block[i], i, cbp&32) < 0)
return -1;
cbp+=cbp;
}
goto end;
}
/* decode each block */
for (i = 0; i < 6; i++) {
if (h263_decode_block(s, block[i], i, cbp&32) < 0)
return -1;
cbp+=cbp;
}
end:
if(s->obmc){
if(s->pict_type == P_TYPE && s->mb_x+1<s->mb_width)
preview_obmc(s);
}
/* per-MB end of slice check */
{
int v= show_bits(&s->gb, 16);
if(get_bits_count(&s->gb) + 16 > s->gb.size_in_bits){
v>>= get_bits_count(&s->gb) + 16 - s->gb.size_in_bits;
}
if(v==0)
return SLICE_END;
}
return SLICE_OK;
}
int ff_mpeg4_decode_mb(MpegEncContext *s,
DCTELEM block[6][64])
{
int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
int16_t *mot_val;
static int8_t quant_tab[4] = { -1, -2, 1, 2 };
const int xy= s->mb_x + s->mb_y * s->mb_stride;
assert(s->h263_pred);
if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) {
do{
if (get_bits1(&s->gb)) {
/* skip mb */
s->mb_intra = 0;
for(i=0;i<6;i++)
s->block_last_index[i] = -1;
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){
s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
s->mcsel=1;
s->mv[0][0][0]= get_amv(s, 0);
s->mv[0][0][1]= get_amv(s, 1);
s->mb_skiped = 0;
}else{
s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
s->mcsel=0;
s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0;
s->mb_skiped = 1;
}
goto end;
}
cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
//fprintf(stderr, "\tCBPC: %d", cbpc);
if (cbpc < 0){
av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
}while(cbpc == 20);
dquant = cbpc & 8;
s->mb_intra = ((cbpc & 4) != 0);
if (s->mb_intra) goto intra;
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
s->mcsel= get_bits1(&s->gb);
else s->mcsel= 0;
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F;
cbp = (cbpc & 3) | (cbpy << 2);
if (dquant) {
s->qscale += quant_tab[get_bits(&s->gb, 2)];
change_qscale(s, 0);
}
if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE))) if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE)))
s->interlaced_dct= get_bits1(&s->gb); s->interlaced_dct= get_bits1(&s->gb);
...@@ -3661,49 +3836,32 @@ int ff_h263_decode_mb(MpegEncContext *s, ...@@ -3661,49 +3836,32 @@ int ff_h263_decode_mb(MpegEncContext *s,
/* 16x16 motion prediction */ /* 16x16 motion prediction */
s->mv_type = MV_TYPE_16X16; s->mv_type = MV_TYPE_16X16;
h263_pred_motion(s, 0, &pred_x, &pred_y); h263_pred_motion(s, 0, &pred_x, &pred_y);
if (s->umvplus) mx = h263_decode_motion(s, pred_x, s->f_code);
mx = h263p_decode_umotion(s, pred_x);
else
mx = h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff) if (mx >= 0xffff)
return -1; return -1;
if (s->umvplus) my = h263_decode_motion(s, pred_y, s->f_code);
my = h263p_decode_umotion(s, pred_y);
else
my = h263_decode_motion(s, pred_y, s->f_code);
if (my >= 0xffff) if (my >= 0xffff)
return -1; return -1;
s->mv[0][0][0] = mx; s->mv[0][0][0] = mx;
s->mv[0][0][1] = my; s->mv[0][0][1] = my;
if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
} }
} else { } else {
s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
s->mv_type = MV_TYPE_8X8; s->mv_type = MV_TYPE_8X8;
for(i=0;i<4;i++) { for(i=0;i<4;i++) {
mot_val = h263_pred_motion(s, i, &pred_x, &pred_y); mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);
if (s->umvplus) mx = h263_decode_motion(s, pred_x, s->f_code);
mx = h263p_decode_umotion(s, pred_x);
else
mx = h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff) if (mx >= 0xffff)
return -1; return -1;
if (s->umvplus) my = h263_decode_motion(s, pred_y, s->f_code);
my = h263p_decode_umotion(s, pred_y);
else
my = h263_decode_motion(s, pred_y, s->f_code);
if (my >= 0xffff) if (my >= 0xffff)
return -1; return -1;
s->mv[0][i][0] = mx; s->mv[0][i][0] = mx;
s->mv[0][i][1] = my; s->mv[0][i][1] = my;
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[0] = mx;
mot_val[1] = my; mot_val[1] = my;
} }
...@@ -3855,17 +4013,11 @@ int ff_h263_decode_mb(MpegEncContext *s, ...@@ -3855,17 +4013,11 @@ int ff_h263_decode_mb(MpegEncContext *s,
dquant = cbpc & 4; dquant = cbpc & 4;
s->mb_intra = 1; s->mb_intra = 1;
intra: intra:
s->current_picture.mb_type[xy]= MB_TYPE_INTRA; s->ac_pred = get_bits1(&s->gb);
if (s->h263_pred || s->h263_aic) { if(s->ac_pred)
s->ac_pred = get_bits1(&s->gb); s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED;
if(s->ac_pred){ else
s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED; s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
if (s->h263_aic)
s->h263_aic_dir = get_bits1(&s->gb);
}
}else
s->ac_pred = 0;
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(cbpy<0){ if(cbpy<0){
...@@ -3874,13 +4026,7 @@ intra: ...@@ -3874,13 +4026,7 @@ intra:
} }
cbp = (cbpc & 3) | (cbpy << 2); cbp = (cbpc & 3) | (cbpy << 2);
if (dquant) { if (dquant) {
if(s->modified_quant){ s->qscale += quant_tab[get_bits(&s->gb, 2)];
if(get_bits1(&s->gb))
s->qscale= modified_quant_tab[get_bits1(&s->gb)][ s->qscale ];
else
s->qscale= get_bits(&s->gb, 5);
}else
s->qscale += quant_tab[get_bits(&s->gb, 2)];
change_qscale(s, 0); change_qscale(s, 0);
} }
...@@ -3888,41 +4034,21 @@ intra: ...@@ -3888,41 +4034,21 @@ intra:
s->interlaced_dct= get_bits1(&s->gb); s->interlaced_dct= get_bits1(&s->gb);
/* decode each block */ /* decode each block */
if (s->h263_pred) { for (i = 0; i < 6; i++) {
for (i = 0; i < 6; i++) { if (mpeg4_decode_block(s, block[i], i, cbp&32, 1, 0) < 0)
if (mpeg4_decode_block(s, block[i], i, cbp&32, 1, 0) < 0) return -1;
return -1; cbp+=cbp;
cbp+=cbp;
}
} else {
for (i = 0; i < 6; i++) {
if (h263_decode_block(s, block[i], i, cbp&32) < 0)
return -1;
cbp+=cbp;
}
} }
goto end; goto end;
} }
/* decode each block */ /* decode each block */
if (s->h263_pred) { for (i = 0; i < 6; i++) {
for (i = 0; i < 6; i++) { if (mpeg4_decode_block(s, block[i], i, cbp&32, 0, 0) < 0)
if (mpeg4_decode_block(s, block[i], i, cbp&32, 0, 0) < 0) return -1;
return -1; cbp+=cbp;
cbp+=cbp;
}
} else {
for (i = 0; i < 6; i++) {
if (h263_decode_block(s, block[i], i, cbp&32) < 0)
return -1;
cbp+=cbp;
}
} }
end: end:
if(s->obmc){
if(s->pict_type == P_TYPE && s->mb_x+1<s->mb_width)
preview_obmc(s);
}
/* per-MB end of slice check */ /* per-MB end of slice check */
if(s->codec_id==CODEC_ID_MPEG4){ if(s->codec_id==CODEC_ID_MPEG4){
...@@ -3932,15 +4058,6 @@ end: ...@@ -3932,15 +4058,6 @@ end:
return SLICE_OK; return SLICE_OK;
return SLICE_END; return SLICE_END;
} }
}else{
int v= show_bits(&s->gb, 16);
if(get_bits_count(&s->gb) + 16 > s->gb.size_in_bits){
v>>= get_bits_count(&s->gb) + 16 - s->gb.size_in_bits;
}
if(v==0)
return SLICE_END;
} }
return SLICE_OK; return SLICE_OK;
...@@ -5219,7 +5336,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ ...@@ -5219,7 +5336,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
if(s->partitioned_frame) if(s->partitioned_frame)
s->decode_mb= mpeg4_decode_partitioned_mb; s->decode_mb= mpeg4_decode_partitioned_mb;
else else
s->decode_mb= ff_h263_decode_mb; s->decode_mb= ff_mpeg4_decode_mb;
if(s->time_increment_resolution==0){ if(s->time_increment_resolution==0){
s->time_increment_resolution=1; s->time_increment_resolution=1;
......
...@@ -55,6 +55,7 @@ int ff_h263_decode_init(AVCodecContext *avctx) ...@@ -55,6 +55,7 @@ int ff_h263_decode_init(AVCodecContext *avctx)
s->unrestricted_mv= 0; s->unrestricted_mv= 0;
break; break;
case CODEC_ID_MPEG4: case CODEC_ID_MPEG4:
s->decode_mb= ff_mpeg4_decode_mb;
s->time_increment_bits = 4; /* default value for broken headers */ s->time_increment_bits = 4; /* default value for broken headers */
s->h263_pred = 1; s->h263_pred = 1;
s->low_delay = 0; //default, might be overriden in the vol header during header parsing s->low_delay = 0; //default, might be overriden in the vol header during header parsing
...@@ -160,7 +161,7 @@ static int decode_slice(MpegEncContext *s){ ...@@ -160,7 +161,7 @@ static int decode_slice(MpegEncContext *s){
s->first_slice_line=1; s->first_slice_line=1;
s->mb_x= s->resync_mb_x; s->mb_x= s->resync_mb_x;
s->mb_y= s->resync_mb_y; s->mb_y= s->resync_mb_y;
s->qscale= qscale; s->chroma_qscale= s->qscale= qscale;
s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ];
s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];
} }
......
...@@ -858,6 +858,8 @@ int intel_h263_decode_picture_header(MpegEncContext *s); ...@@ -858,6 +858,8 @@ int intel_h263_decode_picture_header(MpegEncContext *s);
int flv_h263_decode_picture_header(MpegEncContext *s); int flv_h263_decode_picture_header(MpegEncContext *s);
int ff_h263_decode_mb(MpegEncContext *s, int ff_h263_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]); DCTELEM block[6][64]);
int ff_mpeg4_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]);
int h263_get_picture_format(int width, int height); int h263_get_picture_format(int width, int height);
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s); void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
void ff_mpeg4_clean_buffers(MpegEncContext *s); void ff_mpeg4_clean_buffers(MpegEncContext *s);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment