summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2001-08-13 21:46:21 +0000
committerFabrice Bellard <fabrice@bellard.org>2001-08-13 21:46:21 +0000
commitd95ecd058e6256b6deacad8b09fbe58b52f07430 (patch)
tree2ab7b5b083c8d3f3ce84bb4ec822859cbd41677b /libavcodec
parent3d03c0a24ec27fb7e5387012e170dce00535c110 (diff)
better vol header parsing for mpeg4
Originally committed as revision 83 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/h263.c131
1 files changed, 88 insertions, 43 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 73355a6edc..0cf59627dd 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
#include "common.h"
#include "dsputil.h"
#include "avcodec.h"
@@ -28,9 +25,6 @@
#include "h263data.h"
#include "mpeg4data.h"
-#define NDEBUG
-#include <assert.h>
-
static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
int n);
static void h263_encode_motion(MpegEncContext * s, int val);
@@ -1166,43 +1160,66 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
}
if (startcode == 0x120) {
- int time_increment_resolution, width, height;
+ int time_increment_resolution, width, height, vo_ver_id;
/* vol header */
skip_bits(&s->gb, 1); /* random access */
skip_bits(&s->gb, 8); /* vo_type */
- skip_bits(&s->gb, 1); /* is_ol_id */
- skip_bits(&s->gb, 4); /* vo_ver_id */
- skip_bits(&s->gb, 3); /* vo_priority */
+ if (get_bits1(&s->gb) != 0) { /* is_ol_id */
+ vo_ver_id = get_bits(&s->gb, 4); /* vo_ver_id */
+ skip_bits(&s->gb, 3); /* vo_priority */
+ } else {
+ vo_ver_id = 1;
+ }
skip_bits(&s->gb, 4); /* aspect_ratio_info */
- skip_bits(&s->gb, 1); /* vol control parameter */
- skip_bits(&s->gb, 2); /* vol shape */
+ skip_bits1(&s->gb); /* vol control parameter */
+ s->shape = get_bits(&s->gb, 2); /* vol shape */
skip_bits1(&s->gb); /* marker */
time_increment_resolution = get_bits(&s->gb, 16);
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); /* vop rate */
- skip_bits(&s->gb, s->time_increment_bits);
- skip_bits1(&s->gb); /* marker */
-
- width = get_bits(&s->gb, 13);
- skip_bits1(&s->gb); /* marker */
- height = get_bits(&s->gb, 13);
- skip_bits1(&s->gb); /* marker */
-
- skip_bits1(&s->gb); /* interfaced */
- skip_bits1(&s->gb); /* OBMC */
- skip_bits(&s->gb, 2); /* vol_sprite_usage */
- skip_bits1(&s->gb); /* not_8_bit */
-
- skip_bits1(&s->gb); /* vol_quant_type */
- skip_bits1(&s->gb); /* vol_quarter_pixel */
- skip_bits1(&s->gb); /* complexity_estimation_disabled */
- skip_bits1(&s->gb); /* resync_marker_disabled */
- skip_bits1(&s->gb); /* data_partioning_enabled */
+ if (get_bits1(&s->gb) != 0) { /* fixed_vop_rate */
+ skip_bits(&s->gb, s->time_increment_bits);
+ }
+
+ if (s->shape != 2) {
+ if (s->shape == 0) {
+ skip_bits1(&s->gb); /* marker */
+ width = get_bits(&s->gb, 13);
+ skip_bits1(&s->gb); /* marker */
+ height = get_bits(&s->gb, 13);
+ skip_bits1(&s->gb); /* marker */
+ }
+
+ skip_bits1(&s->gb); /* interlaced */
+ skip_bits1(&s->gb); /* OBMC */
+ if (vo_ver_id == 1) {
+ 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_quarter_pixel */
+ skip_bits1(&s->gb); /* complexity_estimation_disabled */
+ skip_bits1(&s->gb); /* resync_marker_disabled */
+ skip_bits1(&s->gb); /* data_partioning_enabled */
+ if (get_bits1(&s->gb) != 0) { /* scalability */
+ printf("bad scalability!!!\n");
+ return -1;
+ }
+ }
goto redo;
} else if (startcode != 0x1b6) {
goto redo;
@@ -1223,22 +1240,50 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
skip_bits1(&s->gb); /* marker */
/* vop coded */
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 */
s->no_rounding = get_bits1(&s->gb);
+ } else {
+ s->no_rounding = 0;
}
-
- if (get_bits(&s->gb, 3) != 0)
- return -1; /* intra dc VLC threshold */
-
- s->qscale = get_bits(&s->gb, 5);
-
- if (s->pict_type != I_TYPE) {
- s->f_code = get_bits(&s->gb, 3); /* fcode_for */
- }
- return 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 (s->shape != 2) {
+ 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);
+
+ if (s->pict_type != I_TYPE) {
+ 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;
}
/* don't understand why they choose a different header ! */