X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg12.c;h=0c6ef7aa44b287a2fb849711291f8dbc491841b3;hb=cc55c464987c0bfceef32efffd73069509ea784c;hp=e62827a41663b4c746b2018f1fb9a591ee203584;hpb=392b748293deb83e3eb80cb5388ac6cc7239714e;p=ffmpeg diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index e62827a4166..0c6ef7aa44b 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1,6 +1,6 @@ /* - * MPEG1/2 decoder - * Copyright (c) 2000,2001 Fabrice Bellard. + * MPEG-1/2 decoder + * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * * This file is part of FFmpeg. @@ -21,8 +21,8 @@ */ /** - * @file mpeg12.c - * MPEG1/2 decoder + * @file libavcodec/mpeg12.c + * MPEG-1/2 decoder */ //#define DEBUG @@ -34,18 +34,17 @@ #include "mpeg12data.h" #include "mpeg12decdata.h" #include "bytestream.h" +#include "vdpau_internal.h" //#undef NDEBUG //#include -#define DC_VLC_BITS 9 #define MV_VLC_BITS 9 #define MBINCR_VLC_BITS 9 #define MB_PAT_VLC_BITS 9 #define MB_PTYPE_VLC_BITS 6 #define MB_BTYPE_VLC_BITS 6 -#define TEX_VLC_BITS 9 static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, @@ -65,33 +64,33 @@ 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 +int XVMC_field_start(MpegEncContext *s, AVCodecContext *avctx); +int XVMC_field_end(MpegEncContext *s); +void XVMC_pack_pblocks(MpegEncContext *s,int cbp); +void XVMC_init_block(MpegEncContext *s);//set s->block -static const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,-1}; -static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,-1}; -static const enum PixelFormat pixfmt_yuv_444[]= {PIX_FMT_YUV444P,-1}; static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_XVMC_MPEG2_MC, - -1}; + PIX_FMT_NONE}; uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; -static void init_2d_vlc_rl(RLTable *rl, int use_static) -{ - int i; - init_vlc(&rl->vlc, TEX_VLC_BITS, rl->n + 2, - &rl->table_vlc[0][1], 4, 2, - &rl->table_vlc[0][0], 4, 2, use_static); +#define INIT_2D_VLC_RL(rl, static_size)\ +{\ + static RL_VLC_ELEM rl_vlc_table[static_size];\ + INIT_VLC_STATIC(&rl.vlc, TEX_VLC_BITS, rl.n + 2,\ + &rl.table_vlc[0][1], 4, 2,\ + &rl.table_vlc[0][0], 4, 2, static_size);\ +\ + rl.rl_vlc[0]= rl_vlc_table;\ + init_2d_vlc_rl(&rl);\ +} - if(use_static) - rl->rl_vlc[0]= av_mallocz_static(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); - else - rl->rl_vlc[0]= av_malloc(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); +static void init_2d_vlc_rl(RLTable *rl) +{ + int i; for(i=0; ivlc.table_size; i++){ int code= rl->vlc.table[i][0]; @@ -141,48 +140,46 @@ void ff_mpeg1_clean_buffers(MpegEncContext *s){ /******************************************/ /* decoding */ -static VLC dc_lum_vlc; -static VLC dc_chroma_vlc; static VLC mv_vlc; static VLC mbincr_vlc; static VLC mb_ptype_vlc; static VLC mb_btype_vlc; static VLC mb_pat_vlc; -static void init_vlcs(void) +av_cold void ff_mpeg12_init_vlcs(void) { static int done = 0; if (!done) { done = 1; - init_vlc(&dc_lum_vlc, DC_VLC_BITS, 12, + INIT_VLC_STATIC(&dc_lum_vlc, DC_VLC_BITS, 12, ff_mpeg12_vlc_dc_lum_bits, 1, 1, - ff_mpeg12_vlc_dc_lum_code, 2, 2, 1); - init_vlc(&dc_chroma_vlc, DC_VLC_BITS, 12, + ff_mpeg12_vlc_dc_lum_code, 2, 2, 512); + INIT_VLC_STATIC(&dc_chroma_vlc, DC_VLC_BITS, 12, ff_mpeg12_vlc_dc_chroma_bits, 1, 1, - ff_mpeg12_vlc_dc_chroma_code, 2, 2, 1); - init_vlc(&mv_vlc, MV_VLC_BITS, 17, + ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514); + INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17, &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1, - &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 1); - init_vlc(&mbincr_vlc, MBINCR_VLC_BITS, 36, + &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518); + INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36, &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1, - &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 1); - init_vlc(&mb_pat_vlc, MB_PAT_VLC_BITS, 64, + &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538); + INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64, &ff_mpeg12_mbPatTable[0][1], 2, 1, - &ff_mpeg12_mbPatTable[0][0], 2, 1, 1); + &ff_mpeg12_mbPatTable[0][0], 2, 1, 512); - init_vlc(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, + INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, &table_mb_ptype[0][1], 2, 1, - &table_mb_ptype[0][0], 2, 1, 1); - init_vlc(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, + &table_mb_ptype[0][0], 2, 1, 64); + INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, &table_mb_btype[0][1], 2, 1, - &table_mb_btype[0][0], 2, 1, 1); + &table_mb_btype[0][0], 2, 1, 64); init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); - init_2d_vlc_rl(&ff_rl_mpeg1, 1); - init_2d_vlc_rl(&ff_rl_mpeg2, 1); + INIT_2D_VLC_RL(ff_rl_mpeg1, 680); + INIT_2D_VLC_RL(ff_rl_mpeg2, 674); } } @@ -204,7 +201,7 @@ static inline int get_qscale(MpegEncContext *s) } } -/* motion type (for mpeg2) */ +/* motion type (for MPEG-2) */ #define MT_FIELD 1 #define MT_FRAME 2 #define MT_16X8 2 @@ -221,7 +218,7 @@ static int mpeg_decode_mb(MpegEncContext *s, assert(s->mb_skipped==0); if (s->mb_skip_run-- != 0) { - if (s->pict_type == P_TYPE) { + if (s->pict_type == FF_P_TYPE) { s->mb_skipped = 1; s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; } else { @@ -230,7 +227,7 @@ static int mpeg_decode_mb(MpegEncContext *s, if(s->mb_x) mb_type= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]; else - mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in mpeg at all, + mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all if(IS_INTRA(mb_type)) return -1; @@ -247,7 +244,7 @@ static int mpeg_decode_mb(MpegEncContext *s, switch(s->pict_type) { default: - case I_TYPE: + case FF_I_TYPE: if (get_bits1(&s->gb) == 0) { if (get_bits1(&s->gb) == 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y); @@ -258,7 +255,7 @@ static int mpeg_decode_mb(MpegEncContext *s, mb_type = MB_TYPE_INTRA; } break; - case P_TYPE: + case FF_P_TYPE: mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1); if (mb_type < 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y); @@ -266,7 +263,7 @@ static int mpeg_decode_mb(MpegEncContext *s, } mb_type = ptype2mb_type[ mb_type ]; break; - case B_TYPE: + case FF_B_TYPE: mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1); if (mb_type < 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y); @@ -284,8 +281,8 @@ static int mpeg_decode_mb(MpegEncContext *s, s->dsp.clear_blocks(s->block[6]); } - /* compute dct type */ - if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? + /* compute DCT type */ + if (s->picture_structure == PICT_FRAME && //FIXME add an interlaced_dct coded var? !s->frame_pred_frame_dct) { s->interlaced_dct = get_bits1(&s->gb); } @@ -307,8 +304,8 @@ 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 - //one 1 we memcpy blocks in xvmcvideo +#if CONFIG_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(s->swap_uv){ @@ -388,7 +385,7 @@ static int mpeg_decode_mb(MpegEncContext *s, mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]); - /* full_pel: only for mpeg1 */ + /* full_pel: only for MPEG-1 */ if (s->full_pel[i]){ s->mv[i][0][0] <<= 1; s->mv[i][0][1] <<= 1; @@ -520,8 +517,8 @@ static int mpeg_decode_mb(MpegEncContext *s, return -1; } -#ifdef HAVE_XVMC - //on 1 we memcpy blocks in xvmcvideo +#if CONFIG_XVMC + //if 1, we memcpy blocks in xvmcvideo if(s->avctx->xvmc_acceleration > 1){ XVMC_pack_pblocks(s,cbp); if(s->swap_uv){ @@ -586,7 +583,7 @@ static int mpeg_decode_mb(MpegEncContext *s, return 0; } -/* as h263, but only 17 codes */ +/* as H.263, but only 17 codes */ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) { int code, sign, val, l, shift; @@ -617,27 +614,6 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) return val; } -static inline int decode_dc(GetBitContext *gb, int component) -{ - int code, diff; - - if (component == 0) { - code = get_vlc2(gb, dc_lum_vlc.table, DC_VLC_BITS, 2); - } else { - code = get_vlc2(gb, dc_chroma_vlc.table, DC_VLC_BITS, 2); - } - if (code < 0){ - av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n"); - return 0xffff; - } - if (code == 0) { - diff = 0; - } else { - diff = get_xbits(gb, code); - } - return diff; -} - static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n) @@ -649,7 +625,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, const uint16_t *quant_matrix= s->intra_matrix; const int qscale= s->qscale; - /* DC coef */ + /* DC coefficient */ component = (n <= 3 ? 0 : n - 4 + 1); diff = decode_dc(&s->gb, component); if (diff >= 0xffff) @@ -662,7 +638,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, i = 0; { OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefs */ + /* now quantify & encode AC coefficients */ for(;;) { UPDATE_CACHE(re, &s->gb); GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -724,7 +700,7 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, { OPEN_READER(re, &s->gb); i = -1; - /* special case for the first coef. no need to add a second vlc table */ + // special case for first coefficient, no need to add second VLC table UPDATE_CACHE(re, &s->gb); if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { level= (3*qscale*quant_matrix[0])>>5; @@ -737,8 +713,10 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } - - /* now quantify & encode AC coefs */ +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif + /* now quantify & encode AC coefficients */ for(;;) { GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -777,9 +755,14 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, } block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >= 19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -799,7 +782,7 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc { OPEN_READER(re, &s->gb); i = -1; - /* special case for the first coef. no need to add a second vlc table */ + // special case for first coefficient, no need to add second VLC table UPDATE_CACHE(re, &s->gb); if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { level= (3*qscale)>>1; @@ -812,8 +795,11 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif - /* now quantify & encode AC coefs */ + /* now quantify & encode AC coefficients */ for(;;) { GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -848,9 +834,14 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc } block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >= 19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -882,7 +873,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, else quant_matrix = s->chroma_inter_matrix; - /* special case for the first coef. no need to add a second vlc table */ + // special case for first coefficient, no need to add second VLC table UPDATE_CACHE(re, &s->gb); if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { level= (3*qscale*quant_matrix[0])>>5; @@ -895,8 +886,11 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif - /* now quantify & encode AC coefs */ + /* now quantify & encode AC coefficients */ for(;;) { GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -928,9 +922,14 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, mismatch ^= level; block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >= 19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -953,7 +952,7 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, OPEN_READER(re, &s->gb); i = -1; - /* special case for the first coef. no need to add a second vlc table */ + // special case for first coefficient, no need to add second VLC table UPDATE_CACHE(re, &s->gb); if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { level= (3*qscale)>>1; @@ -965,8 +964,11 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif - /* now quantify & encode AC coefs */ + /* now quantify & encode AC coefficients */ for(;;) { GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -993,9 +995,14 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, } block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >=19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -1017,7 +1024,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, const int qscale= s->qscale; int mismatch; - /* DC coef */ + /* DC coefficient */ if (n < 4){ quant_matrix = s->intra_matrix; component = 0; @@ -1042,7 +1049,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, { OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefs */ + /* now quantify & encode AC coefficients */ for(;;) { UPDATE_CACHE(re, &s->gb); GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -1096,7 +1103,7 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, const uint16_t *quant_matrix; const int qscale= s->qscale; - /* DC coef */ + /* DC coefficient */ if (n < 4){ quant_matrix = s->intra_matrix; component = 0; @@ -1118,7 +1125,7 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, { OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefs */ + /* now quantify & encode AC coefficients */ for(;;) { UPDATE_CACHE(re, &s->gb); GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -1168,15 +1175,14 @@ typedef struct Mpeg1Context { } Mpeg1Context; -static int mpeg_decode_init(AVCodecContext *avctx) +static av_cold int mpeg_decode_init(AVCodecContext *avctx) { Mpeg1Context *s = avctx->priv_data; MpegEncContext *s2 = &s->mpeg_enc_ctx; int i; - //we need some parmutation to store - //matrixes, until MPV_common_init() - //set the real permutatuon + /* we need some permutation to store matrices, + * until MPV_common_init() sets the real permutation. */ for(i=0;i<64;i++) s2->dsp.idct_permutation[i]=i; @@ -1186,7 +1192,7 @@ static 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); - init_vlcs(); + ff_mpeg12_init_vlcs(); s->mpeg_enc_ctx_allocated = 0; s->mpeg_enc_ctx.picture_number = 0; @@ -1207,8 +1213,29 @@ static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, } } -//Call this function when we know all parameters -//it may be called in different places for mpeg1 and mpeg2 +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 PIX_FMT_YUV420P; + 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){ Mpeg1Context *s1 = avctx->priv_data; MpegEncContext *s = &s1->mpeg_enc_ctx; @@ -1240,29 +1267,32 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ s1->save_width = s->width; s1->save_height = s->height; - //low_delay may be forced, in this case we will have B frames - //that behave like P frames + /* 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 - //mpeg1 fps + 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; - //mpeg1 aspect + //MPEG-1 aspect avctx->sample_aspect_ratio= av_d2q( 1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255); - }else{//mpeg2 - //mpeg2 fps + }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].den * s1->frame_rate_ext.den, 1<<30); - //mpeg2 aspect + //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], @@ -1279,28 +1309,17 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ s->avctx->sample_aspect_ratio= ff_mpeg2_aspect[s->aspect_ratio_info]; } - }//mpeg2 + }//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); //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 || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) if( avctx->idct_algo == FF_IDCT_AUTO ) avctx->idct_algo = FF_IDCT_SIMPLE; - //quantization matrixes may need reordering - //if dct permutation is changed + /* Quantization matrices may need reordering + * if DCT permutation is changed. */ memcpy(old_permutation,s->dsp.idct_permutation,64*sizeof(uint8_t)); if (MPV_common_init(s) < 0) @@ -1334,24 +1353,24 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, return -1; vbv_delay= get_bits(&s->gb, 16); - if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { + 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; } - if (s->pict_type == B_TYPE) { + 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; } s->current_picture.pict_type= s->pict_type; - s->current_picture.key_frame= s->pict_type == I_TYPE; + s->current_picture.key_frame= s->pict_type == FF_I_TYPE; if(avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type); @@ -1368,7 +1387,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1) int horiz_size_ext, vert_size_ext; int bit_rate_ext; - skip_bits(&s->gb, 1); /* profil and level esc*/ + skip_bits(&s->gb, 1); /* profile and level esc*/ s->avctx->profile= get_bits(&s->gb, 3); s->avctx->level= get_bits(&s->gb, 4); s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ @@ -1390,7 +1409,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1) dprintf(s->avctx, "sequence extension\n"); s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO; - s->avctx->sub_id = 2; /* indicates mpeg2 found */ + s->avctx->sub_id = 2; /* indicates MPEG-2 found */ if(s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n", @@ -1494,13 +1513,28 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) } } -static void mpeg_decode_picture_coding_extension(MpegEncContext *s) +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->first_slice= 1; + } 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); @@ -1566,7 +1600,7 @@ static void mpeg_decode_extension(AVCodecContext *avctx, mpeg_decode_picture_display_extension(s1); break; case 0x8: - mpeg_decode_picture_coding_extension(s); + mpeg_decode_picture_coding_extension(s1); break; } } @@ -1617,7 +1651,7 @@ static int mpeg_field_start(MpegEncContext *s){ } } } -#ifdef HAVE_XVMC +#if CONFIG_XVMC // MPV_frame_start will call this function too, // but we need to call it on every field if(s->avctx->xvmc_acceleration) @@ -1700,7 +1734,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, if(s->avctx->debug&FF_DEBUG_PICT_INFO){ av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1], - s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), + s->pict_type == FF_I_TYPE ? "I" : (s->pict_type == FF_P_TYPE ? "P" : (s->pict_type == FF_B_TYPE ? "B" : "S")), s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); @@ -1708,8 +1742,8 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, } for(;;) { -#ifdef HAVE_XVMC - //one 1 we memcpy blocks in xvmcvideo +#if CONFIG_XVMC + //If 1, we memcpy blocks in xvmcvideo. if(s->avctx->xvmc_acceleration > 1) XVMC_init_block(s);//set s->block #endif @@ -1726,7 +1760,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, for(i=0; i<2; i++){ for(dir=0; dir<2; dir++){ - if (s->mb_intra || (dir==1 && s->pict_type != B_TYPE)) { + if (s->mb_intra || (dir==1 && s->pict_type != FF_B_TYPE)) { motion_x = motion_y = 0; }else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)){ motion_x = s->mv[dir][0][0]; @@ -1764,12 +1798,12 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, if(s->mb_y<= s->mb_height){ int left= s->gb.size_in_bits - get_bits_count(&s->gb); - int is_d10= s->chroma_format==2 && s->pict_type==I_TYPE && avctx->profile==0 && avctx->level==5 + 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 @@ -1781,7 +1815,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, /* skip mb handling */ if (s->mb_skip_run == -1) { - /* read again increment */ + /* read increment again */ s->mb_skip_run = 0; for(;;) { int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); @@ -1807,7 +1841,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, } if(s->mb_skip_run){ int i; - if(s->pict_type == I_TYPE){ + if(s->pict_type == FF_I_TYPE){ av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -1820,7 +1854,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, s->mv_type = MV_TYPE_16X16; else s->mv_type = MV_TYPE_FIELD; - if (s->pict_type == P_TYPE) { + if (s->pict_type == FF_P_TYPE) { /* if P type, zero motion vector is implied */ s->mv_dir = MV_DIR_FORWARD; s->mv[0][0][0] = s->mv[0][0][1] = 0; @@ -1838,13 +1872,13 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, } } eos: // end of slice - *buf += get_bits_count(&s->gb)/8 - 1; + *buf += (get_bits_count(&s->gb)-1)/8; //printf("y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y); return 0; } 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; @@ -1879,8 +1913,8 @@ static int slice_decode_thread(AVCodecContext *c, void *arg){ } /** - * handles slice ends. - * @return 1 if it seems to be the last slice of + * Handles slice ends. + * @return 1 if it seems to be the last slice */ static int slice_end(AVCodecContext *avctx, AVFrame *pict) { @@ -1890,7 +1924,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr) return 0; -#ifdef HAVE_XVMC +#if CONFIG_XVMC if(s->avctx->xvmc_acceleration) XVMC_field_end(s); #endif @@ -1904,12 +1938,12 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) MPV_frame_end(s); - if (s->pict_type == B_TYPE || s->low_delay) { + if (s->pict_type == FF_B_TYPE || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; ff_print_debug_info(s, pict); } else { s->picture_number++; - /* latency of 1 frame for I and P frames */ + /* latency of 1 frame for I- and P-frames */ /* XXX: use another variable than picture_number */ if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr; @@ -1935,12 +1969,14 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, width = get_bits(&s->gb, 12); height = get_bits(&s->gb, 12); - if (width <= 0 || height <= 0 || - (width % 2) != 0 || (height % 2) != 0) + if (width <= 0 || height <= 0) return -1; s->aspect_ratio_info= get_bits(&s->gb, 4); - if (s->aspect_ratio_info == 0) - return -1; + if (s->aspect_ratio_info == 0) { + av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); + if (avctx->error_recognition >= FF_ER_COMPLIANT) + return -1; + } s->frame_rate_index = get_bits(&s->gb, 4); if (s->frame_rate_index == 0 || s->frame_rate_index > 13) return -1; @@ -1991,7 +2027,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->chroma_inter_matrix[j] = v; } #ifdef DEBUG - dprintf(s->avctx, "non intra matrix present\n"); + 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"); @@ -2010,16 +2046,16 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, return -1; } - /* we set mpeg2 parameters so that it emulates mpeg1 */ + /* we set MPEG-2 parameters so that it emulates MPEG-1 */ s->progressive_sequence = 1; s->progressive_frame = 1; s->picture_structure = PICT_FRAME; s->frame_pred_frame_dct = 1; s->chroma_format = 1; s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG1VIDEO; - avctx->sub_id = 1; /* indicates mpeg1 */ + avctx->sub_id = 1; /* indicates MPEG-1 */ s->out_format = FMT_MPEG1; - s->swap_uv = 0;//AFAIK VCR2 don't have SEQ_HEADER + s->swap_uv = 0;//AFAIK VCR2 does not have SEQ_HEADER if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1; if(s->avctx->debug & FF_DEBUG_PICT_INFO) @@ -2035,7 +2071,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx) MpegEncContext *s = &s1->mpeg_enc_ctx; int i, v; - /* start new mpeg1 context decoding */ + /* start new MPEG-1 context decoding */ s->out_format = FMT_MPEG1; if (s1->mpeg_enc_ctx_allocated) { MPV_common_end(s); @@ -2045,13 +2081,10 @@ 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); - if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ) + if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) if( avctx->idct_algo == FF_IDCT_AUTO ) avctx->idct_algo = FF_IDCT_SIMPLE; @@ -2078,7 +2111,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx) s->frame_pred_frame_dct = 1; s->chroma_format = 1; s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO; - avctx->sub_id = 2; /* indicates mpeg2 */ + avctx->sub_id = 2; /* indicates MPEG-2 */ return 0; } @@ -2120,7 +2153,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 broken_link; + int closed_gop, broken_link; init_get_bits(&s->gb, buf, buf_size*8); @@ -2132,18 +2165,19 @@ 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); /*broken_link indicate that after editing the reference frames of the first B-Frames after GOP I-Frame are missing (open gop)*/ broken_link = get_bits1(&s->gb); if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) broken_link=%d\n", + 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, broken_link); + time_code_pictures, closed_gop, broken_link); } /** - * finds the end of the current frame in the bitstream. + * 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) @@ -2151,29 +2185,43 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) int i; uint32_t state= pc->state; - i=0; - if(!pc->frame_start_found){ - for(i=0; i 1/4 + 1 first_SEQEXT -> 0/2 + 2 first field start -> 3/0 + 3 second_SEQEXT -> 2/0 + 4 searching end +*/ + + for(i=0; iframe_start_found>=0 && pc->frame_start_found<=4); + if(pc->frame_start_found&1){ + if(state == EXT_START_CODE && (buf[i]&0xF0) != 0x80) + pc->frame_start_found--; + else if(state == EXT_START_CODE+2){ + if((buf[i]&3) == 3) pc->frame_start_found= 0; + else pc->frame_start_found= (pc->frame_start_found+1)&3; + } + state++; + }else{ i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1; - if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ + if(pc->frame_start_found==0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ i++; - pc->frame_start_found=1; - break; + pc->frame_start_found=4; } if(state == SEQ_END_CODE){ pc->state=-1; return i+1; } - } - } - - if(pc->frame_start_found){ - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - for(; iframe_start_found==2 && state == SEQ_START_CODE) + pc->frame_start_found= 0; + if(pc->frame_start_found<4 && state == EXT_START_CODE) + pc->frame_start_found++; + if(pc->frame_start_found == 4 && (state&0xFFFFFF00) == 0x100){ if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){ pc->frame_start_found=0; pc->state=-1; @@ -2186,16 +2234,16 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) return END_NOT_FOUND; } +static int decode_chunks(AVCodecContext *avctx, + AVFrame *picture, int *data_size, + const uint8_t *buf, int buf_size); + /* handle buffering and image synchronisation */ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { Mpeg1Context *s = avctx->priv_data; - const uint8_t *buf_end; - const uint8_t *buf_ptr; - uint32_t start_code; - int ret, input_size; AVFrame *picture = data; MpegEncContext *s2 = &s->mpeg_enc_ctx; dprintf(avctx, "fill_buffer\n"); @@ -2208,7 +2256,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, *data_size = sizeof(AVFrame); } - return 0; + return buf_size; } if(s2->flags&CODEC_FLAG_TRUNCATED){ @@ -2218,9 +2266,6 @@ static int mpeg_decode_frame(AVCodecContext *avctx, return buf_size; } - buf_ptr = buf; - buf_end = buf + buf_size; - #if 0 if (s->repeat_field % 2 == 1) { s->repeat_field++; @@ -2233,36 +2278,57 @@ 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; + if(avctx->extradata && !avctx->frame_number) + decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size); + + return decode_chunks(avctx, picture, data_size, buf, buf_size); +} + +static int decode_chunks(AVCodecContext *avctx, + AVFrame *picture, int *data_size, + const uint8_t *buf, int buf_size) +{ + Mpeg1Context *s = avctx->priv_data; + MpegEncContext *s2 = &s->mpeg_enc_ctx; + const uint8_t *buf_ptr = buf; + const uint8_t *buf_end = buf + buf_size; + int ret, input_size; + for(;;) { - /* find start next code */ - start_code = -1; + /* find next start code */ + uint32_t start_code = -1; buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code); if (start_code > 0x1ff){ - if(s2->pict_type != B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){ + if(s2->pict_type != FF_B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){ 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, (void**)&(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); } input_size = buf_end - buf_ptr; if(avctx->debug & FF_DEBUG_STARTCODE){ - av_log(avctx, AV_LOG_DEBUG, "%3X at %zd left %d\n", start_code, buf_ptr-buf, input_size); + av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size); } /* prepare data for next start code */ @@ -2273,9 +2339,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx, break; case PICTURE_START_CODE: - /* we have a complete image : we try to decompress it */ - mpeg1_decode_picture(avctx, - buf_ptr, input_size); + /* we have a complete image: we try to decompress it */ + if(mpeg1_decode_picture(avctx, + buf_ptr, input_size) < 0) + s2->pict_type=0; break; case EXT_START_CODE: mpeg_decode_extension(avctx, @@ -2297,14 +2364,16 @@ static int mpeg_decode_frame(AVCodecContext *avctx, if(s2->last_picture_ptr==NULL){ /* Skip B-frames if we do not have reference frames. */ - if(s2->pict_type==B_TYPE) break; - /* Skip P-frames if we do not have reference frame no valid header. */ -// if(s2->pict_type==P_TYPE && s2->first_field && !s2->first_slice) break; + if(s2->pict_type==FF_B_TYPE) break; + } + 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; } /* Skip B-frames if we are in a hurry. */ - if(avctx->hurry_up && s2->pict_type==B_TYPE) break; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=I_TYPE) + if(avctx->hurry_up && s2->pict_type==FF_B_TYPE) break; + if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==FF_B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=FF_I_TYPE) || avctx->skip_frame >= AVDISCARD_ALL) break; /* Skip everything if we are in a hurry>=5. */ @@ -2317,6 +2386,11 @@ static int mpeg_decode_frame(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) @@ -2327,6 +2401,11 @@ static int mpeg_decode_frame(AVCodecContext *avctx, 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){ @@ -2341,7 +2420,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, init_get_bits(&thread_context->gb, buf_ptr, input_size*8); s->slice_count++; } - buf_ptr += 2; //FIXME add minimum num of bytes per slice + buf_ptr += 2; //FIXME add minimum number of bytes per slice }else{ ret = mpeg_decode_slice(s, mb_y, &buf_ptr, input_size); emms_c(); @@ -2379,6 +2458,7 @@ AVCodec mpeg1video_decoder = { mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, .flush= ff_mpeg_flush, + .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), }; AVCodec mpeg2video_decoder = { @@ -2392,6 +2472,7 @@ AVCodec mpeg2video_decoder = { mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, .flush= ff_mpeg_flush, + .long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"), }; //legacy decoder @@ -2406,10 +2487,11 @@ AVCodec mpegvideo_decoder = { mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, .flush= ff_mpeg_flush, + .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), }; -#ifdef HAVE_XVMC -static int mpeg_mc_decode_init(AVCodecContext *avctx){ +#if CONFIG_XVMC +static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){ Mpeg1Context *s; if( avctx->thread_count > 1) @@ -2439,11 +2521,40 @@ AVCodec mpeg_xvmc_decoder = { 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)"), +}; + +#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= ff_mpeg_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= ff_mpeg_flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"), +}; #endif -/* this is ugly i know, but the alternative is too make - hundreds of vars global and prefix them with ff_mpeg1_ - which is far uglier. */ -#include "mdec.c"