Commit 7c4d9a58 authored by michaelni's avatar michaelni

mpeg4 header parser clenup (needed for parsing of VOL header in avctx->extradata)


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@1032 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent beaa5b2f
...@@ -180,6 +180,7 @@ typedef struct AVCodecContext { ...@@ -180,6 +180,7 @@ typedef struct AVCodecContext {
* some codecs need / can use extra-data like huffman tables * some codecs need / can use extra-data like huffman tables
* mjpeg: huffman tables * mjpeg: huffman tables
* rv10: additional flags * rv10: additional flags
* mpeg4: global headers (they can be in the bitstream or here)
* encoding: set/allocated/freed by lavc. * encoding: set/allocated/freed by lavc.
* decoding: set/allocated/freed by user. * decoding: set/allocated/freed by user.
*/ */
......
...@@ -4040,72 +4040,43 @@ printf("%d %d\n", s->sprite_delta[1][1][1], a<<s->sprite_shift[1][1]);*/ ...@@ -4040,72 +4040,43 @@ 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]); //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 */ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
int mpeg4_decode_picture_header(MpegEncContext * s)
{
int time_incr, startcode, state, v;
int time_increment;
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;
}
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;
}
}
}
//printf("startcode %X %d\n", startcode, get_bits_count(&s->gb));
if (startcode == 0x120) { // Video Object Layer
int width, height, vo_ver_id; int width, height, vo_ver_id;
/* vol header */ /* vol header */
skip_bits(&s->gb, 1); /* random access */ skip_bits(gb, 1); /* random access */
s->vo_type= get_bits(&s->gb, 8); s->vo_type= get_bits(gb, 8);
if (get_bits1(&s->gb) != 0) { /* is_ol_id */ if (get_bits1(gb) != 0) { /* is_ol_id */
vo_ver_id = get_bits(&s->gb, 4); /* vo_ver_id */ vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
skip_bits(&s->gb, 3); /* vo_priority */ skip_bits(gb, 3); /* vo_priority */
} else { } else {
vo_ver_id = 1; vo_ver_id = 1;
} }
//printf("vo type:%d\n",s->vo_type); //printf("vo type:%d\n",s->vo_type);
s->aspect_ratio_info= get_bits(&s->gb, 4); s->aspect_ratio_info= get_bits(gb, 4);
if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){ if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){
s->aspected_width = get_bits(&s->gb, 8); // par_width s->aspected_width = get_bits(gb, 8); // par_width
s->aspected_height = get_bits(&s->gb, 8); // par_height s->aspected_height = get_bits(gb, 8); // par_height
} }
if ((s->vol_control_parameters=get_bits1(&s->gb))) { /* vol control parameter */ if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */
int chroma_format= get_bits(&s->gb, 2); int chroma_format= get_bits(gb, 2);
if(chroma_format!=1){ if(chroma_format!=1){
printf("illegal chroma format\n"); printf("illegal chroma format\n");
} }
s->low_delay= get_bits1(&s->gb); s->low_delay= get_bits1(gb);
if(get_bits1(&s->gb)){ /* vbv parameters */ if(get_bits1(gb)){ /* vbv parameters */
get_bits(&s->gb, 15); /* first_half_bitrate */ get_bits(gb, 15); /* first_half_bitrate */
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
get_bits(&s->gb, 15); /* latter_half_bitrate */ get_bits(gb, 15); /* latter_half_bitrate */
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
get_bits(&s->gb, 15); /* first_half_vbv_buffer_size */ get_bits(gb, 15); /* first_half_vbv_buffer_size */
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
get_bits(&s->gb, 3); /* latter_half_vbv_buffer_size */ get_bits(gb, 3); /* latter_half_vbv_buffer_size */
get_bits(&s->gb, 11); /* first_half_vbv_occupancy */ get_bits(gb, 11); /* first_half_vbv_occupancy */
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
get_bits(&s->gb, 15); /* latter_half_vbv_occupancy */ get_bits(gb, 15); /* latter_half_vbv_occupancy */
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
} }
}else{ }else{
// set low delay flag only once so the smart? low delay detection wont be overriden // set low delay flag only once so the smart? low delay detection wont be overriden
...@@ -4113,33 +4084,33 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4113,33 +4084,33 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
s->low_delay=0; s->low_delay=0;
} }
s->shape = get_bits(&s->gb, 2); /* vol shape */ s->shape = get_bits(gb, 2); /* vol shape */
if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n"); if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n");
if(s->shape == GRAY_SHAPE && vo_ver_id != 1){ if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
printf("Gray shape not supported\n"); printf("Gray shape not supported\n");
skip_bits(&s->gb, 4); //video_object_layer_shape_extension skip_bits(gb, 4); //video_object_layer_shape_extension
} }
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
s->time_increment_resolution = get_bits(&s->gb, 16); s->time_increment_resolution = get_bits(gb, 16);
s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
if (s->time_increment_bits < 1) if (s->time_increment_bits < 1)
s->time_increment_bits = 1; s->time_increment_bits = 1;
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
if (get_bits1(&s->gb) != 0) { /* fixed_vop_rate */ if (get_bits1(gb) != 0) { /* fixed_vop_rate */
skip_bits(&s->gb, s->time_increment_bits); skip_bits(gb, s->time_increment_bits);
} }
if (s->shape != BIN_ONLY_SHAPE) { if (s->shape != BIN_ONLY_SHAPE) {
if (s->shape == RECT_SHAPE) { if (s->shape == RECT_SHAPE) {
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
width = get_bits(&s->gb, 13); width = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
height = get_bits(&s->gb, 13); height = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
if(width && height){ /* they should be non zero but who knows ... */ if(width && height){ /* they should be non zero but who knows ... */
s->width = width; s->width = width;
s->height = height; s->height = height;
...@@ -4147,36 +4118,36 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4147,36 +4118,36 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
} }
s->progressive_sequence= get_bits1(&s->gb)^1; s->progressive_sequence= get_bits1(gb)^1;
if(!get_bits1(&s->gb)) printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ if(!get_bits1(gb)) printf("OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */
if (vo_ver_id == 1) { if (vo_ver_id == 1) {
s->vol_sprite_usage = get_bits1(&s->gb); /* vol_sprite_usage */ s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
} else { } else {
s->vol_sprite_usage = get_bits(&s->gb, 2); /* vol_sprite_usage */ 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) 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->vol_sprite_usage==GMC_SPRITE){
if(s->vol_sprite_usage==STATIC_SPRITE){ if(s->vol_sprite_usage==STATIC_SPRITE){
s->sprite_width = get_bits(&s->gb, 13); s->sprite_width = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
s->sprite_height= get_bits(&s->gb, 13); s->sprite_height= get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
s->sprite_left = get_bits(&s->gb, 13); s->sprite_left = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
s->sprite_top = get_bits(&s->gb, 13); s->sprite_top = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
} }
s->num_sprite_warping_points= get_bits(&s->gb, 6); s->num_sprite_warping_points= get_bits(gb, 6);
s->sprite_warping_accuracy = get_bits(&s->gb, 2); s->sprite_warping_accuracy = get_bits(gb, 2);
s->sprite_brightness_change= get_bits1(&s->gb); s->sprite_brightness_change= get_bits1(gb);
if(s->vol_sprite_usage==STATIC_SPRITE) if(s->vol_sprite_usage==STATIC_SPRITE)
s->low_latency_sprite= get_bits1(&s->gb); s->low_latency_sprite= get_bits1(gb);
} }
// FIXME sadct disable bit if verid!=1 && shape not rect // FIXME sadct disable bit if verid!=1 && shape not rect
if (get_bits1(&s->gb) == 1) { /* not_8_bit */ if (get_bits1(gb) == 1) { /* not_8_bit */
s->quant_precision = get_bits(&s->gb, 4); /* quant_precision */ s->quant_precision = get_bits(gb, 4); /* quant_precision */
if(get_bits(&s->gb, 4)!=8) printf("N-bit not supported\n"); /* bits_per_pixel */ 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); if(s->quant_precision!=5) printf("quant precission %d\n", s->quant_precision);
} else { } else {
s->quant_precision = 5; s->quant_precision = 5;
...@@ -4184,7 +4155,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4184,7 +4155,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
// FIXME a bunch of grayscale shape things // FIXME a bunch of grayscale shape things
if((s->mpeg_quant=get_bits1(&s->gb))){ /* vol_quant_type */ if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */
int i, j, v; int i, j, v;
/* load default matrixes */ /* load default matrixes */
...@@ -4200,10 +4171,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4200,10 +4171,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
/* load custom intra matrix */ /* load custom intra matrix */
if(get_bits1(&s->gb)){ if(get_bits1(gb)){
int last=0; int last=0;
for(i=0; i<64; i++){ for(i=0; i<64; i++){
v= get_bits(&s->gb, 8); v= get_bits(gb, 8);
if(v==0) break; if(v==0) break;
last= v; last= v;
...@@ -4221,10 +4192,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4221,10 +4192,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
/* load custom non intra matrix */ /* load custom non intra matrix */
if(get_bits1(&s->gb)){ if(get_bits1(gb)){
int last=0; int last=0;
for(i=0; i<64; i++){ for(i=0; i<64; i++){
v= get_bits(&s->gb, 8); v= get_bits(gb, 8);
if(v==0) break; if(v==0) break;
last= v; last= v;
...@@ -4245,29 +4216,29 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4245,29 +4216,29 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
if(vo_ver_id != 1) if(vo_ver_id != 1)
s->quarter_sample= get_bits1(&s->gb); s->quarter_sample= get_bits1(gb);
else s->quarter_sample=0; else s->quarter_sample=0;
if(!get_bits1(&s->gb)) printf("Complexity estimation not supported\n"); if(!get_bits1(gb)) printf("Complexity estimation not supported\n");
s->resync_marker= !get_bits1(&s->gb); /* resync_marker_disabled */ s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */
s->data_partitioning= get_bits1(&s->gb); s->data_partitioning= get_bits1(gb);
if(s->data_partitioning){ if(s->data_partitioning){
s->rvlc= get_bits1(&s->gb); s->rvlc= get_bits1(gb);
if(s->rvlc){ if(s->rvlc){
printf("reversible vlc not supported\n"); printf("reversible vlc not supported\n");
} }
} }
if(vo_ver_id != 1) { if(vo_ver_id != 1) {
s->new_pred= get_bits1(&s->gb); s->new_pred= get_bits1(gb);
if(s->new_pred){ if(s->new_pred){
printf("new pred not supported\n"); printf("new pred not supported\n");
skip_bits(&s->gb, 2); /* requested upstream message type */ skip_bits(gb, 2); /* requested upstream message type */
skip_bits1(&s->gb); /* newpred segment type */ skip_bits1(gb); /* newpred segment type */
} }
s->reduced_res_vop= get_bits1(&s->gb); s->reduced_res_vop= get_bits1(gb);
if(s->reduced_res_vop) printf("reduced resolution VOP not supported\n"); if(s->reduced_res_vop) printf("reduced resolution VOP not supported\n");
} }
else{ else{
...@@ -4275,18 +4246,18 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4275,18 +4246,18 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
s->reduced_res_vop= 0; s->reduced_res_vop= 0;
} }
s->scalability= get_bits1(&s->gb); s->scalability= get_bits1(gb);
if (s->scalability) { if (s->scalability) {
GetBitContext bak= s->gb; GetBitContext bak= *gb;
int dummy= s->hierachy_type= get_bits1(&s->gb); int dummy= s->hierachy_type= get_bits1(gb);
int ref_layer_id= get_bits(&s->gb, 4); int ref_layer_id= get_bits(gb, 4);
int ref_layer_sampling_dir= get_bits1(&s->gb); int ref_layer_sampling_dir= get_bits1(gb);
int h_sampling_factor_n= get_bits(&s->gb, 5); int h_sampling_factor_n= get_bits(gb, 5);
int h_sampling_factor_m= get_bits(&s->gb, 5); int h_sampling_factor_m= get_bits(gb, 5);
int v_sampling_factor_n= get_bits(&s->gb, 5); int v_sampling_factor_n= get_bits(gb, 5);
int v_sampling_factor_m= get_bits(&s->gb, 5); int v_sampling_factor_m= get_bits(gb, 5);
s->enhancement_type= get_bits1(&s->gb); s->enhancement_type= get_bits1(gb);
if( h_sampling_factor_n==0 || h_sampling_factor_m==0 if( h_sampling_factor_n==0 || h_sampling_factor_m==0
|| v_sampling_factor_n==0 || v_sampling_factor_m==0){ || v_sampling_factor_n==0 || v_sampling_factor_m==0){
...@@ -4294,28 +4265,27 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4294,28 +4265,27 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
// fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n"); // fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n");
s->scalability=0; s->scalability=0;
s->gb= bak; *gb= bak;
goto redo; }else
} printf("scalability not supported\n");
// bin shape stuff FIXME // bin shape stuff FIXME
printf("scalability not supported\n");
} }
} }
//printf("end Data %X %d\n", show_bits(&s->gb, 32), get_bits_count(&s->gb)&0x7); return 0;
goto redo; }
} else if (startcode == 0x1b2) { //userdata
static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
char buf[256]; char buf[256];
int i; int i;
int e; int e;
int ver, build, ver2, ver3; int ver, build, ver2, ver3;
//printf("user Data %X\n", show_bits(&s->gb, 32)); buf[0]= show_bits(gb, 8);
buf[0]= show_bits(&s->gb, 8);
for(i=1; i<256; i++){ for(i=1; i<256; i++){
buf[i]= show_bits(&s->gb, 16)&0xFF; buf[i]= show_bits(gb, 16)&0xFF;
if(buf[i]==0) break; if(buf[i]==0) break;
skip_bits(&s->gb, 8); skip_bits(gb, 8);
} }
buf[255]=0; buf[255]=0;
e=sscanf(buf, "DivX%dBuild%d", &ver, &build); e=sscanf(buf, "DivX%dBuild%d", &ver, &build);
...@@ -4347,13 +4317,13 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4347,13 +4317,13 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
printf("This file was encoded with libavcodec build %d\n", build); printf("This file was encoded with libavcodec build %d\n", build);
} }
//printf("User Data: %s\n", buf); //printf("User Data: %s\n", buf);
goto redo; return 0;
} else if (startcode != 0x1b6) { //VOP }
goto redo;
}
s->pict_type = get_bits(&s->gb, 2) + I_TYPE; /* pict type: I = 0 , P = 1 */ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
//if(s->pict_type!=I_TYPE) return FRAME_SKIPED; 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){ if(s->pict_type==B_TYPE && s->low_delay && s->vol_control_parameters==0){
printf("low_delay flag set, but shouldnt, clearing it\n"); printf("low_delay flag set, but shouldnt, clearing it\n");
s->low_delay=0; s->low_delay=0;
...@@ -4371,11 +4341,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4371,11 +4341,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
// fprintf(stderr, "time_increment_resolution is illegal\n"); // fprintf(stderr, "time_increment_resolution is illegal\n");
} }
time_incr=0; time_incr=0;
while (get_bits1(&s->gb) != 0) while (get_bits1(gb) != 0)
time_incr++; time_incr++;
check_marker(&s->gb, "before time_increment"); check_marker(gb, "before time_increment");
time_increment= get_bits(&s->gb, s->time_increment_bits); 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); //printf(" type:%d modulo_time_base:%d increment:%d\n", s->pict_type, time_incr, time_increment);
if(s->pict_type!=B_TYPE){ if(s->pict_type!=B_TYPE){
s->last_time_base= s->time_base; s->last_time_base= s->time_base;
...@@ -4409,22 +4379,24 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4409,22 +4379,24 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution; 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"); 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++){ 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); printf("my guess is %d bits ;)\n",s->time_increment_bits);
} }
/* vop coded */ /* vop coded */
if (get_bits1(&s->gb) != 1) if (get_bits1(gb) != 1){
goto redo; 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, //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); //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 if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE
|| (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) { || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) {
/* rounding type for motion estimation */ /* rounding type for motion estimation */
s->no_rounding = get_bits1(&s->gb); s->no_rounding = get_bits1(gb);
} else { } else {
s->no_rounding = 0; s->no_rounding = 0;
} }
...@@ -4434,29 +4406,29 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4434,29 +4406,29 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
if (s->vol_sprite_usage != 1 || s->pict_type != I_TYPE) { if (s->vol_sprite_usage != 1 || s->pict_type != I_TYPE) {
int width, height, hor_spat_ref, ver_spat_ref; int width, height, hor_spat_ref, ver_spat_ref;
width = get_bits(&s->gb, 13); width = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
height = get_bits(&s->gb, 13); height = get_bits(gb, 13);
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
hor_spat_ref = get_bits(&s->gb, 13); /* hor_spat_ref */ hor_spat_ref = get_bits(gb, 13); /* hor_spat_ref */
skip_bits1(&s->gb); /* marker */ skip_bits1(gb); /* marker */
ver_spat_ref = get_bits(&s->gb, 13); /* ver_spat_ref */ 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) { if (get_bits1(gb) != 0) {
skip_bits(&s->gb, 8); /* constant_alpha_value */ skip_bits(gb, 8); /* constant_alpha_value */
} }
} }
//FIXME complexity estimation stuff //FIXME complexity estimation stuff
if (s->shape != BIN_ONLY_SHAPE) { if (s->shape != BIN_ONLY_SHAPE) {
int t; 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); //printf("threshold %d\n", t);
if(!s->progressive_sequence){ if(!s->progressive_sequence){
s->top_field_first= get_bits1(&s->gb); s->top_field_first= get_bits1(gb);
s->alternate_scan= get_bits1(&s->gb); s->alternate_scan= get_bits1(gb);
}else }else
s->alternate_scan= 0; s->alternate_scan= 0;
} }
...@@ -4482,14 +4454,14 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -4482,14 +4454,14 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
if (s->shape != BIN_ONLY_SHAPE) { 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){ if(s->qscale==0){
printf("Error, header damaged or not MPEG4 header (qscale=0)\n"); 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 return -1; // makes no sense to continue, as there is nothing left from the image then
} }
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(gb, 3); /* fcode_for */
if(s->f_code==0){ if(s->f_code==0){
printf("Error, header damaged or not MPEG4 header (f_code=0)\n"); 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 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) ...@@ -4498,28 +4470,28 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
s->f_code=1; s->f_code=1;
if (s->pict_type == B_TYPE) { if (s->pict_type == B_TYPE) {
s->b_code = get_bits(&s->gb, 3); s->b_code = get_bits(gb, 3);
}else }else
s->b_code=1; s->b_code=1;
#if 0 #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", 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->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->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); s->quarter_sample, s->data_partitioning, s->resync_marker);
#endif #endif
if(!s->scalability){ if(!s->scalability){
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) { 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{ }else{
if(s->enhancement_type){ if(s->enhancement_type){
int load_backward_shape= get_bits1(&s->gb); int load_backward_shape= get_bits1(gb);
if(load_backward_shape){ if(load_backward_shape){
printf("load backward shape isnt supported\n"); 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)*/ /* 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 ...@@ -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; 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 ! */ /* don't understand why they choose a different header ! */
int intel_h263_decode_picture_header(MpegEncContext *s) int intel_h263_decode_picture_header(MpegEncContext *s)
{ {
......
...@@ -40,8 +40,6 @@ static inline long long rdtsc() ...@@ -40,8 +40,6 @@ static inline long long rdtsc()
} }
#endif #endif
const UINT16 ff_mpeg4_resync_prefix[8];
static int h263_decode_init(AVCodecContext *avctx) static int h263_decode_init(AVCodecContext *avctx)
{ {
MpegEncContext *s = avctx->priv_data; MpegEncContext *s = avctx->priv_data;
...@@ -313,7 +311,14 @@ uint64_t time= rdtsc(); ...@@ -313,7 +311,14 @@ uint64_t time= rdtsc();
if (s->h263_msmpeg4) { if (s->h263_msmpeg4) {
ret = msmpeg4_decode_picture_header(s); ret = msmpeg4_decode_picture_header(s);
} else if (s->h263_pred) { } 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; s->has_b_frames= !s->low_delay;
} else if (s->h263_intel) { } else if (s->h263_intel) {
ret = intel_h263_decode_picture_header(s); ret = intel_h263_decode_picture_header(s);
......
...@@ -624,7 +624,9 @@ void h263_encode_init(MpegEncContext *s); ...@@ -624,7 +624,9 @@ void h263_encode_init(MpegEncContext *s);
void h263_decode_init_vlc(MpegEncContext *s); void h263_decode_init_vlc(MpegEncContext *s);
int h263_decode_picture_header(MpegEncContext *s); int h263_decode_picture_header(MpegEncContext *s);
int ff_h263_decode_gob_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 intel_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]);
......
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