better vol header parsing for mpeg4

Originally committed as revision 83 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Fabrice Bellard 24 years ago
parent 3d03c0a24e
commit d95ecd058e
  1. 85
      libavcodec/h263.c

@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "common.h" #include "common.h"
#include "dsputil.h" #include "dsputil.h"
#include "avcodec.h" #include "avcodec.h"
@ -28,9 +25,6 @@
#include "h263data.h" #include "h263data.h"
#include "mpeg4data.h" #include "mpeg4data.h"
#define NDEBUG
#include <assert.h>
static void h263_encode_block(MpegEncContext * s, DCTELEM * block, static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
int n); int n);
static void h263_encode_motion(MpegEncContext * s, int val); static void h263_encode_motion(MpegEncContext * s, int val);
@ -1166,43 +1160,66 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
if (startcode == 0x120) { if (startcode == 0x120) {
int time_increment_resolution, width, height; int time_increment_resolution, width, height, vo_ver_id;
/* vol header */ /* vol header */
skip_bits(&s->gb, 1); /* random access */ skip_bits(&s->gb, 1); /* random access */
skip_bits(&s->gb, 8); /* vo_type */ skip_bits(&s->gb, 8); /* vo_type */
skip_bits(&s->gb, 1); /* is_ol_id */ if (get_bits1(&s->gb) != 0) { /* is_ol_id */
skip_bits(&s->gb, 4); /* vo_ver_id */ vo_ver_id = get_bits(&s->gb, 4); /* vo_ver_id */
skip_bits(&s->gb, 3); /* vo_priority */ skip_bits(&s->gb, 3); /* vo_priority */
} else {
vo_ver_id = 1;
}
skip_bits(&s->gb, 4); /* aspect_ratio_info */ skip_bits(&s->gb, 4); /* aspect_ratio_info */
skip_bits(&s->gb, 1); /* vol control parameter */ skip_bits1(&s->gb); /* vol control parameter */
skip_bits(&s->gb, 2); /* vol shape */ s->shape = get_bits(&s->gb, 2); /* vol shape */
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
time_increment_resolution = get_bits(&s->gb, 16); time_increment_resolution = get_bits(&s->gb, 16);
s->time_increment_bits = log2(time_increment_resolution - 1) + 1; s->time_increment_bits = log2(time_increment_resolution - 1) + 1;
if (s->time_increment_bits < 1)
s->time_increment_bits = 1;
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
skip_bits1(&s->gb); /* vop rate */ if (get_bits1(&s->gb) != 0) { /* fixed_vop_rate */
skip_bits(&s->gb, s->time_increment_bits); skip_bits(&s->gb, s->time_increment_bits);
skip_bits1(&s->gb); /* marker */ }
if (s->shape != 2) {
if (s->shape == 0) {
skip_bits1(&s->gb); /* marker */
width = get_bits(&s->gb, 13); width = get_bits(&s->gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
height = get_bits(&s->gb, 13); height = get_bits(&s->gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
}
skip_bits1(&s->gb); /* interfaced */ skip_bits1(&s->gb); /* interlaced */
skip_bits1(&s->gb); /* OBMC */ skip_bits1(&s->gb); /* OBMC */
skip_bits(&s->gb, 2); /* vol_sprite_usage */ if (vo_ver_id == 1) {
skip_bits1(&s->gb); /* not_8_bit */ s->vol_sprite_usage = get_bits1(&s->gb); /* vol_sprite_usage */
} else {
s->vol_sprite_usage = get_bits(&s->gb, 2); /* vol_sprite_usage */
}
if (get_bits1(&s->gb) == 1) { /* not_8_bit */
s->quant_precision = get_bits(&s->gb, 4); /* quant_precision */
skip_bits(&s->gb, 4); /* bits_per_pixel */
} else {
s->quant_precision = 5;
}
skip_bits1(&s->gb); /* vol_quant_type */ skip_bits1(&s->gb); /* vol_quant_type */
skip_bits1(&s->gb); /* vol_quarter_pixel */ skip_bits1(&s->gb); /* vol_quarter_pixel */
skip_bits1(&s->gb); /* complexity_estimation_disabled */ skip_bits1(&s->gb); /* complexity_estimation_disabled */
skip_bits1(&s->gb); /* resync_marker_disabled */ skip_bits1(&s->gb); /* resync_marker_disabled */
skip_bits1(&s->gb); /* data_partioning_enabled */ skip_bits1(&s->gb); /* data_partioning_enabled */
if (get_bits1(&s->gb) != 0) { /* scalability */
printf("bad scalability!!!\n");
return -1;
}
}
goto redo; goto redo;
} else if (startcode != 0x1b6) { } else if (startcode != 0x1b6) {
goto redo; goto redo;
@ -1223,21 +1240,49 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
/* vop coded */ /* vop coded */
if (get_bits1(&s->gb) != 1) if (get_bits1(&s->gb) != 1)
return -1; goto redo;
if (s->pict_type == P_TYPE) { if (s->shape != 2 && s->pict_type == P_TYPE) {
/* rounding type for motion estimation */ /* rounding type for motion estimation */
s->no_rounding = get_bits1(&s->gb); s->no_rounding = get_bits1(&s->gb);
} else {
s->no_rounding = 0;
}
if (s->shape != 0) {
if (s->vol_sprite_usage != 1 || s->pict_type != I_TYPE) {
int width, height, hor_spat_ref, ver_spat_ref;
width = get_bits(&s->gb, 13);
skip_bits1(&s->gb); /* marker */
height = get_bits(&s->gb, 13);
skip_bits1(&s->gb); /* marker */
hor_spat_ref = get_bits(&s->gb, 13); /* hor_spat_ref */
skip_bits1(&s->gb); /* marker */
ver_spat_ref = get_bits(&s->gb, 13); /* ver_spat_ref */
}
skip_bits1(&s->gb); /* change_CR_disable */
if (get_bits1(&s->gb) != 0) {
skip_bits(&s->gb, 8); /* constant_alpha_value */
}
} }
if (get_bits(&s->gb, 3) != 0) if (s->shape != 2) {
return -1; /* intra dc VLC threshold */ skip_bits(&s->gb, 3); /* intra dc VLC threshold */
/* note: we do not use quant_precision to avoid problem if no
MPEG4 vol header as it is found on some old opendivx
movies */
s->qscale = get_bits(&s->gb, 5); s->qscale = get_bits(&s->gb, 5);
if (s->pict_type != I_TYPE) { if (s->pict_type != I_TYPE) {
s->f_code = get_bits(&s->gb, 3); /* fcode_for */ s->f_code = get_bits(&s->gb, 3); /* fcode_for */
} }
if (s->shape && (s->pict_type != I_TYPE)) {
skip_bits1(&s->gb); // vop shape coding type
}
}
return 0; return 0;
} }

Loading…
Cancel
Save