From 96815ce9e206279612628ce91bdc21734930fd12 Mon Sep 17 00:00:00 2001 From: Juanjo Date: Sat, 17 Nov 2001 21:14:54 +0000 Subject: [PATCH] - Added support to Inter4V+Q MBs to H.263 decoder. - Advanced Prediction Mode activated for H.263 decoder. - Bug fixed on H.263+ header parsing for UFEP. - Now we can decode VIVO v1 streams :) Originally committed as revision 221 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/h263.c | 90 +++++++++++++++++++++++++------------------ libavcodec/h263data.h | 10 +++-- libavcodec/h263dec.c | 4 +- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/libavcodec/h263.c b/libavcodec/h263.c index b22f4ab560..4aaf5d6ad4 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -750,7 +750,7 @@ void h263_decode_init_vlc(MpegEncContext *s) init_vlc(&intra_MCBPC_vlc, 6, 8, intra_MCBPC_bits, 1, 1, intra_MCBPC_code, 1, 1); - init_vlc(&inter_MCBPC_vlc, 9, 20, + init_vlc(&inter_MCBPC_vlc, 9, 25, inter_MCBPC_bits, 1, 1, inter_MCBPC_code, 1, 1); init_vlc(&cbpy_vlc, 6, 16, @@ -825,6 +825,10 @@ int h263_decode_mb(MpegEncContext *s, //fprintf(stderr, "\tCBPC: %d", cbpc); if (cbpc < 0) return -1; + if (cbpc > 20) + cbpc+=3; + else if (cbpc == 20) + fprintf(stderr, "Stuffing !"); dquant = cbpc & 8; s->mb_intra = ((cbpc & 4) != 0); @@ -1223,14 +1227,16 @@ int h263_decode_picture_header(MpegEncContext *s) format = get_bits(&s->gb, 3); - if (format != 7) { + if (format != 7 && format != 6) { s->h263_plus = 0; /* H.263v1 */ width = h263_format[format][0]; height = h263_format[format][1]; if (!width) return -1; - + + s->width = width; + s->height = height; s->pict_type = I_TYPE + get_bits1(&s->gb); s->unrestricted_mv = get_bits1(&s->gb); @@ -1238,27 +1244,36 @@ int h263_decode_picture_header(MpegEncContext *s) if (get_bits1(&s->gb) != 0) return -1; /* SAC: off */ - if (get_bits1(&s->gb) != 0) - return -1; /* advanced prediction mode: off */ + if (get_bits1(&s->gb) != 0) { + s->mv_type = MV_TYPE_8X8; /* Advanced prediction mode */ + } + if (get_bits1(&s->gb) != 0) return -1; /* not PB frame */ s->qscale = get_bits(&s->gb, 5); skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ } else { - s->h263_plus = 1; - /* H.263v2 */ - /* OPPTYPE */ - - if (get_bits(&s->gb, 3) != 1) /* Update Full Extended PTYPE */ - return -1; - format = get_bits(&s->gb, 3); - - skip_bits(&s->gb,1); /* Custom PCF */ - s->umvplus_dec = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ - skip_bits(&s->gb, 10); - skip_bits(&s->gb, 3); /* Reserved */ + int ufep; + /* H.263v2 */ + s->h263_plus = 1; + ufep = get_bits(&s->gb, 3); /* Update Full Extended PTYPE */ + + if (ufep == 1) { + /* OPPTYPE */ + format = get_bits(&s->gb, 3); + skip_bits(&s->gb,1); /* Custom PCF */ + s->umvplus_dec = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ + skip_bits1(&s->gb); /* Syntax-based Arithmetic Coding (SAC) */ + if (get_bits1(&s->gb) != 0) { + s->mv_type = MV_TYPE_8X8; /* Advanced prediction mode */ + } + skip_bits(&s->gb, 8); + skip_bits(&s->gb, 3); /* Reserved */ + } else if (ufep != 0) + return -1; + /* MPPTYPE */ s->pict_type = get_bits(&s->gb, 3) + 1; if (s->pict_type != I_TYPE && @@ -1267,26 +1282,28 @@ int h263_decode_picture_header(MpegEncContext *s) skip_bits(&s->gb, 7); /* Get the picture dimensions */ - if (format == 6) { - /* Custom Picture Format (CPFMT) */ - skip_bits(&s->gb, 4); /* aspect ratio */ - width = (get_bits(&s->gb, 9) + 1) * 4; - skip_bits1(&s->gb); - height = get_bits(&s->gb, 9) * 4; + if (ufep) { + if (format == 6) { + /* Custom Picture Format (CPFMT) */ + skip_bits(&s->gb, 4); /* aspect ratio */ + width = (get_bits(&s->gb, 9) + 1) * 4; + skip_bits1(&s->gb); + height = get_bits(&s->gb, 9) * 4; #ifdef DEBUG - fprintf(stderr,"\nH.263+ Custom picture: %dx%d\n",width,height); + fprintf(stderr,"\nH.263+ Custom picture: %dx%d\n",width,height); #endif - } - else { - width = h263_format[format][0]; - height = h263_format[format][1]; - } - - if ((width == 0) || (height == 0)) - return -1; - - if (s->umvplus_dec) { - skip_bits1(&s->gb); /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ + } + else { + width = h263_format[format][0]; + height = h263_format[format][1]; + } + if ((width == 0) || (height == 0)) + return -1; + s->width = width; + s->height = height; + if (s->umvplus_dec) { + skip_bits1(&s->gb); /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ + } } s->qscale = get_bits(&s->gb, 5); @@ -1296,9 +1313,6 @@ int h263_decode_picture_header(MpegEncContext *s) skip_bits(&s->gb, 8); } s->f_code = 1; - s->width = width; - s->height = height; - return 0; } diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h index 696552522d..d41996a3bc 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -4,20 +4,24 @@ static const UINT8 intra_MCBPC_code[8] = { 1, 1, 2, 3, 1, 1, 2, 3 }; static const UINT8 intra_MCBPC_bits[8] = { 1, 3, 3, 3, 4, 6, 6, 6 }; /* inter MCBPC, mb_type = (inter), (intra), (interq), (intraq), (inter4v) */ -/* Changed the tables for interq, following the standard ** Juanjo ** */ -static const UINT8 inter_MCBPC_code[20] = { +/* Changed the tables for interq and inter4v+q, following the standard ** Juanjo ** */ +static const UINT8 inter_MCBPC_code[25] = { 1, 3, 2, 5, 3, 4, 3, 3, 3, 7, 6, 5, 4, 4, 3, 2, 2, 5, 4, 5, + 1, /* Stuffing */ + 2, 12, 14, 15, }; -static const UINT8 inter_MCBPC_bits[20] = { +static const UINT8 inter_MCBPC_bits[25] = { 1, 4, 4, 6, 5, 8, 8, 7, 3, 7, 7, 9, 6, 9, 9, 9, 3, 7, 7, 8, + 9, /* Stuffing */ + 11, 13, 13, 13, }; /* This is the old table diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 5db4bc6b40..d56bc8252b 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -163,8 +163,10 @@ static int h263_decode_frame(AVCodecContext *avctx, if (msmpeg4_decode_mb(s, s->block) < 0) return -1; } else { - if (h263_decode_mb(s, s->block) < 0) + if (h263_decode_mb(s, s->block) < 0) { + fprintf(stderr,"\nError at MB: %d\n", (s->mb_y * s->mb_width) + s->mb_x); return -1; + } } MPV_decode_mb(s, s->block); }