summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-10-14 12:21:54 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-10-14 12:21:54 +0000
commitb704e7420b2615d73aafd40a432b624c7272184c (patch)
tree856bc41358ba31d4ab5470b361da124cb7380402 /libavcodec
parent26893f6bd433b01e30d7f81782ff1577a9b3491b (diff)
mpeg4 header parser clenup (needed for parsing of VOL header in avctx->extradata)
Originally committed as revision 1032 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/avcodec.h1
-rw-r--r--libavcodec/h263.c627
-rw-r--r--libavcodec/h263dec.c11
-rw-r--r--libavcodec/mpegvideo.h4
4 files changed, 335 insertions, 308 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index e9a5acda99..86d9b6f586 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -180,6 +180,7 @@ typedef struct AVCodecContext {
* some codecs need / can use extra-data like huffman tables
* mjpeg: huffman tables
* rv10: additional flags
+ * mpeg4: global headers (they can be in the bitstream or here)
* encoding: set/allocated/freed by lavc.
* decoding: set/allocated/freed by user.
*/
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index a9b5650c6f..77588b87d2 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -4040,320 +4040,290 @@ printf("%d %d\n", s->sprite_delta[1][1][1], a<<s->sprite_shift[1][1]);*/
//printf("%d %d %d %d\n", d[0][0], d[0][1], s->sprite_offset[0][0], s->sprite_offset[0][1]);
}
-/* decode mpeg4 VOP header */
-int mpeg4_decode_picture_header(MpegEncContext * s)
-{
- int time_incr, startcode, state, v;
- int time_increment;
+static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
+ int width, height, vo_ver_id;
+
+ /* vol header */
+ skip_bits(gb, 1); /* random access */
+ s->vo_type= get_bits(gb, 8);
+ if (get_bits1(gb) != 0) { /* is_ol_id */
+ vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
+ skip_bits(gb, 3); /* vo_priority */
+ } else {
+ vo_ver_id = 1;
+ }
+//printf("vo type:%d\n",s->vo_type);
+ s->aspect_ratio_info= get_bits(gb, 4);
+ if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){
+ s->aspected_width = get_bits(gb, 8); // par_width
+ s->aspected_height = get_bits(gb, 8); // par_height
+ }
- redo:
- /* search next start code */
- align_get_bits(&s->gb);
- state = 0xff;
- for(;;) {
- v = get_bits(&s->gb, 8);
- if (state == 0x000001) {
- state = ((state << 8) | v) & 0xffffff;
- startcode = state;
- break;
+ if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */
+ int chroma_format= get_bits(gb, 2);
+ if(chroma_format!=1){
+ printf("illegal chroma format\n");
}
- state = ((state << 8) | v) & 0xffffff;
- if( get_bits_count(&s->gb) > s->gb.size*8-32){
- if(s->gb.size>50){
- printf("no VOP startcode found, frame size was=%d\n", s->gb.size);
- return -1;
- }else{
- printf("frame skip\n");
- return FRAME_SKIPED;
- }
+ s->low_delay= get_bits1(gb);
+ if(get_bits1(gb)){ /* vbv parameters */
+ get_bits(gb, 15); /* first_half_bitrate */
+ skip_bits1(gb); /* marker */
+ get_bits(gb, 15); /* latter_half_bitrate */
+ skip_bits1(gb); /* marker */
+ get_bits(gb, 15); /* first_half_vbv_buffer_size */
+ skip_bits1(gb); /* marker */
+ get_bits(gb, 3); /* latter_half_vbv_buffer_size */
+ get_bits(gb, 11); /* first_half_vbv_occupancy */
+ skip_bits1(gb); /* marker */
+ get_bits(gb, 15); /* latter_half_vbv_occupancy */
+ skip_bits1(gb); /* marker */
}
+ }else{
+ // set low delay flag only once so the smart? low delay detection wont be overriden
+ if(s->picture_number==0)
+ s->low_delay=0;
}
-//printf("startcode %X %d\n", startcode, get_bits_count(&s->gb));
- if (startcode == 0x120) { // Video Object Layer
- int width, height, vo_ver_id;
-
- /* vol header */
- skip_bits(&s->gb, 1); /* random access */
- s->vo_type= get_bits(&s->gb, 8);
- 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;
- }
-//printf("vo type:%d\n",s->vo_type);
- s->aspect_ratio_info= get_bits(&s->gb, 4);
- if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){
- s->aspected_width = get_bits(&s->gb, 8); // par_width
- s->aspected_height = get_bits(&s->gb, 8); // par_height
- }
- if ((s->vol_control_parameters=get_bits1(&s->gb))) { /* vol control parameter */
- int chroma_format= get_bits(&s->gb, 2);
- if(chroma_format!=1){
- printf("illegal chroma format\n");
- }
- s->low_delay= get_bits1(&s->gb);
- if(get_bits1(&s->gb)){ /* vbv parameters */
- get_bits(&s->gb, 15); /* first_half_bitrate */
- skip_bits1(&s->gb); /* marker */
- get_bits(&s->gb, 15); /* latter_half_bitrate */
- skip_bits1(&s->gb); /* marker */
- get_bits(&s->gb, 15); /* first_half_vbv_buffer_size */
- skip_bits1(&s->gb); /* marker */
- get_bits(&s->gb, 3); /* latter_half_vbv_buffer_size */
- get_bits(&s->gb, 11); /* first_half_vbv_occupancy */
- skip_bits1(&s->gb); /* marker */
- get_bits(&s->gb, 15); /* latter_half_vbv_occupancy */
- skip_bits1(&s->gb); /* marker */
- }
- }else{
- // set low delay flag only once so the smart? low delay detection wont be overriden
- if(s->picture_number==0)
- s->low_delay=0;
- }
+ s->shape = get_bits(gb, 2); /* vol shape */
+ if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n");
+ if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
+ printf("Gray shape not supported\n");
+ skip_bits(gb, 4); //video_object_layer_shape_extension
+ }
- s->shape = get_bits(&s->gb, 2); /* vol shape */
- if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n");
- if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
- printf("Gray shape not supported\n");
- skip_bits(&s->gb, 4); //video_object_layer_shape_extension
- }
+ skip_bits1(gb); /* marker */
+
+ s->time_increment_resolution = get_bits(gb, 16);
+
+ s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
+ if (s->time_increment_bits < 1)
+ s->time_increment_bits = 1;
+ skip_bits1(gb); /* marker */
+
+ if (get_bits1(gb) != 0) { /* fixed_vop_rate */
+ skip_bits(gb, s->time_increment_bits);
+ }
- skip_bits1(&s->gb); /* marker */
+ if (s->shape != BIN_ONLY_SHAPE) {
+ if (s->shape == RECT_SHAPE) {
+ skip_bits1(gb); /* marker */
+ width = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ height = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ if(width && height){ /* they should be non zero but who knows ... */
+ s->width = width;
+ s->height = height;
+// printf("width/height: %d %d\n", width, height);
+ }
+ }
- s->time_increment_resolution = get_bits(&s->gb, 16);
+ s->progressive_sequence= get_bits1(gb)^1;
+ if(!get_bits1(gb)) printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */
+ if (vo_ver_id == 1) {
+ s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
+ } else {
+ s->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
+ }
+ if(s->vol_sprite_usage==STATIC_SPRITE) printf("Static Sprites not supported\n");
+ if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){
+ if(s->vol_sprite_usage==STATIC_SPRITE){
+ s->sprite_width = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ s->sprite_height= get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ s->sprite_left = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ s->sprite_top = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ }
+ s->num_sprite_warping_points= get_bits(gb, 6);
+ s->sprite_warping_accuracy = get_bits(gb, 2);
+ s->sprite_brightness_change= get_bits1(gb);
+ if(s->vol_sprite_usage==STATIC_SPRITE)
+ s->low_latency_sprite= get_bits1(gb);
+ }
+ // FIXME sadct disable bit if verid!=1 && shape not rect
- s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
- if (s->time_increment_bits < 1)
- s->time_increment_bits = 1;
- skip_bits1(&s->gb); /* marker */
-
- if (get_bits1(&s->gb) != 0) { /* fixed_vop_rate */
- skip_bits(&s->gb, s->time_increment_bits);
+ if (get_bits1(gb) == 1) { /* not_8_bit */
+ s->quant_precision = get_bits(gb, 4); /* quant_precision */
+ if(get_bits(gb, 4)!=8) printf("N-bit not supported\n"); /* bits_per_pixel */
+ if(s->quant_precision!=5) printf("quant precission %d\n", s->quant_precision);
+ } else {
+ s->quant_precision = 5;
}
+
+ // FIXME a bunch of grayscale shape things
- if (s->shape != BIN_ONLY_SHAPE) {
- if (s->shape == RECT_SHAPE) {
- 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 */
- if(width && height){ /* they should be non zero but who knows ... */
- s->width = width;
- s->height = height;
-// printf("width/height: %d %d\n", width, height);
- }
- }
+ if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */
+ int i, j, v;
- s->progressive_sequence= get_bits1(&s->gb)^1;
- if(!get_bits1(&s->gb)) printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */
- 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(s->vol_sprite_usage==STATIC_SPRITE) printf("Static Sprites not supported\n");
- if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){
- if(s->vol_sprite_usage==STATIC_SPRITE){
- s->sprite_width = get_bits(&s->gb, 13);
- skip_bits1(&s->gb); /* marker */
- s->sprite_height= get_bits(&s->gb, 13);
- skip_bits1(&s->gb); /* marker */
- s->sprite_left = get_bits(&s->gb, 13);
- skip_bits1(&s->gb); /* marker */
- s->sprite_top = get_bits(&s->gb, 13);
- skip_bits1(&s->gb); /* marker */
- }
- s->num_sprite_warping_points= get_bits(&s->gb, 6);
- s->sprite_warping_accuracy = get_bits(&s->gb, 2);
- s->sprite_brightness_change= get_bits1(&s->gb);
- if(s->vol_sprite_usage==STATIC_SPRITE)
- s->low_latency_sprite= get_bits1(&s->gb);
- }
- // FIXME sadct disable bit if verid!=1 && shape not rect
-
- if (get_bits1(&s->gb) == 1) { /* not_8_bit */
- s->quant_precision = get_bits(&s->gb, 4); /* quant_precision */
- if(get_bits(&s->gb, 4)!=8) printf("N-bit not supported\n"); /* bits_per_pixel */
- if(s->quant_precision!=5) printf("quant precission %d\n", s->quant_precision);
- } else {
- s->quant_precision = 5;
+ /* load default matrixes */
+ for(i=0; i<64; i++){
+ int j= s->idct_permutation[i];
+ v= ff_mpeg4_default_intra_matrix[i];
+ s->intra_matrix[j]= v;
+ s->chroma_intra_matrix[j]= v;
+
+ v= ff_mpeg4_default_non_intra_matrix[i];
+ s->inter_matrix[j]= v;
+ s->chroma_inter_matrix[j]= v;
}
-
- // FIXME a bunch of grayscale shape things
- if((s->mpeg_quant=get_bits1(&s->gb))){ /* vol_quant_type */
- int i, j, v;
-
- /* load default matrixes */
+ /* load custom intra matrix */
+ if(get_bits1(gb)){
+ int last=0;
for(i=0; i<64; i++){
- int j= s->idct_permutation[i];
- v= ff_mpeg4_default_intra_matrix[i];
+ v= get_bits(gb, 8);
+ if(v==0) break;
+
+ last= v;
+ j= s->idct_permutation[ ff_zigzag_direct[i] ];
s->intra_matrix[j]= v;
s->chroma_intra_matrix[j]= v;
-
- v= ff_mpeg4_default_non_intra_matrix[i];
- s->inter_matrix[j]= v;
- s->chroma_inter_matrix[j]= v;
}
- /* load custom intra matrix */
- if(get_bits1(&s->gb)){
- int last=0;
- for(i=0; i<64; i++){
- v= get_bits(&s->gb, 8);
- if(v==0) break;
-
- last= v;
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
- s->intra_matrix[j]= v;
- s->chroma_intra_matrix[j]= v;
- }
-
- /* replicate last value */
- for(; i<64; i++){
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
- s->intra_matrix[j]= v;
- s->chroma_intra_matrix[j]= v;
- }
+ /* replicate last value */
+ for(; i<64; i++){
+ j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ s->intra_matrix[j]= v;
+ s->chroma_intra_matrix[j]= v;
}
+ }
- /* load custom non intra matrix */
- if(get_bits1(&s->gb)){
- int last=0;
- for(i=0; i<64; i++){
- v= get_bits(&s->gb, 8);
- if(v==0) break;
-
- last= v;
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
- s->inter_matrix[j]= v;
- s->chroma_inter_matrix[j]= v;
- }
+ /* load custom non intra matrix */
+ if(get_bits1(gb)){
+ int last=0;
+ for(i=0; i<64; i++){
+ v= get_bits(gb, 8);
+ if(v==0) break;
- /* replicate last value */
- for(; i<64; i++){
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
- s->inter_matrix[j]= last;
- s->chroma_inter_matrix[j]= last;
- }
+ last= v;
+ j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ s->inter_matrix[j]= v;
+ s->chroma_inter_matrix[j]= v;
}
- // FIXME a bunch of grayscale shape things
+ /* replicate last value */
+ for(; i<64; i++){
+ j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ s->inter_matrix[j]= last;
+ s->chroma_inter_matrix[j]= last;
+ }
}
- if(vo_ver_id != 1)
- s->quarter_sample= get_bits1(&s->gb);
- else s->quarter_sample=0;
+ // FIXME a bunch of grayscale shape things
+ }
- if(!get_bits1(&s->gb)) printf("Complexity estimation not supported\n");
+ if(vo_ver_id != 1)
+ s->quarter_sample= get_bits1(gb);
+ else s->quarter_sample=0;
- s->resync_marker= !get_bits1(&s->gb); /* resync_marker_disabled */
+ if(!get_bits1(gb)) printf("Complexity estimation not supported\n");
- s->data_partitioning= get_bits1(&s->gb);
- if(s->data_partitioning){
- s->rvlc= get_bits1(&s->gb);
- if(s->rvlc){
- printf("reversible vlc not supported\n");
- }
- }
-
- if(vo_ver_id != 1) {
- s->new_pred= get_bits1(&s->gb);
- if(s->new_pred){
- printf("new pred not supported\n");
- skip_bits(&s->gb, 2); /* requested upstream message type */
- skip_bits1(&s->gb); /* newpred segment type */
- }
- s->reduced_res_vop= get_bits1(&s->gb);
- if(s->reduced_res_vop) printf("reduced resolution VOP not supported\n");
- }
- else{
- s->new_pred=0;
- s->reduced_res_vop= 0;
- }
+ s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */
- s->scalability= get_bits1(&s->gb);
-
- if (s->scalability) {
- GetBitContext bak= s->gb;
- int dummy= s->hierachy_type= get_bits1(&s->gb);
- int ref_layer_id= get_bits(&s->gb, 4);
- int ref_layer_sampling_dir= get_bits1(&s->gb);
- int h_sampling_factor_n= get_bits(&s->gb, 5);
- int h_sampling_factor_m= get_bits(&s->gb, 5);
- int v_sampling_factor_n= get_bits(&s->gb, 5);
- int v_sampling_factor_m= get_bits(&s->gb, 5);
- s->enhancement_type= get_bits1(&s->gb);
-
- if( h_sampling_factor_n==0 || h_sampling_factor_m==0
- || v_sampling_factor_n==0 || v_sampling_factor_m==0){
-
-// fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n");
- s->scalability=0;
-
- s->gb= bak;
- goto redo;
- }
-
- // bin shape stuff FIXME
- printf("scalability not supported\n");
+ s->data_partitioning= get_bits1(gb);
+ if(s->data_partitioning){
+ s->rvlc= get_bits1(gb);
+ if(s->rvlc){
+ printf("reversible vlc not supported\n");
}
}
-//printf("end Data %X %d\n", show_bits(&s->gb, 32), get_bits_count(&s->gb)&0x7);
- goto redo;
- } else if (startcode == 0x1b2) { //userdata
- char buf[256];
- int i;
- int e;
- int ver, build, ver2, ver3;
-
-//printf("user Data %X\n", show_bits(&s->gb, 32));
- buf[0]= show_bits(&s->gb, 8);
- for(i=1; i<256; i++){
- buf[i]= show_bits(&s->gb, 16)&0xFF;
- if(buf[i]==0) break;
- skip_bits(&s->gb, 8);
- }
- buf[255]=0;
- e=sscanf(buf, "DivX%dBuild%d", &ver, &build);
- if(e!=2)
- e=sscanf(buf, "DivX%db%d", &ver, &build);
- if(e==2){
- s->divx_version= ver;
- s->divx_build= build;
- if(s->picture_number==0){
- printf("This file was encoded with DivX%d Build%d\n", ver, build);
- if(ver==500 && build==413){
- printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n");
- }
+
+ if(vo_ver_id != 1) {
+ s->new_pred= get_bits1(gb);
+ if(s->new_pred){
+ printf("new pred not supported\n");
+ skip_bits(gb, 2); /* requested upstream message type */
+ skip_bits1(gb); /* newpred segment type */
}
+ s->reduced_res_vop= get_bits1(gb);
+ if(s->reduced_res_vop) printf("reduced resolution VOP not supported\n");
+ }
+ else{
+ s->new_pred=0;
+ s->reduced_res_vop= 0;
+ }
+
+ s->scalability= get_bits1(gb);
+
+ if (s->scalability) {
+ GetBitContext bak= *gb;
+ int dummy= s->hierachy_type= get_bits1(gb);
+ int ref_layer_id= get_bits(gb, 4);
+ int ref_layer_sampling_dir= get_bits1(gb);
+ int h_sampling_factor_n= get_bits(gb, 5);
+ int h_sampling_factor_m= get_bits(gb, 5);
+ int v_sampling_factor_n= get_bits(gb, 5);
+ int v_sampling_factor_m= get_bits(gb, 5);
+ s->enhancement_type= get_bits1(gb);
+
+ if( h_sampling_factor_n==0 || h_sampling_factor_m==0
+ || v_sampling_factor_n==0 || v_sampling_factor_m==0){
+
+// fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n");
+ s->scalability=0;
+
+ *gb= bak;
+ }else
+ printf("scalability not supported\n");
+
+ // bin shape stuff FIXME
}
- e=sscanf(buf, "FFmpeg%d.%d.%db%d", &ver, &ver2, &ver3, &build);
- if(e!=4)
- e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
- if(e!=4){
- if(strcmp(buf, "ffmpeg")==0){
- s->ffmpeg_version= 0x000406;
- s->lavc_build= 4600;
+ }
+ return 0;
+}
+
+static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
+ char buf[256];
+ int i;
+ int e;
+ int ver, build, ver2, ver3;
+
+ buf[0]= show_bits(gb, 8);
+ for(i=1; i<256; i++){
+ buf[i]= show_bits(gb, 16)&0xFF;
+ if(buf[i]==0) break;
+ skip_bits(gb, 8);
+ }
+ buf[255]=0;
+ e=sscanf(buf, "DivX%dBuild%d", &ver, &build);
+ if(e!=2)
+ e=sscanf(buf, "DivX%db%d", &ver, &build);
+ if(e==2){
+ s->divx_version= ver;
+ s->divx_build= build;
+ if(s->picture_number==0){
+ printf("This file was encoded with DivX%d Build%d\n", ver, build);
+ if(ver==500 && build==413){
+ printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n");
}
}
- if(e==4){
- s->ffmpeg_version= ver*256*256 + ver2*256 + ver3;
- s->lavc_build= build;
- if(s->picture_number==0)
- printf("This file was encoded with libavcodec build %d\n", build);
+ }
+ e=sscanf(buf, "FFmpeg%d.%d.%db%d", &ver, &ver2, &ver3, &build);
+ if(e!=4)
+ e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
+ if(e!=4){
+ if(strcmp(buf, "ffmpeg")==0){
+ s->ffmpeg_version= 0x000406;
+ s->lavc_build= 4600;
}
-//printf("User Data: %s\n", buf);
- goto redo;
- } else if (startcode != 0x1b6) { //VOP
- goto redo;
}
-
- s->pict_type = get_bits(&s->gb, 2) + I_TYPE; /* pict type: I = 0 , P = 1 */
-//if(s->pict_type!=I_TYPE) return FRAME_SKIPED;
+ if(e==4){
+ s->ffmpeg_version= ver*256*256 + ver2*256 + ver3;
+ s->lavc_build= build;
+ if(s->picture_number==0)
+ printf("This file was encoded with libavcodec build %d\n", build);
+ }
+//printf("User Data: %s\n", buf);
+ return 0;
+}
+
+static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
+ int time_incr, time_increment;
+
+ s->pict_type = get_bits(gb, 2) + I_TYPE; /* pict type: I = 0 , P = 1 */
if(s->pict_type==B_TYPE && s->low_delay && s->vol_control_parameters==0){
printf("low_delay flag set, but shouldnt, clearing it\n");
s->low_delay=0;
@@ -4371,11 +4341,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
// fprintf(stderr, "time_increment_resolution is illegal\n");
}
time_incr=0;
- while (get_bits1(&s->gb) != 0)
+ while (get_bits1(gb) != 0)
time_incr++;
- check_marker(&s->gb, "before time_increment");
- time_increment= get_bits(&s->gb, s->time_increment_bits);
+ check_marker(gb, "before time_increment");
+ time_increment= get_bits(gb, s->time_increment_bits);
//printf(" type:%d modulo_time_base:%d increment:%d\n", s->pict_type, time_incr, time_increment);
if(s->pict_type!=B_TYPE){
s->last_time_base= s->time_base;
@@ -4409,22 +4379,24 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution;
- if(check_marker(&s->gb, "before vop_coded")==0 && s->picture_number==0){
+ if(check_marker(gb, "before vop_coded")==0 && s->picture_number==0){
printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n");
for(s->time_increment_bits++ ;s->time_increment_bits<16; s->time_increment_bits++){
- if(get_bits1(&s->gb)) break;
+ if(get_bits1(gb)) break;
}
printf("my guess is %d bits ;)\n",s->time_increment_bits);
}
/* vop coded */
- if (get_bits1(&s->gb) != 1)
- goto redo;
+ if (get_bits1(gb) != 1){
+ printf("vop not coded\n");
+ return FRAME_SKIPED;
+ }
//printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->time_increment_resolution, s->time_base,
//s->time, s->last_non_b_time, s->last_non_b_time - s->pp_time);
if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE
|| (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) {
/* rounding type for motion estimation */
- s->no_rounding = get_bits1(&s->gb);
+ s->no_rounding = get_bits1(gb);
} else {
s->no_rounding = 0;
}
@@ -4434,29 +4406,29 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
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 */
+ width = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ height = get_bits(gb, 13);
+ skip_bits1(gb); /* marker */
+ hor_spat_ref = get_bits(gb, 13); /* hor_spat_ref */
+ skip_bits1(gb); /* marker */
+ ver_spat_ref = get_bits(gb, 13); /* ver_spat_ref */
}
- skip_bits1(&s->gb); /* change_CR_disable */
+ skip_bits1(gb); /* change_CR_disable */
- if (get_bits1(&s->gb) != 0) {
- skip_bits(&s->gb, 8); /* constant_alpha_value */
+ if (get_bits1(gb) != 0) {
+ skip_bits(gb, 8); /* constant_alpha_value */
}
}
//FIXME complexity estimation stuff
if (s->shape != BIN_ONLY_SHAPE) {
int t;
- t=get_bits(&s->gb, 3); /* intra dc VLC threshold */
+ t=get_bits(gb, 3); /* intra dc VLC threshold */
//printf("threshold %d\n", t);
if(!s->progressive_sequence){
- s->top_field_first= get_bits1(&s->gb);
- s->alternate_scan= get_bits1(&s->gb);
+ s->top_field_first= get_bits1(gb);
+ s->alternate_scan= get_bits1(gb);
}else
s->alternate_scan= 0;
}
@@ -4482,14 +4454,14 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
}
if (s->shape != BIN_ONLY_SHAPE) {
- s->qscale = get_bits(&s->gb, s->quant_precision);
+ s->qscale = get_bits(gb, s->quant_precision);
if(s->qscale==0){
printf("Error, header damaged or not MPEG4 header (qscale=0)\n");
return -1; // makes no sense to continue, as there is nothing left from the image then
}
if (s->pict_type != I_TYPE) {
- s->f_code = get_bits(&s->gb, 3); /* fcode_for */
+ s->f_code = get_bits(gb, 3); /* fcode_for */
if(s->f_code==0){
printf("Error, header damaged or not MPEG4 header (f_code=0)\n");
return -1; // makes no sense to continue, as the MV decoding will break very quickly
@@ -4498,28 +4470,28 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
s->f_code=1;
if (s->pict_type == B_TYPE) {
- s->b_code = get_bits(&s->gb, 3);
+ s->b_code = get_bits(gb, 3);
}else
s->b_code=1;
#if 0
printf("qp:%d fc:%d bc:%d type:%s size:%d pro:%d alt:%d top:%d qpel:%d part:%d resync:%d\n",
s->qscale, s->f_code, s->b_code,
s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")),
- s->gb.size,s->progressive_sequence, s->alternate_scan, s->top_field_first,
+ gb->size,s->progressive_sequence, s->alternate_scan, s->top_field_first,
s->quarter_sample, s->data_partitioning, s->resync_marker);
#endif
if(!s->scalability){
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
- skip_bits1(&s->gb); // vop shape coding type
+ skip_bits1(gb); // vop shape coding type
}
}else{
if(s->enhancement_type){
- int load_backward_shape= get_bits1(&s->gb);
+ int load_backward_shape= get_bits1(gb);
if(load_backward_shape){
printf("load backward shape isnt supported\n");
}
}
- skip_bits(&s->gb, 2); //ref_select_code
+ skip_bits(gb, 2); //ref_select_code
}
}
/* detect buggy encoders which dont set the low_delay flag (divx4/xvid/opendivx)*/
@@ -4541,6 +4513,53 @@ printf("qp:%d fc:%d bc:%d type:%s size:%d pro:%d alt:%d top:%d qpel:%d part:%d r
return 0;
}
+/**
+ * decode mpeg4 headers
+ * @return <0 if no VOP found (or a damaged one)
+ * FRAME_SKIPPED if a not coded VOP is found
+ * 0 if a VOP is found
+ */
+int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
+{
+ int startcode, v;
+
+ /* search next start code */
+ align_get_bits(gb);
+ startcode = 0xff;
+ for(;;) {
+ v = get_bits(gb, 8);
+ startcode = ((startcode << 8) | v) & 0xffffffff;
+
+ if(get_bits_count(gb) >= gb->size*8){
+ if(gb->size==1 && s->divx_version){
+ printf("frame skip %d\n", gb->size);
+ return FRAME_SKIPED; //divx bug
+ }else
+ return -1; //end of stream
+ }
+
+ if((startcode&0xFFFFFF00) != 0x100)
+ continue; //no startcode
+
+ switch(startcode){
+ case 0x120:
+ decode_vol_header(s, gb);
+ break;
+ case 0x1b2:
+ decode_user_data(s, gb);
+ break;
+ case 0x1b6:
+ return decode_vop_header(s, gb);
+ default:
+// printf("startcode %X found\n", startcode);
+ break;
+ }
+
+ align_get_bits(gb);
+ startcode = 0xff;
+ }
+}
+
/* don't understand why they choose a different header ! */
int intel_h263_decode_picture_header(MpegEncContext *s)
{
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 5b7a9d2995..652907f0f1 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -40,8 +40,6 @@ static inline long long rdtsc()
}
#endif
-const UINT16 ff_mpeg4_resync_prefix[8];
-
static int h263_decode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
@@ -313,7 +311,14 @@ uint64_t time= rdtsc();
if (s->h263_msmpeg4) {
ret = msmpeg4_decode_picture_header(s);
} else if (s->h263_pred) {
- ret = mpeg4_decode_picture_header(s);
+ if(s->avctx->extradata_size && s->picture_number==0){
+ GetBitContext gb;
+
+ init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size);
+ ret = ff_mpeg4_decode_picture_header(s, &gb);
+ }
+ ret = ff_mpeg4_decode_picture_header(s, &s->gb);
+
s->has_b_frames= !s->low_delay;
} else if (s->h263_intel) {
ret = intel_h263_decode_picture_header(s);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index bc458e63ac..ff03f2bdfe 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -624,7 +624,9 @@ void h263_encode_init(MpegEncContext *s);
void h263_decode_init_vlc(MpegEncContext *s);
int h263_decode_picture_header(MpegEncContext *s);
int ff_h263_decode_gob_header(MpegEncContext *s);
-int mpeg4_decode_picture_header(MpegEncContext * s);
+int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb);
+
+
int intel_h263_decode_picture_header(MpegEncContext *s);
int ff_h263_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]);