X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg12.c;h=636ae067c849eb4c83bae4c5780ec36aa015af26;hb=5f000d5f386601e2316a243c3e41536dfbbccf4d;hp=0f9f649c9a37784e15c43097984a54af5055d9e7;hpb=054480a57b9b5cc751f482aa8b22c100ffc340d1;p=ffmpeg diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 0f9f649c9a3..636ae067c84 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1,6 +1,6 @@ /* * MPEG-1/2 decoder - * Copyright (c) 2000,2001 Fabrice Bellard. + * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * * This file is part of FFmpeg. @@ -21,11 +21,12 @@ */ /** - * @file mpeg12.c + * @file libavcodec/mpeg12.c * MPEG-1/2 decoder */ //#define DEBUG +#include "internal.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -34,6 +35,8 @@ #include "mpeg12data.h" #include "mpeg12decdata.h" #include "bytestream.h" +#include "vdpau_internal.h" +#include "xvmc_internal.h" //#undef NDEBUG //#include @@ -45,10 +48,10 @@ #define MB_PTYPE_VLC_BITS 6 #define MB_BTYPE_VLC_BITS 6 -static inline int mpeg1_decode_block_inter(MpegEncContext *s, +static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); -static inline int mpeg1_decode_block_intra(MpegEncContext *s, +static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); @@ -63,14 +66,6 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); static void exchange_uv(MpegEncContext *s); -extern int XVMC_field_start(MpegEncContext *s, AVCodecContext *avctx); -extern int XVMC_field_end(MpegEncContext *s); -extern void XVMC_pack_pblocks(MpegEncContext *s,int cbp); -extern void XVMC_init_block(MpegEncContext *s);//set s->block - -static const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,PIX_FMT_NONE}; -static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,PIX_FMT_NONE}; -static const enum PixelFormat pixfmt_yuv_444[]= {PIX_FMT_YUV444P,PIX_FMT_NONE}; static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_XVMC_MPEG2_MC, @@ -148,7 +143,7 @@ static VLC mb_ptype_vlc; static VLC mb_btype_vlc; static VLC mb_pat_vlc; -av_cold void ff_init_vlcs(void) +av_cold void ff_mpeg12_init_vlcs(void) { static int done = 0; @@ -306,30 +301,28 @@ static int mpeg_decode_mb(MpegEncContext *s, }else memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */ s->mb_intra = 1; -#ifdef HAVE_XVMC //if 1, we memcpy blocks in xvmcvideo - if(s->avctx->xvmc_acceleration > 1){ - XVMC_pack_pblocks(s,-1);//inter are always full blocks + if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){ + ff_xvmc_pack_pblocks(s,-1);//inter are always full blocks if(s->swap_uv){ exchange_uv(s); } } -#endif if (s->codec_id == CODEC_ID_MPEG2VIDEO) { if(s->flags2 & CODEC_FLAG2_FAST){ for(i=0;i<6;i++) { - mpeg2_fast_decode_block_intra(s, s->pblocks[i], i); + mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i); } }else{ for(i=0;ipblocks[i], i) < 0) + if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0) return -1; } } } else { for(i=0;i<6;i++) { - if (mpeg1_decode_block_intra(s, s->pblocks[i], i) < 0) + if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0) return -1; } } @@ -455,18 +448,20 @@ static int mpeg_decode_mb(MpegEncContext *s, for(i=0;i<2;i++) { if (USES_LIST(mb_type, i)) { int dmx, dmy, mx, my, m; + const int my_shift= s->picture_structure == PICT_FRAME; + mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); s->last_mv[i][0][0] = mx; s->last_mv[i][1][0] = mx; dmx = get_dmv(s); my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][0][1] >> 1); + s->last_mv[i][0][1] >> my_shift); dmy = get_dmv(s); - s->last_mv[i][0][1] = my<<1; - s->last_mv[i][1][1] = my<<1; + s->last_mv[i][0][1] = my<last_mv[i][1][1] = my<mv[i][0][0] = mx; s->mv[i][0][1] = my; @@ -519,21 +514,19 @@ static int mpeg_decode_mb(MpegEncContext *s, return -1; } -#ifdef HAVE_XVMC //if 1, we memcpy blocks in xvmcvideo - if(s->avctx->xvmc_acceleration > 1){ - XVMC_pack_pblocks(s,cbp); + if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){ + ff_xvmc_pack_pblocks(s,cbp); if(s->swap_uv){ exchange_uv(s); } } -#endif if (s->codec_id == CODEC_ID_MPEG2VIDEO) { if(s->flags2 & CODEC_FLAG2_FAST){ for(i=0;i<6;i++) { if(cbp & 32) { - mpeg2_fast_decode_block_non_intra(s, s->pblocks[i], i); + mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i); } else { s->block_last_index[i] = -1; } @@ -544,7 +537,7 @@ static int mpeg_decode_mb(MpegEncContext *s, for(i=0;ipblocks[i], i) < 0) + if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; @@ -556,7 +549,7 @@ static int mpeg_decode_mb(MpegEncContext *s, if(s->flags2 & CODEC_FLAG2_FAST){ for(i=0;i<6;i++) { if (cbp & 32) { - mpeg1_fast_decode_block_inter(s, s->pblocks[i], i); + mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i); } else { s->block_last_index[i] = -1; } @@ -565,7 +558,7 @@ static int mpeg_decode_mb(MpegEncContext *s, }else{ for(i=0;i<6;i++) { if (cbp & 32) { - if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0) + if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; @@ -635,7 +628,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, dc = s->last_dc[component]; dc += diff; s->last_dc[component] = dc; - block[0] = dc<<3; + block[0] = dc*quant_matrix[0]; dprintf(s->avctx, "dc=%d diff=%d\n", dc, diff); i = 0; { @@ -689,6 +682,13 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, return 0; } +int ff_mpeg1_decode_block_intra(MpegEncContext *s, + DCTELEM *block, + int n) +{ + return mpeg1_decode_block_intra(s, block, n); +} + static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n) @@ -1172,9 +1172,9 @@ typedef struct Mpeg1Context { int slice_count; int swap_uv;//indicate VCR2 int save_aspect_info; - int save_width, save_height; + int save_width, save_height, save_progressive_seq; AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator - + int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame? } Mpeg1Context; static av_cold int mpeg_decode_init(AVCodecContext *avctx) @@ -1194,12 +1194,17 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx) s->mpeg_enc_ctx.flags= avctx->flags; s->mpeg_enc_ctx.flags2= avctx->flags2; ff_mpeg12_common_init(&s->mpeg_enc_ctx); - ff_init_vlcs(); + ff_mpeg12_init_vlcs(); s->mpeg_enc_ctx_allocated = 0; s->mpeg_enc_ctx.picture_number = 0; s->repeat_field = 0; s->mpeg_enc_ctx.codec_id= avctx->codec->id; + avctx->color_range= AVCOL_RANGE_MPEG; + if (avctx->codec->id == CODEC_ID_MPEG1VIDEO) + avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; + else + avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; return 0; } @@ -1215,6 +1220,27 @@ static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, } } +static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){ + Mpeg1Context *s1 = avctx->priv_data; + MpegEncContext *s = &s1->mpeg_enc_ctx; + + if(avctx->xvmc_acceleration) + return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); + else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){ + if(avctx->codec_id == CODEC_ID_MPEG1VIDEO) + return PIX_FMT_VDPAU_MPEG1; + else + return PIX_FMT_VDPAU_MPEG2; + }else{ + if(s->chroma_format < 2) + return avctx->get_format(avctx,ff_hwaccel_pixfmt_list_420); + else if(s->chroma_format == 2) + return PIX_FMT_YUV422P; + else + return PIX_FMT_YUV444P; + } +} + /* Call this function when we know all parameters. * It may be called in different places for MPEG-1 and MPEG-2. */ static int mpeg_decode_postinit(AVCodecContext *avctx){ @@ -1229,6 +1255,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ s1->save_width != s->width || s1->save_height != s->height || s1->save_aspect_info != s->aspect_ratio_info|| + s1->save_progressive_seq != s->progressive_sequence || 0) { @@ -1247,30 +1274,35 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ s1->save_aspect_info = s->aspect_ratio_info; s1->save_width = s->width; s1->save_height = s->height; + s1->save_progressive_seq = s->progressive_sequence; /* low_delay may be forced, in this case we will have B-frames * that behave like P-frames. */ avctx->has_b_frames = !(s->low_delay); - if(avctx->sub_id==1){//s->codec_id==avctx->codec_id==CODEC_ID + assert((avctx->sub_id==1) == (avctx->codec_id==CODEC_ID_MPEG1VIDEO)); + if(avctx->codec_id==CODEC_ID_MPEG1VIDEO){ //MPEG-1 fps avctx->time_base.den= ff_frame_rate_tab[s->frame_rate_index].num; avctx->time_base.num= ff_frame_rate_tab[s->frame_rate_index].den; //MPEG-1 aspect avctx->sample_aspect_ratio= av_d2q( 1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255); - + avctx->ticks_per_frame=1; }else{//MPEG-2 //MPEG-2 fps av_reduce( &s->avctx->time_base.den, &s->avctx->time_base.num, - ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num, + ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2, ff_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den, 1<<30); + avctx->ticks_per_frame=2; //MPEG-2 aspect if(s->aspect_ratio_info > 1){ - if( (s1->pan_scan.width == 0 )||(s1->pan_scan.height == 0) ){ + //we ignore the spec here as reality does not match the spec, see for example + // res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg + if( (s1->pan_scan.width == 0 )||(s1->pan_scan.height == 0) || 1){ s->avctx->sample_aspect_ratio= av_div_q( ff_mpeg2_aspect[s->aspect_ratio_info], @@ -1289,21 +1321,12 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ } }//MPEG-2 - if(avctx->xvmc_acceleration){ - avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); - }else{ - if(s->chroma_format < 2){ - avctx->pix_fmt = avctx->get_format(avctx,pixfmt_yuv_420); - }else - if(s->chroma_format == 2){ - avctx->pix_fmt = avctx->get_format(avctx,pixfmt_yuv_422); - }else - if(s->chroma_format > 2){ - avctx->pix_fmt = avctx->get_format(avctx,pixfmt_yuv_444); - } - } + avctx->pix_fmt = mpeg_get_pixelformat(avctx); + avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); //until then pix_fmt may be changed right after codec init - if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ) + if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || + avctx->hwaccel || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) if( avctx->idct_algo == FF_IDCT_AUTO ) avctx->idct_algo = FF_IDCT_SIMPLE; @@ -1331,9 +1354,6 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, MpegEncContext *s = &s1->mpeg_enc_ctx; int ref, f_code, vbv_delay; - if(mpeg_decode_postinit(s->avctx) < 0) - return -2; - init_get_bits(&s->gb, buf, buf_size*8); ref = get_bits(&s->gb, 10); /* temporal ref */ @@ -1345,7 +1365,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, if (s->pict_type == FF_P_TYPE || s->pict_type == FF_B_TYPE) { s->full_pel[0] = get_bits1(&s->gb); f_code = get_bits(&s->gb, 3); - if (f_code == 0 && avctx->error_resilience >= FF_ER_COMPLIANT) + if (f_code == 0 && avctx->error_recognition >= FF_ER_COMPLIANT) return -1; s->mpeg_f_code[0][0] = f_code; s->mpeg_f_code[0][1] = f_code; @@ -1353,7 +1373,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, if (s->pict_type == FF_B_TYPE) { s->full_pel[1] = get_bits1(&s->gb); f_code = get_bits(&s->gb, 3); - if (f_code == 0 && avctx->error_resilience >= FF_ER_COMPLIANT) + if (f_code == 0 && avctx->error_recognition >= FF_ER_COMPLIANT) return -1; s->mpeg_f_code[1][0] = f_code; s->mpeg_f_code[1][1] = f_code; @@ -1366,7 +1386,6 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, s->y_dc_scale = 8; s->c_dc_scale = 8; - s->first_slice = 1; return 0; } @@ -1414,9 +1433,9 @@ static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1) skip_bits(&s->gb, 3); /* video format */ color_description= get_bits1(&s->gb); if(color_description){ - skip_bits(&s->gb, 8); /* color primaries */ - skip_bits(&s->gb, 8); /* transfer_characteristics */ - skip_bits(&s->gb, 8); /* matrix_coefficients */ + s->avctx->color_primaries= get_bits(&s->gb, 8); + s->avctx->color_trc = get_bits(&s->gb, 8); + s->avctx->colorspace = get_bits(&s->gb, 8); } w= get_bits(&s->gb, 14); skip_bits(&s->gb, 1); //marker @@ -1464,51 +1483,58 @@ static void mpeg_decode_picture_display_extension(Mpeg1Context *s1) ); } -static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) -{ - int i, v, j; - - dprintf(s->avctx, "matrix extension\n"); +static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra){ + int i; - if (get_bits1(&s->gb)) { - for(i=0;i<64;i++) { - v = get_bits(&s->gb, 8); - j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - } - } - if (get_bits1(&s->gb)) { - for(i=0;i<64;i++) { - v = get_bits(&s->gb, 8); - j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; + for(i=0; i<64; i++) { + int j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; + int v = get_bits(&s->gb, 8); + if(v==0){ + av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n"); + return -1; } - } - if (get_bits1(&s->gb)) { - for(i=0;i<64;i++) { - v = get_bits(&s->gb, 8); - j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->chroma_intra_matrix[j] = v; - } - } - if (get_bits1(&s->gb)) { - for(i=0;i<64;i++) { - v = get_bits(&s->gb, 8); - j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->chroma_inter_matrix[j] = v; + if(intra && i==0 && v!=8){ + av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n"); + v= 8; // needed by pink.mpg / issue1046 } + matrix0[j] = v; + if(matrix1) + matrix1[j] = v; } + return 0; } -static void mpeg_decode_picture_coding_extension(MpegEncContext *s) +static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) { + dprintf(s->avctx, "matrix extension\n"); + + if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); + if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); + if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1); + if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0); +} + +static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) +{ + MpegEncContext *s= &s1->mpeg_enc_ctx; + s->full_pel[0] = s->full_pel[1] = 0; s->mpeg_f_code[0][0] = get_bits(&s->gb, 4); s->mpeg_f_code[0][1] = get_bits(&s->gb, 4); s->mpeg_f_code[1][0] = get_bits(&s->gb, 4); s->mpeg_f_code[1][1] = get_bits(&s->gb, 4); + if(!s->pict_type && s1->mpeg_enc_ctx_allocated){ + av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n"); + if(s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1]==15){ + if(s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15) + s->pict_type= FF_I_TYPE; + else + s->pict_type= FF_P_TYPE; + }else + s->pict_type= FF_B_TYPE; + s->current_picture.pict_type= s->pict_type; + s->current_picture.key_frame= s->pict_type == FF_I_TYPE; + } s->intra_dc_precision = get_bits(&s->gb, 2); s->picture_structure = get_bits(&s->gb, 2); s->top_field_first = get_bits1(&s->gb); @@ -1521,6 +1547,21 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) s->chroma_420_type = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb); + if(s->progressive_sequence && !s->progressive_frame){ + s->progressive_frame= 1; + av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n"); + } + + if(s->picture_structure==0 || (s->progressive_frame && s->picture_structure!=PICT_FRAME)){ + av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure); + s->picture_structure= PICT_FRAME; + } + + if(s->progressive_sequence && !s->frame_pred_frame_dct){ + av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n"); + s->frame_pred_frame_dct= 1; + } + if(s->picture_structure == PICT_FRAME){ s->first_field=0; s->v_edge_pos= 16*s->mb_height; @@ -1550,42 +1591,15 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) dprintf(s->avctx, "progressive_frame=%d\n", s->progressive_frame); } -static void mpeg_decode_extension(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int ext_type; - - init_get_bits(&s->gb, buf, buf_size*8); - - ext_type = get_bits(&s->gb, 4); - switch(ext_type) { - case 0x1: - mpeg_decode_sequence_extension(s1); - break; - case 0x2: - mpeg_decode_sequence_display_extension(s1); - break; - case 0x3: - mpeg_decode_quant_matrix_extension(s); - break; - case 0x7: - mpeg_decode_picture_display_extension(s1); - break; - case 0x8: - mpeg_decode_picture_coding_extension(s); - break; - } -} - static void exchange_uv(MpegEncContext *s){ - short * tmp = s->pblocks[4]; + DCTELEM (*tmp)[64]; + + tmp = s->pblocks[4]; s->pblocks[4] = s->pblocks[5]; s->pblocks[5] = tmp; } -static int mpeg_field_start(MpegEncContext *s){ +static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size){ AVCodecContext *avctx= s->avctx; Mpeg1Context *s1 = (Mpeg1Context*)s; @@ -1625,12 +1639,17 @@ static int mpeg_field_start(MpegEncContext *s){ } } } -#ifdef HAVE_XVMC + + if (avctx->hwaccel) { + if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) + return -1; + } + // MPV_frame_start will call this function too, // but we need to call it on every field - if(s->avctx->xvmc_acceleration) - XVMC_field_start(s,avctx); -#endif + if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) + if(ff_xvmc_field_start(s,avctx) < 0) + return -1; return 0; } @@ -1654,10 +1673,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, s->resync_mb_x= s->resync_mb_y= -1; - if (mb_y<= s->mb_height){ - av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s->mb_height); - return -1; - } + assert(mb_y < s->mb_height); init_get_bits(&s->gb, *buf, buf_size*8); @@ -1678,27 +1694,45 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, s->mb_x=0; - for(;;) { - int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n"); - return -1; - } - if (code >= 33) { - if (code == 33) { - s->mb_x += 33; + if(mb_y==0 && s->codec_tag == AV_RL32("SLIF")){ + skip_bits1(&s->gb); + }else{ + for(;;) { + int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); + if (code < 0){ + av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n"); + return -1; + } + if (code >= 33) { + if (code == 33) { + s->mb_x += 33; + } + /* otherwise, stuffing, nothing to do */ + } else { + s->mb_x += code; + break; } - /* otherwise, stuffing, nothing to do */ - } else { - s->mb_x += code; - break; } } + if(s->mb_x >= (unsigned)s->mb_width){ av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n"); return -1; } + if (avctx->hwaccel) { + const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */ + int start_code = -1; + buf_end = ff_find_start_code(buf_start + 2, *buf + buf_size, &start_code); + if (buf_end < *buf + buf_size) + buf_end -= 4; + s->mb_y = mb_y; + if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0) + return DECODE_SLICE_ERROR; + *buf = buf_end; + return DECODE_SLICE_OK; + } + s->resync_mb_x= s->mb_x; s->resync_mb_y= s->mb_y= mb_y; s->mb_skip_run= 0; @@ -1716,21 +1750,17 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, } for(;;) { -#ifdef HAVE_XVMC //If 1, we memcpy blocks in xvmcvideo. - if(s->avctx->xvmc_acceleration > 1) - XVMC_init_block(s);//set s->block -#endif + if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) + ff_xvmc_init_block(s);//set s->block if(mpeg_decode_mb(s, s->block) < 0) return -1; if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs - const int wrap = field_pic ? 2*s->b8_stride : s->b8_stride; + const int wrap = s->b8_stride; int xy = s->mb_x*2 + s->mb_y*2*wrap; int motion_x, motion_y, dir, i; - if(field_pic && !s->first_field) - xy += wrap/2; for(i=0; i<2; i++){ for(dir=0; dir<2; dir++){ @@ -1765,19 +1795,19 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, if (++s->mb_x >= s->mb_width) { const int mb_size= 16>>s->avctx->lowres; - ff_draw_horiz_band(s, mb_size*s->mb_y, mb_size); + ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size); s->mb_x = 0; - s->mb_y++; + s->mb_y += 1<mb_y<= s->mb_height){ - int left= s->gb.size_in_bits - get_bits_count(&s->gb); + if(s->mb_y >= s->mb_height){ + int left= get_bits_left(&s->gb); int is_d10= s->chroma_format==2 && s->pict_type==FF_I_TYPE && avctx->profile==0 && avctx->level==5 && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0 && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/; if(left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) - || (avctx->error_resilience >= FF_ER_AGGRESSIVE && left>8)){ + || (avctx->error_recognition >= FF_ER_AGGRESSIVE && left>8)){ av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23))); return -1; }else @@ -1834,7 +1864,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, s->mv[0][0][0] = s->mv[0][0][1] = 0; s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; - s->field_select[0][0]= s->picture_structure - 1; + s->field_select[0][0]= (s->picture_structure - 1) & 1; } else { /* if B type, reuse previous vectors and directions */ s->mv[0][0][0] = s->last_mv[0][0][0]; @@ -1852,11 +1882,12 @@ eos: // end of slice } static int slice_decode_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= arg; + MpegEncContext *s= *(void**)arg; const uint8_t *buf= s->gb.buffer; int mb_y= s->start_mb_y; + const int field_pic= s->picture_structure != PICT_FRAME; - s->error_count= 3*(s->end_mb_y - s->start_mb_y)*s->mb_width; + s->error_count= (3*(s->end_mb_y - s->start_mb_y)*s->mb_width) >> field_pic; for(;;){ uint32_t start_code; @@ -1898,10 +1929,14 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr) return 0; -#ifdef HAVE_XVMC - if(s->avctx->xvmc_acceleration) - XVMC_field_end(s); -#endif + if (s->avctx->hwaccel) { + if (s->avctx->hwaccel->end_frame(s->avctx) < 0) + av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n"); + } + + if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) + ff_xvmc_field_end(s); + /* end of slice reached */ if (/*s->mb_y<mb_height &&*/ !s->first_field) { /* end of image */ @@ -1948,7 +1983,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->aspect_ratio_info= get_bits(&s->gb, 4); if (s->aspect_ratio_info == 0) { av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); - if (avctx->error_resilience >= FF_ER_COMPLIANT) + if (avctx->error_recognition >= FF_ER_COMPLIANT) return -1; } s->frame_rate_index = get_bits(&s->gb, 4); @@ -1965,22 +2000,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, /* get matrix */ if (get_bits1(&s->gb)) { - for(i=0;i<64;i++) { - v = get_bits(&s->gb, 8); - if(v==0){ - av_log(s->avctx, AV_LOG_ERROR, "intra matrix damaged\n"); - return -1; - } - j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - } -#ifdef DEBUG - dprintf(s->avctx, "intra matrix present\n"); - for(i=0;i<64;i++) - dprintf(s->avctx, " %d", s->intra_matrix[s->dsp.idct_permutation[i]]); - dprintf(s->avctx, "\n"); -#endif + load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); } else { for(i=0;i<64;i++) { j = s->dsp.idct_permutation[i]; @@ -1990,22 +2010,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, } } if (get_bits1(&s->gb)) { - for(i=0;i<64;i++) { - v = get_bits(&s->gb, 8); - if(v==0){ - av_log(s->avctx, AV_LOG_ERROR, "inter matrix damaged\n"); - return -1; - } - j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; - } -#ifdef DEBUG - dprintf(s->avctx, "non-intra matrix present\n"); - for(i=0;i<64;i++) - dprintf(s->avctx, " %d", s->inter_matrix[s->dsp.idct_permutation[i]]); - dprintf(s->avctx, "\n"); -#endif + load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); } else { for(i=0;i<64;i++) { int j= s->dsp.idct_permutation[i]; @@ -2055,13 +2060,11 @@ static int vcr2_init_sequence(AVCodecContext *avctx) avctx->has_b_frames= 0; //true? s->low_delay= 1; - if(avctx->xvmc_acceleration){ - avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); - }else{ - avctx->pix_fmt = avctx->get_format(avctx,pixfmt_yuv_420); - } + avctx->pix_fmt = mpeg_get_pixelformat(avctx); + avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ) + if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) if( avctx->idct_algo == FF_IDCT_AUTO ) avctx->idct_algo = FF_IDCT_SIMPLE; @@ -2094,28 +2097,21 @@ static int vcr2_init_sequence(AVCodecContext *avctx) static void mpeg_decode_user_data(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) + const uint8_t *p, int buf_size) { - const uint8_t *p; - int len, flags; - p = buf; - len = buf_size; + const uint8_t *buf_end = p+buf_size; /* we parse the DTG active format information */ - if (len >= 5 && + if (buf_end - p >= 5 && p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') { - flags = p[4]; + int flags = p[4]; p += 5; - len -= 5; if (flags & 0x80) { /* skip event id */ - if (len < 2) - return; p += 2; - len -= 2; } if (flags & 0x40) { - if (len < 1) + if (buf_end - p < 1) return; avctx->dtg_active_format = p[0] & 0x0f; } @@ -2130,7 +2126,7 @@ static void mpeg_decode_gop(AVCodecContext *avctx, int drop_frame_flag; int time_code_hours, time_code_minutes; int time_code_seconds, time_code_pictures; - int closed_gop, broken_link; + int broken_link; init_get_bits(&s->gb, buf, buf_size*8); @@ -2142,7 +2138,7 @@ static void mpeg_decode_gop(AVCodecContext *avctx, time_code_seconds = get_bits(&s->gb,6); time_code_pictures = get_bits(&s->gb,6); - closed_gop = get_bits1(&s->gb); + s->closed_gop = get_bits1(&s->gb); /*broken_link indicate that after editing the reference frames of the first B-Frames after GOP I-Frame are missing (open gop)*/ @@ -2151,13 +2147,13 @@ static void mpeg_decode_gop(AVCodecContext *avctx, if(s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) closed_gop=%d broken_link=%d\n", time_code_hours, time_code_minutes, time_code_seconds, - time_code_pictures, closed_gop, broken_link); + time_code_pictures, s->closed_gop, broken_link); } /** * Finds the end of the current frame in the bitstream. * @return the position of the first byte of the next frame, or -1 */ -int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s) { int i; uint32_t state= pc->state; @@ -2205,6 +2201,9 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) return i-3; } } + if(s && state == PICTURE_START_CODE){ + ff_fetch_timestamp(s, i-3, 1); + } } } pc->state= state; @@ -2218,8 +2217,10 @@ static int decode_chunks(AVCodecContext *avctx, /* handle buffering and image synchronisation */ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - const uint8_t *buf, int buf_size) + AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; Mpeg1Context *s = avctx->priv_data; AVFrame *picture = data; MpegEncContext *s2 = &s->mpeg_enc_ctx; @@ -2237,7 +2238,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, } if(s2->flags&CODEC_FLAG_TRUNCATED){ - int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size); + int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL); if( ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 ) return buf_size; @@ -2255,7 +2256,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, } #endif - if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == ff_get_fourcc("VCR2")) + if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == AV_RL32("VCR2")) vcr2_init_sequence(avctx); s->slice_count= 0; @@ -2275,6 +2276,7 @@ static int decode_chunks(AVCodecContext *avctx, const uint8_t *buf_ptr = buf; const uint8_t *buf_end = buf + buf_size; int ret, input_size; + int last_code= 0; for(;;) { /* find next start code */ @@ -2285,15 +2287,20 @@ static int decode_chunks(AVCodecContext *avctx, if(avctx->thread_count > 1){ int i; - avctx->execute(avctx, slice_decode_thread, (void**)&(s2->thread_context[0]), NULL, s->slice_count); + avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); for(i=0; islice_count; i++) s2->error_count += s2->thread_context[i]->error_count; } + + if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) + ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); + if (slice_end(avctx, picture)) { if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice *data_size = sizeof(AVPicture); } } + s2->pict_type= 0; return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index); } @@ -2306,40 +2313,102 @@ static int decode_chunks(AVCodecContext *avctx, /* prepare data for next start code */ switch(start_code) { case SEQ_START_CODE: + if(last_code == 0){ mpeg1_decode_sequence(avctx, buf_ptr, input_size); + s->sync=1; + }else{ + av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code); + } break; case PICTURE_START_CODE: + if(last_code == 0 || last_code == SLICE_MIN_START_CODE){ + if(mpeg_decode_postinit(avctx) < 0){ + av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n"); + return -1; + } + /* we have a complete image: we try to decompress it */ - mpeg1_decode_picture(avctx, - buf_ptr, input_size); + if(mpeg1_decode_picture(avctx, + buf_ptr, input_size) < 0) + s2->pict_type=0; + s2->first_slice = 1; + last_code= PICTURE_START_CODE; + }else{ + av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code); + } break; case EXT_START_CODE: - mpeg_decode_extension(avctx, - buf_ptr, input_size); + init_get_bits(&s2->gb, buf_ptr, input_size*8); + + switch(get_bits(&s2->gb, 4)) { + case 0x1: + if(last_code == 0){ + mpeg_decode_sequence_extension(s); + }else{ + av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code); + } + break; + case 0x2: + mpeg_decode_sequence_display_extension(s); + break; + case 0x3: + mpeg_decode_quant_matrix_extension(s2); + break; + case 0x7: + mpeg_decode_picture_display_extension(s); + break; + case 0x8: + if(last_code == PICTURE_START_CODE){ + mpeg_decode_picture_coding_extension(s); + }else{ + av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code); + } + break; + } break; case USER_START_CODE: mpeg_decode_user_data(avctx, buf_ptr, input_size); break; case GOP_START_CODE: + if(last_code == 0){ s2->first_field=0; mpeg_decode_gop(avctx, buf_ptr, input_size); + s->sync=1; + }else{ + av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code); + } break; default: if (start_code >= SLICE_MIN_START_CODE && - start_code <= SLICE_MAX_START_CODE) { - int mb_y= start_code - SLICE_MIN_START_CODE; + start_code <= SLICE_MAX_START_CODE && last_code!=0) { + const int field_pic= s2->picture_structure != PICT_FRAME; + int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic; + last_code= SLICE_MIN_START_CODE; + + if(s2->picture_structure == PICT_BOTTOM_FIELD) + mb_y++; + + if (mb_y >= s2->mb_height){ + av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height); + return -1; + } if(s2->last_picture_ptr==NULL){ - /* Skip B-frames if we do not have reference frames. */ - if(s2->pict_type==FF_B_TYPE) break; + /* Skip B-frames if we do not have reference frames and gop is not closed */ + if(s2->pict_type==FF_B_TYPE){ + if(!s2->closed_gop) + break; + } } + if(s2->pict_type==FF_I_TYPE) + s->sync=1; if(s2->next_picture_ptr==NULL){ /* Skip P-frames if we do not have a reference frame or we have an invalid header. */ - if(s2->pict_type==FF_P_TYPE && (s2->first_field || s2->picture_structure==PICT_FRAME)) break; + if(s2->pict_type==FF_P_TYPE && !s->sync) break; } /* Skip B-frames if we are in a hurry. */ if(avctx->hurry_up && s2->pict_type==FF_B_TYPE) break; @@ -2357,16 +2426,26 @@ static int decode_chunks(AVCodecContext *avctx, break; } + if(!s2->pict_type){ + av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n"); + break; + } + if(s2->first_slice){ s2->first_slice=0; - if(mpeg_field_start(s2) < 0) + if(mpeg_field_start(s2, buf, buf_size) < 0) return -1; - } + } if(!s2->current_picture_ptr){ av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n"); return -1; } + if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) { + s->slice_count++; + break; + } + if(avctx->thread_count > 1){ int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; if(threshold <= mb_y){ @@ -2399,6 +2478,14 @@ static int decode_chunks(AVCodecContext *avctx, } } +static void flush(AVCodecContext *avctx){ + Mpeg1Context *s = avctx->priv_data; + + s->sync=0; + + ff_mpeg_flush(avctx); +} + static int mpeg_decode_end(AVCodecContext *avctx) { Mpeg1Context *s = avctx->priv_data; @@ -2418,7 +2505,7 @@ AVCodec mpeg1video_decoder = { mpeg_decode_end, mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, - .flush= ff_mpeg_flush, + .flush= flush, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), }; @@ -2432,7 +2519,7 @@ AVCodec mpeg2video_decoder = { mpeg_decode_end, mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, - .flush= ff_mpeg_flush, + .flush= flush, .long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"), }; @@ -2447,14 +2534,12 @@ AVCodec mpegvideo_decoder = { mpeg_decode_end, mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, - .flush= ff_mpeg_flush, + .flush= flush, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), }; -#ifdef HAVE_XVMC +#if CONFIG_MPEG_XVMC_DECODER static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){ - Mpeg1Context *s; - if( avctx->thread_count > 1) return -1; if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) ) @@ -2463,7 +2548,6 @@ static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){ dprintf(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n"); } mpeg_decode_init(avctx); - s = avctx->priv_data; avctx->pix_fmt = PIX_FMT_XVMC_MPEG2_IDCT; avctx->xvmc_acceleration = 2;//2 - the blocks are packed! @@ -2481,8 +2565,41 @@ AVCodec mpeg_xvmc_decoder = { mpeg_decode_end, mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY, - .flush= ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video XvMC (X-Video Motion Compensation)"), + .flush= flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"), +}; + +#endif + +#if CONFIG_MPEG_VDPAU_DECODER +AVCodec mpeg_vdpau_decoder = { + "mpegvideo_vdpau", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG2VIDEO, + sizeof(Mpeg1Context), + mpeg_decode_init, + NULL, + mpeg_decode_end, + mpeg_decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, + .flush= flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"), }; +#endif +#if CONFIG_MPEG1_VDPAU_DECODER +AVCodec mpeg1_vdpau_decoder = { + "mpeg1video_vdpau", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG1VIDEO, + sizeof(Mpeg1Context), + mpeg_decode_init, + NULL, + mpeg_decode_end, + mpeg_decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, + .flush= flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"), +}; #endif +