X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg4videodec.c;h=2807d506ee9e09519773d3282354d3639ead71de;hb=2d1b6fb72bd3d37798d448ba32ba85ee0eabd9e3;hp=c0d9f8fe3c37d149f785559db80329a06af87854;hpb=4f18f1b089035a99d8e2027d65dea03e5d4de659;p=ffmpeg diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index c0d9f8fe3c3..2807d506ee9 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3,26 +3,27 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mpegvideo.h" #include "mpeg4video.h" #include "h263.h" +#include "thread.h" // The defines below define the number of bits that are read at once for // reading vlc values. Changing these may improve speed and data cache needs @@ -54,7 +55,7 @@ void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, { int i; int16_t *ac_val, *ac_val1; - int8_t * const qscale_table= s->current_picture.qscale_table; + int8_t * const qscale_table = s->current_picture.f.qscale_table; /* find prediction */ ac_val = s->ac_val[0][0] + s->block_index[n] * 16; @@ -117,7 +118,7 @@ static inline int mpeg4_is_resync(MpegEncContext *s){ } while(v<=0xFF){ - if(s->pict_type==FF_B_TYPE || (v>>(8-s->pict_type)!=1) || s->partitioned_frame) + if(s->pict_type==AV_PICTURE_TYPE_B || (v>>(8-s->pict_type)!=1) || s->partitioned_frame) break; skip_bits(&s->gb, 8+s->pict_type); bits_count+= 8+s->pict_type; @@ -372,8 +373,14 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s) av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); return -1; } - if(s->pict_type == FF_B_TYPE){ - while(s->next_picture.mbskip_table[ s->mb_index2xy[ mb_num ] ]) mb_num++; + if(s->pict_type == AV_PICTURE_TYPE_B){ + int mb_x = 0, mb_y = 0; + + while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) { + if (!mb_x) ff_thread_await_progress((AVFrame*)s->next_picture_ptr, mb_y++, 0); + mb_num++; + if (++mb_x == s->mb_width) mb_x = 0; + } if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where already decoded } @@ -390,14 +397,13 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s) header_extension= get_bits1(&s->gb); } if(header_extension){ - int time_increment; int time_incr=0; while (get_bits1(&s->gb) != 0) time_incr++; check_marker(&s->gb, "before time_increment in video packed header"); - time_increment= get_bits(&s->gb, s->time_increment_bits); + skip_bits(&s->gb, s->time_increment_bits); /* time_increment */ check_marker(&s->gb, "before vop_coding_type in video packed header"); skip_bits(&s->gb, 2); /* vop coding type */ @@ -406,20 +412,20 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s) if(s->shape != BIN_ONLY_SHAPE){ skip_bits(&s->gb, 3); /* intra dc vlc threshold */ //FIXME don't just ignore everything - if(s->pict_type == FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ + if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ mpeg4_decode_sprite_trajectory(s, &s->gb); av_log(s->avctx, AV_LOG_ERROR, "untested\n"); } //FIXME reduced res stuff here - if (s->pict_type != FF_I_TYPE) { + if (s->pict_type != AV_PICTURE_TYPE_I) { int f_code = get_bits(&s->gb, 3); /* fcode_for */ if(f_code==0){ av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n"); } } - if (s->pict_type == FF_B_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_B) { int b_code = get_bits(&s->gb, 3); if(b_code==0){ av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n"); @@ -548,7 +554,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) s->first_slice_line=0; - if(s->pict_type==FF_I_TYPE){ + if(s->pict_type==AV_PICTURE_TYPE_I){ int i; do{ @@ -564,13 +570,13 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ }while(cbpc == 8); s->cbp_table[xy]= cbpc & 3; - s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; s->mb_intra = 1; if(cbpc & 4) { ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); } - s->current_picture.qscale_table[xy]= s->qscale; + s->current_picture.f.qscale_table[xy]= s->qscale; s->mbintra_table[xy]= 1; for(i=0; i<6; i++){ @@ -586,7 +592,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ s->pred_dir_table[xy]= dir; }else{ /* P/S_TYPE */ int mx, my, pred_x, pred_y, bits; - int16_t * const mot_val= s->current_picture.motion_val[0][s->block_index[0]]; + int16_t * const mot_val = s->current_picture.f.motion_val[0][s->block_index[0]]; const int stride= s->b8_stride*2; try_again: @@ -597,12 +603,12 @@ try_again: skip_bits1(&s->gb); if(bits&0x10000){ /* skip mb */ - if(s->pict_type==FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ - s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ + s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; mx= get_amv(s, 0); my= get_amv(s, 1); }else{ - s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; mx=my=0; } mot_val[0 ]= mot_val[2 ]= @@ -628,7 +634,7 @@ try_again: s->mb_intra = ((cbpc & 4) != 0); if(s->mb_intra){ - s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; s->mbintra_table[xy]= 1; mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= 0; @@ -638,7 +644,7 @@ try_again: if(s->mbintra_table[xy]) ff_clean_intra_table_entries(s); - if(s->pict_type==FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) + if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) s->mcsel= get_bits1(&s->gb); else s->mcsel= 0; @@ -654,11 +660,11 @@ try_again: my = h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; - s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; } else { mx = get_amv(s, 0); my = get_amv(s, 1); - s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; } mot_val[0 ]= mot_val[2 ] = @@ -667,7 +673,7 @@ try_again: mot_val[1+stride]= mot_val[3+stride]= my; } else { int i; - s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = h263_decode_motion(s, pred_x, s->f_code); @@ -710,7 +716,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) s->first_slice_line=0; - if(s->pict_type==FF_I_TYPE){ + if(s->pict_type==AV_PICTURE_TYPE_I){ int ac_pred= get_bits1(&s->gb); int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); if(cbpy<0){ @@ -719,9 +725,9 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ } s->cbp_table[xy]|= cbpy<<2; - s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; }else{ /* P || S_TYPE */ - if(IS_INTRA(s->current_picture.mb_type[xy])){ + if (IS_INTRA(s->current_picture.f.mb_type[xy])) { int dir=0,i; int ac_pred = get_bits1(&s->gb); int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); @@ -734,7 +740,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ if(s->cbp_table[xy] & 8) { ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); } - s->current_picture.qscale_table[xy]= s->qscale; + s->current_picture.f.qscale_table[xy] = s->qscale; for(i=0; i<6; i++){ int dc_pred_dir; @@ -748,10 +754,10 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ } s->cbp_table[xy]&= 3; //remove dquant s->cbp_table[xy]|= cbpy<<2; - s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; s->pred_dir_table[xy]= dir; - }else if(IS_SKIP(s->current_picture.mb_type[xy])){ - s->current_picture.qscale_table[xy]= s->qscale; + } else if (IS_SKIP(s->current_picture.f.mb_type[xy])) { + s->current_picture.f.qscale_table[xy] = s->qscale; s->cbp_table[xy]= 0; }else{ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); @@ -764,7 +770,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ if(s->cbp_table[xy] & 8) { ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); } - s->current_picture.qscale_table[xy]= s->qscale; + s->current_picture.f.qscale_table[xy] = s->qscale; s->cbp_table[xy]&= 3; //remove dquant s->cbp_table[xy]|= (cbpy^0xf)<<2; @@ -784,8 +790,8 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ int ff_mpeg4_decode_partitions(MpegEncContext *s) { int mb_num; - const int part_a_error= s->pict_type==FF_I_TYPE ? (DC_ERROR|MV_ERROR) : MV_ERROR; - const int part_a_end = s->pict_type==FF_I_TYPE ? (DC_END |MV_END) : MV_END; + const int part_a_error= s->pict_type==AV_PICTURE_TYPE_I ? (DC_ERROR|MV_ERROR) : MV_ERROR; + const int part_a_end = s->pict_type==AV_PICTURE_TYPE_I ? (DC_END |MV_END) : MV_END; mb_num= mpeg4_decode_partition_a(s); if(mb_num<0){ @@ -801,7 +807,7 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) s->mb_num_left= mb_num; - if(s->pict_type==FF_I_TYPE){ + if(s->pict_type==AV_PICTURE_TYPE_I){ while(show_bits(&s->gb, 9) == 1) skip_bits(&s->gb, 9); if(get_bits_long(&s->gb, 19)!=DC_MARKER){ @@ -819,11 +825,11 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end); if( mpeg4_decode_partition_b(s, mb_num) < 0){ - if(s->pict_type==FF_P_TYPE) + if(s->pict_type==AV_PICTURE_TYPE_P) ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, DC_ERROR); return -1; }else{ - if(s->pict_type==FF_P_TYPE) + if(s->pict_type==AV_PICTURE_TYPE_P) ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, DC_END); } @@ -984,28 +990,6 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, SKIP_COUNTER(re, &s->gb, 1+12+1); } -#if 0 - if(s->error_recognition >= FF_ER_COMPLIANT){ - const int abs_level= FFABS(level); - if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ - const int run1= run - rl->max_run[last][abs_level] - 1; - if(abs_level <= rl->max_level[last][run]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); - return -1; - } - if(s->error_recognition > FF_ER_COMPLIANT){ - if(abs_level <= rl->max_level[last][run]*2){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); - return -1; - } - if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); - return -1; - } - } - } - } -#endif if (level>0) level= level * qmul + qadd; else level= level * qmul - qadd; @@ -1023,12 +1007,7 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, if(last) i+=192; } else { /* second escape */ -#if MIN_CACHE_BITS < 20 - LAST_SKIP_BITS(re, &s->gb, 2); - UPDATE_CACHE(re, &s->gb); -#else SKIP_BITS(re, &s->gb, 2); -#endif GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -1036,12 +1015,7 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, } } else { /* first escape */ -#if MIN_CACHE_BITS < 19 - LAST_SKIP_BITS(re, &s->gb, 1); - UPDATE_CACHE(re, &s->gb); -#else SKIP_BITS(re, &s->gb, 1); -#endif GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); i+= run; level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing @@ -1095,20 +1069,20 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) int cbp, mb_type; const int xy= s->mb_x + s->mb_y*s->mb_stride; - mb_type= s->current_picture.mb_type[xy]; + mb_type = s->current_picture.f.mb_type[xy]; cbp = s->cbp_table[xy]; s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold; - if(s->current_picture.qscale_table[xy] != s->qscale){ - ff_set_qscale(s, s->current_picture.qscale_table[xy] ); + if (s->current_picture.f.qscale_table[xy] != s->qscale) { + ff_set_qscale(s, s->current_picture.f.qscale_table[xy]); } - if (s->pict_type == FF_P_TYPE || s->pict_type==FF_S_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) { int i; for(i=0; i<4; i++){ - s->mv[0][i][0] = s->current_picture.motion_val[0][ s->block_index[i] ][0]; - s->mv[0][i][1] = s->current_picture.motion_val[0][ s->block_index[i] ][1]; + s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0]; + s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1]; } s->mb_intra = IS_INTRA(mb_type); @@ -1118,7 +1092,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) s->block_last_index[i] = -1; s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - if(s->pict_type==FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ + if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ s->mcsel=1; s->mb_skipped = 0; }else{ @@ -1126,7 +1100,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) s->mb_skipped = 1; } }else if(s->mb_intra){ - s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); + s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]); }else if(!s->mb_intra){ // s->mcsel= 0; //FIXME do we need to init that @@ -1139,7 +1113,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) } } else { /* I-Frame */ s->mb_intra = 1; - s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); + s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]); } if (!IS_SKIP(mb_type)) { @@ -1182,7 +1156,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, assert(s->h263_pred); - if (s->pict_type == FF_P_TYPE || s->pict_type==FF_S_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) { do{ if (get_bits1(&s->gb)) { /* skip mb */ @@ -1191,15 +1165,15 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->block_last_index[i] = -1; s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - if(s->pict_type==FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ - s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ + s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; s->mcsel=1; s->mv[0][0][0]= get_amv(s, 0); s->mv[0][0][1]= get_amv(s, 1); s->mb_skipped = 0; }else{ - s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; s->mcsel=0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; @@ -1219,7 +1193,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mb_intra = ((cbpc & 4) != 0); if (s->mb_intra) goto intra; - if(s->pict_type==FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) + if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) s->mcsel= get_bits1(&s->gb); else s->mcsel= 0; cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F; @@ -1234,7 +1208,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; if ((cbpc & 16) == 0) { if(s->mcsel){ - s->current_picture.mb_type[xy]= MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 global motion prediction */ s->mv_type = MV_TYPE_16X16; mx= get_amv(s, 0); @@ -1242,7 +1216,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][0] = mx; s->mv[0][0][1] = my; }else if((!s->progressive_sequence) && get_bits1(&s->gb)){ - s->current_picture.mb_type[xy]= MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; + s->current_picture.f.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; /* 16x8 field motion prediction */ s->mv_type= MV_TYPE_FIELD; @@ -1264,7 +1238,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][i][1] = my; } }else{ - s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; h263_pred_motion(s, 0, 0, &pred_x, &pred_y); @@ -1281,7 +1255,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][1] = my; } } else { - s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); @@ -1298,7 +1272,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, mot_val[1] = my; } } - } else if(s->pict_type==FF_B_TYPE) { + } else if(s->pict_type==AV_PICTURE_TYPE_B) { int modb1; // first bit of modb int modb2; // second bit of modb int mb_type; @@ -1313,10 +1287,12 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->last_mv[i][1][0]= s->last_mv[i][1][1]= 0; } + + ff_thread_await_progress((AVFrame*)s->next_picture_ptr, s->mb_y, 0); } /* if we skipped it in the future P Frame than skip it now too */ - s->mb_skipped= s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC + s->mb_skipped = s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC if(s->mb_skipped){ /* skip mb */ @@ -1329,7 +1305,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][1] = 0; s->mv[1][0][0] = 0; s->mv[1][0][1] = 0; - s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; goto end; } @@ -1435,7 +1411,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; mb_type |= ff_mpeg4_set_direct_mv(s, mx, my); } - s->current_picture.mb_type[xy]= mb_type; + s->current_picture.f.mb_type[xy] = mb_type; } else { /* I-Frame */ do{ cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); @@ -1450,9 +1426,9 @@ static int mpeg4_decode_mb(MpegEncContext *s, intra: s->ac_pred = get_bits1(&s->gb); if(s->ac_pred) - s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED; + s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED; else - s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); if(cbpy<0){ @@ -1492,7 +1468,13 @@ end: if(s->codec_id==CODEC_ID_MPEG4){ if(mpeg4_is_resync(s)){ const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; - if(s->pict_type==FF_B_TYPE && s->next_picture.mbskip_table[xy + delta]) + + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) { + ff_thread_await_progress((AVFrame*)s->next_picture_ptr, + (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0); + } + + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) return SLICE_OK; return SLICE_END; } @@ -1504,18 +1486,35 @@ end: static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){ int hours, minutes, seconds; + unsigned time_code = show_bits(gb, 18); + + if (time_code & 0x40) { /* marker_bit */ + hours = time_code >> 13; + minutes = time_code >> 7 & 0x3f; + seconds = time_code & 0x3f; + s->time_base = seconds + 60*(minutes + 60*hours); + skip_bits(gb, 20); /* time_code, closed_gov, broken_link */ + } else { + av_log(s->avctx, AV_LOG_WARNING, "GOP header missing marker_bit\n"); + } - hours= get_bits(gb, 5); - minutes= get_bits(gb, 6); - skip_bits1(gb); - seconds= get_bits(gb, 6); + return 0; +} - s->time_base= seconds + 60*(minutes + 60*hours); +static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){ + int profile_and_level_indication; - skip_bits1(gb); - skip_bits1(gb); + profile_and_level_indication = get_bits(gb, 8); - return 0; + s->avctx->profile = (profile_and_level_indication & 0xf0) >> 4; + s->avctx->level = (profile_and_level_indication & 0x0f); + + // for Simple profile, level 0 + if (s->avctx->profile == 0 && s->avctx->level == 8) { + s->avctx->level = 0; + } + + return 0; } static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ @@ -1795,16 +1794,14 @@ no_cplx_est: if (s->scalability) { GetBitContext bak= *gb; - int ref_layer_id; - int ref_layer_sampling_dir; int h_sampling_factor_n; int h_sampling_factor_m; int v_sampling_factor_n; int v_sampling_factor_m; s->hierachy_type= get_bits1(gb); - ref_layer_id= get_bits(gb, 4); - ref_layer_sampling_dir= get_bits1(gb); + skip_bits(gb, 4); /* ref_layer_id */ + skip_bits1(gb); /* ref_layer_sampling_dir */ h_sampling_factor_n= get_bits(gb, 5); h_sampling_factor_m= get_bits(gb, 5); v_sampling_factor_n= get_bits(gb, 5); @@ -1857,7 +1854,7 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ } } - /* ffmpeg detection */ + /* libavcodec detection */ e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3; if(e!=4) e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); @@ -1887,13 +1884,13 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ int time_incr, time_increment; - s->pict_type = get_bits(gb, 2) + FF_I_TYPE; /* pict type: I = 0 , P = 1 */ - if(s->pict_type==FF_B_TYPE && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){ + s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */ + if(s->pict_type==AV_PICTURE_TYPE_B && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){ av_log(s->avctx, AV_LOG_ERROR, "low_delay flag incorrectly, clearing it\n"); s->low_delay=0; } - s->partitioned_frame= s->data_partitioning && s->pict_type!=FF_B_TYPE; + s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B; if(s->partitioned_frame) s->decode_mb= mpeg4_decode_partitioned_mb; else @@ -1909,8 +1906,8 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ av_log(s->avctx, AV_LOG_ERROR, "hmm, seems the headers are not complete, trying to guess time_increment_bits\n"); for(s->time_increment_bits=1 ;s->time_increment_bits<16; s->time_increment_bits++){ - if ( s->pict_type == FF_P_TYPE - || (s->pict_type == FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE)) { + if ( s->pict_type == AV_PICTURE_TYPE_P + || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) { if((show_bits(gb, s->time_increment_bits+6)&0x37) == 0x30) break; }else if((show_bits(gb, s->time_increment_bits+5)&0x1F) == 0x18) break; @@ -1922,7 +1919,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further else time_increment= get_bits(gb, s->time_increment_bits); - if(s->pict_type!=FF_B_TYPE){ + if(s->pict_type!=AV_PICTURE_TYPE_B){ s->last_time_base= s->time_base; s->time_base+= time_incr; s->time= s->time_base*s->avctx->time_base.den + time_increment; @@ -1958,11 +1955,12 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } if(s->avctx->time_base.num) - s->current_picture_ptr->pts= (s->time + s->avctx->time_base.num/2) / s->avctx->time_base.num; + s->current_picture_ptr->f.pts = (s->time + s->avctx->time_base.num / 2) / s->avctx->time_base.num; else - s->current_picture_ptr->pts= AV_NOPTS_VALUE; + s->current_picture_ptr->f.pts = AV_NOPTS_VALUE; if(s->avctx->debug&FF_DEBUG_PTS) - av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n", s->current_picture_ptr->pts); + av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n", + s->current_picture_ptr->f.pts); check_marker(gb, "before vop_coded"); @@ -1972,8 +1970,8 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n"); return FRAME_SKIPPED; } - if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == FF_P_TYPE - || (s->pict_type == FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) { + if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == AV_PICTURE_TYPE_P + || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE))) { /* rounding type for motion estimation */ s->no_rounding = get_bits1(gb); } else { @@ -1982,16 +1980,14 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ //FIXME reduced res stuff if (s->shape != RECT_SHAPE) { - if (s->vol_sprite_usage != 1 || s->pict_type != FF_I_TYPE) { - int width, height, hor_spat_ref, ver_spat_ref; - - width = get_bits(gb, 13); + if (s->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) { + skip_bits(gb, 13); /* width */ skip_bits1(gb); /* marker */ - height = get_bits(gb, 13); + skip_bits(gb, 13); /* height */ skip_bits1(gb); /* marker */ - hor_spat_ref = get_bits(gb, 13); /* hor_spat_ref */ + skip_bits(gb, 13); /* hor_spat_ref */ skip_bits1(gb); /* marker */ - ver_spat_ref = get_bits(gb, 13); /* ver_spat_ref */ + skip_bits(gb, 13); /* ver_spat_ref */ } skip_bits1(gb); /* change_CR_disable */ @@ -2003,9 +1999,9 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ if (s->shape != BIN_ONLY_SHAPE) { skip_bits_long(gb, s->cplx_estimation_trash_i); - if(s->pict_type != FF_I_TYPE) + if(s->pict_type != AV_PICTURE_TYPE_I) skip_bits_long(gb, s->cplx_estimation_trash_p); - if(s->pict_type == FF_B_TYPE) + if(s->pict_type == AV_PICTURE_TYPE_B) skip_bits_long(gb, s->cplx_estimation_trash_b); s->intra_dc_threshold= mpeg4_dc_threshold[ get_bits(gb, 3) ]; @@ -2028,7 +2024,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); } - if(s->pict_type == FF_S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ + if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ mpeg4_decode_sprite_trajectory(s, gb); if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n"); if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); @@ -2041,7 +2037,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ return -1; // makes no sense to continue, as there is nothing left from the image then } - if (s->pict_type != FF_I_TYPE) { + if (s->pict_type != AV_PICTURE_TYPE_I) { s->f_code = get_bits(gb, 3); /* fcode_for */ if(s->f_code==0){ av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (f_code=0)\n"); @@ -2050,7 +2046,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ }else s->f_code=1; - if (s->pict_type == FF_B_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_B) { s->b_code = get_bits(gb, 3); }else s->b_code=1; @@ -2058,14 +2054,14 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ if(s->avctx->debug&FF_DEBUG_PICT_INFO){ av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d\n", s->qscale, s->f_code, s->b_code, - s->pict_type == FF_I_TYPE ? "I" : (s->pict_type == FF_P_TYPE ? "P" : (s->pict_type == FF_B_TYPE ? "B" : "S")), + s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first, s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points, s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold, s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b); } if(!s->scalability){ - if (s->shape!=RECT_SHAPE && s->pict_type!=FF_I_TYPE) { + if (s->shape!=RECT_SHAPE && s->pict_type!=AV_PICTURE_TYPE_I) { skip_bits1(gb); // vop shape coding type } }else{ @@ -2081,7 +2077,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ /* detect buggy encoders which don't set the low_delay flag (divx4/xvid/opendivx)*/ // note we cannot detect divx5 without b-frames easily (although it's buggy too) if(s->vo_type==0 && s->vol_control_parameters==0 && s->divx_version==-1 && s->picture_number==0){ - av_log(s->avctx, AV_LOG_ERROR, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); + av_log(s->avctx, AV_LOG_WARNING, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); s->low_delay=1; } @@ -2105,7 +2101,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ */ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) { - int startcode, v; + unsigned startcode, v; /* search next start code */ align_get_bits(gb); @@ -2120,7 +2116,7 @@ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) for(;;) { if(get_bits_count(gb) >= gb->size_in_bits){ if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0)){ - av_log(s->avctx, AV_LOG_ERROR, "frame skip %d\n", gb->size_in_bits); + av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits); return FRAME_SKIPPED; //divx bug }else return -1; //end of stream @@ -2175,6 +2171,9 @@ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) else if(startcode == GOP_STARTCODE){ mpeg4_decode_gop_header(s, gb); } + else if(startcode == VOS_STARTCODE){ + mpeg4_decode_profile_level(s, gb); + } else if(startcode == VOP_STARTCODE){ break; } @@ -2235,34 +2234,53 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -AVCodec mpeg4_decoder = { - "mpeg4", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(MpegEncContext), - decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, +static const AVProfile mpeg4_video_profiles[] = { + { FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" }, + { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" }, + { FF_PROFILE_MPEG4_CORE, "Core Profile" }, + { FF_PROFILE_MPEG4_MAIN, "Main Profile" }, + { FF_PROFILE_MPEG4_N_BIT, "N-bit Profile" }, + { FF_PROFILE_MPEG4_SCALABLE_TEXTURE, "Scalable Texture Profile" }, + { FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION, "Simple Face Animation Profile" }, + { FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE, "Basic Animated Texture Profile" }, + { FF_PROFILE_MPEG4_HYBRID, "Hybrid Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_REAL_TIME, "Advanced Real Time Simple Profile" }, + { FF_PROFILE_MPEG4_CORE_SCALABLE, "Code Scalable Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_CODING, "Advanced Coding Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_CORE, "Advanced Core Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" }, + { FF_PROFILE_MPEG4_SIMPLE_STUDIO, "Simple Studio Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" }, +}; + +AVCodec ff_mpeg4_decoder = { + .name = "mpeg4", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG4, + .priv_data_size = sizeof(MpegEncContext), + .init = decode_init, + .close = ff_h263_decode_end, + .decode = ff_h263_decode_frame, + .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS, .flush= ff_mpeg_flush, .max_lowres= 3, .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), .pix_fmts= ff_hwaccel_pixfmt_list_420, + .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles), + .update_thread_context= ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context) }; #if CONFIG_MPEG4_VDPAU_DECODER -AVCodec mpeg4_vdpau_decoder = { - "mpeg4_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(MpegEncContext), - decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, +AVCodec ff_mpeg4_vdpau_decoder = { + .name = "mpeg4_vdpau", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG4, + .priv_data_size = sizeof(MpegEncContext), + .init = decode_init, + .close = ff_h263_decode_end, + .decode = ff_h263_decode_frame, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"), .pix_fmts= (const enum PixelFormat[]){PIX_FMT_VDPAU_MPEG4, PIX_FMT_NONE}, };