From 9b7a0c5d886223802df54b754caf75b6e125e76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reimar=20D=C3=B6ffinger?= Date: Mon, 28 Mar 2011 22:33:58 +0200 Subject: [PATCH] Allow selecting VDPAU, XvMC via get_format for MPEG-2 To avoid further special-casing, dummy AVHWAccels are added for VDPAU. It should be possible to move VDPAU completely to AVHWAccel later. --- libavcodec/allcodecs.c | 2 ++ libavcodec/mpeg12.c | 70 ++++++++++++++++++++++++++---------------- libavcodec/vdpau.c | 36 ++++++++++++++++++++++ 3 files changed, 82 insertions(+), 26 deletions(-) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 0142c13093..78bb540657 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -57,8 +57,10 @@ void avcodec_register_all(void) REGISTER_HWACCEL (H263_VAAPI, h263_vaapi); REGISTER_HWACCEL (H264_DXVA2, h264_dxva2); REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); + REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau); REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); + REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau); REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 7034a91b51..bfe0d9e68e 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -67,11 +67,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); -static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { - PIX_FMT_XVMC_MPEG2_IDCT, - PIX_FMT_XVMC_MPEG2_MC, - PIX_FMT_NONE}; - uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; @@ -1213,25 +1208,50 @@ static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, } } +static const enum PixelFormat mpeg1_hwaccel_pixfmt_list_420[] = { + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_XVMC_MPEG2_MC, + PIX_FMT_VDPAU_MPEG1, + PIX_FMT_DXVA2_VLD, + PIX_FMT_VAAPI_VLD, + PIX_FMT_YUV420P, + PIX_FMT_NONE +}; + +static const enum PixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_XVMC_MPEG2_MC, + PIX_FMT_VDPAU_MPEG2, + PIX_FMT_DXVA2_VLD, + PIX_FMT_VAAPI_VLD, + 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. @@ -1334,8 +1354,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; @@ -2081,8 +2100,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; @@ -2313,7 +2331,7 @@ static int decode_chunks(AVCodecContext *avctx, s2->error_count += s2->thread_context[i]->error_count; } - if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) + if (uses_vdpau(avctx)) ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); if (slice_end(avctx, picture)) { @@ -2472,7 +2490,7 @@ static int decode_chunks(AVCodecContext *avctx, return -1; } - if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) { + if (uses_vdpau(avctx)) { s->slice_count++; break; } diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index bd721e8f8e..55b2110c02 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -369,4 +369,40 @@ void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, render->bitstream_buffers_used = 0; } +// Only dummy functions for now +static int vdpau_mpeg2_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + return 0; +} + +static int vdpau_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + return 0; +} + +static int vdpau_mpeg2_end_frame(AVCodecContext *avctx) +{ + return 0; +} + +AVHWAccel ff_mpeg1_vdpau_hwaccel = { + .name = "mpeg1_vdpau", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG1VIDEO, + .pix_fmt = PIX_FMT_VDPAU_MPEG1, + .start_frame = vdpau_mpeg2_start_frame, + .end_frame = vdpau_mpeg2_end_frame, + .decode_slice = vdpau_mpeg2_decode_slice, +}; + +AVHWAccel ff_mpeg2_vdpau_hwaccel = { + .name = "mpeg2_vdpau", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG2VIDEO, + .pix_fmt = PIX_FMT_VDPAU_MPEG2, + .start_frame = vdpau_mpeg2_start_frame, + .end_frame = vdpau_mpeg2_end_frame, + .decode_slice = vdpau_mpeg2_decode_slice, +}; + /* @}*/