diff options
Diffstat (limited to 'libavcodec/mpeg12.c')
-rw-r--r-- | libavcodec/mpeg12.c | 119 |
1 files changed, 88 insertions, 31 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 5734ab8..0575a97 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg 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. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,6 +30,7 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "libavutil/avassert.h" #include "mpeg12.h" #include "mpeg12data.h" @@ -935,6 +936,10 @@ static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64]) } break; case MT_FIELD: + if(s->progressive_sequence){ + av_log(s->avctx, AV_LOG_ERROR, "MT_FIELD in progressive_sequence\n"); + return -1; + } s->mv_type = MV_TYPE_FIELD; if (s->picture_structure == PICT_FRAME) { mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; @@ -972,6 +977,10 @@ static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64]) } break; case MT_DMV: + if(s->progressive_sequence){ + av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n"); + return -1; + } s->mv_type = MV_TYPE_DMV; for (i = 0; i < 2; i++) { if (USES_LIST(mb_type, i)) { @@ -1117,6 +1126,7 @@ typedef struct Mpeg1Context { 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? + int tmpgexs; } Mpeg1Context; static av_cold int mpeg_decode_init(AVCodecContext *avctx) @@ -1184,31 +1194,61 @@ static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, } } -static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { +static const enum PixelFormat mpeg1_hwaccel_pixfmt_list_420[] = { +#if CONFIG_MPEG_XVMC_DECODER PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_XVMC_MPEG2_MC, - PIX_FMT_NONE }; +#endif +#if CONFIG_MPEG1_VDPAU_HWACCEL + PIX_FMT_VDPAU_MPEG1, +#endif + PIX_FMT_YUV420P, + PIX_FMT_NONE +}; + +static const enum PixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { +#if CONFIG_MPEG_XVMC_DECODER + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_XVMC_MPEG2_MC, +#endif +#if CONFIG_MPEG2_VDPAU_HWACCEL + PIX_FMT_VDPAU_MPEG2, +#endif +#if CONFIG_MPEG2_DXVA2_HWACCEL + PIX_FMT_DXVA2_VLD, +#endif +#if CONFIG_MPEG2_VAAPI_HWACCEL + PIX_FMT_VAAPI_VLD, +#endif + PIX_FMT_YUV420P, + PIX_FMT_NONE +}; + +static inline int uses_vdpau(AVCodecContext *avctx) { + return avctx->pix_fmt == PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == PIX_FMT_VDPAU_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 avctx->get_format(avctx, ff_hwaccel_pixfmt_list_420); - else if (s->chroma_format == 2) - return PIX_FMT_YUV422P; - else - return PIX_FMT_YUV444P; - } + if(s->chroma_format < 2) { + enum PixelFormat res; + res = avctx->get_format(avctx, + avctx->codec_id == CODEC_ID_MPEG1VIDEO ? + mpeg1_hwaccel_pixfmt_list_420 : + mpeg2_hwaccel_pixfmt_list_420); + if (res != PIX_FMT_XVMC_MPEG2_IDCT && res != PIX_FMT_XVMC_MPEG2_MC) { + avctx->xvmc_acceleration = 0; + } else if (!avctx->xvmc_acceleration) { + avctx->xvmc_acceleration = 2; + } + return res; + } else if(s->chroma_format == 2) + return PIX_FMT_YUV422P; + else + return PIX_FMT_YUV444P; } /* Call this function when we know all parameters. @@ -1302,8 +1342,7 @@ static int mpeg_decode_postinit(AVCodecContext *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 || - avctx->hwaccel || - s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) + avctx->hwaccel ) if (avctx->idct_algo == FF_IDCT_AUTO) avctx->idct_algo = FF_IDCT_SIMPLE; @@ -1537,7 +1576,6 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) 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) { @@ -1918,7 +1956,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) ff_xvmc_field_end(s); /* end of slice reached */ - if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) { + if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s->first_slice) { /* end of image */ s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2; @@ -2045,8 +2083,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx) 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 || avctx->hwaccel || - s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) + if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ) if (avctx->idct_algo == FF_IDCT_AUTO) avctx->idct_algo = FF_IDCT_SIMPLE; @@ -2084,8 +2121,22 @@ static int vcr2_init_sequence(AVCodecContext *avctx) static void mpeg_decode_user_data(AVCodecContext *avctx, const uint8_t *p, int buf_size) { + Mpeg1Context *s = avctx->priv_data; const uint8_t *buf_end = p + buf_size; + if(buf_size > 29){ + int i; + for(i=0; i<20; i++) + if(!memcmp(p+i, "\0TMPGEXS\0", 9)){ + s->tmpgexs= 1; + } + +/* for(i=0; !(!p[i-2] && !p[i-1] && p[i]==1) && i<buf_size; i++){ + av_log(0,0, "%c", p[i]); + } + av_log(0,0, "\n");*/ + } + /* we parse the DTG active format information */ if (buf_end - p >= 5 && p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') { @@ -2264,13 +2315,14 @@ static int decode_chunks(AVCodecContext *avctx, if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) { if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) { int i; + av_assert0(avctx->thread_count > 1); avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); for (i = 0; i < s->slice_count; i++) s2->error_count += s2->thread_context[i]->error_count; } - if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) + if (CONFIG_VDPAU && uses_vdpau(avctx)) ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); if (slice_end(avctx, picture)) { @@ -2302,6 +2354,10 @@ static int decode_chunks(AVCodecContext *avctx, break; case PICTURE_START_CODE: + if(s->tmpgexs){ + s2->intra_dc_precision= 3; + s2->intra_matrix[0]= 1; + } if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) { int i; @@ -2399,7 +2455,7 @@ static int decode_chunks(AVCodecContext *avctx, break; } } - if (s2->pict_type == AV_PICTURE_TYPE_I) + if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->flags2 & CODEC_FLAG2_SHOW_ALL)) 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. */ @@ -2435,13 +2491,14 @@ static int decode_chunks(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) { + if (uses_vdpau(avctx)) { s->slice_count++; break; } if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) { - int threshold= (s2->mb_height * s->slice_count + avctx->thread_count / 2) / avctx->thread_count; + int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; + av_assert0(avctx->thread_count > 1); if (threshold <= mb_y) { MpegEncContext *thread_context = s2->thread_context[s->slice_count]; |