Mercurial > mplayer.hg
changeset 36322:d649e84ea8d5
Make VDPAU support work again with latest FFmpeg.
author | reimar |
---|---|
date | Sun, 11 Aug 2013 18:28:58 +0000 |
parents | 9c5b06130385 |
children | 335349ca2137 |
files | etc/codecs.conf fmt-conversion.c libmpcodecs/img_format.h libmpcodecs/vd_ffmpeg.c libvo/vo_vdpau.c |
diffstat | 5 files changed, 81 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/codecs.conf Sat Aug 10 04:02:17 2013 +0000 +++ b/etc/codecs.conf Sun Aug 11 18:28:58 2013 +0000 @@ -542,7 +542,7 @@ fourcc m2v1,m1v1 fourcc "m1v " driver ffmpeg - dll "mpegvideo_vdpau" + dll "mpegvideo" out VDPAU_MPEG1 out VDPAU_MPEG2 @@ -1249,7 +1249,7 @@ status buggy fourcc WMV3,wmv3 driver ffmpeg - dll wmv3_vdpau + dll wmv3 out VDPAU_WMV3 videocodec ffwmv3crystalhd @@ -1275,7 +1275,7 @@ fourcc WVC1,wvc1,WMVA fourcc vc-1,VC-1 driver ffmpeg - dll vc1_vdpau + dll vc1 out VDPAU_VC1 videocodec ffvc1crystalhd @@ -1348,7 +1348,7 @@ fourcc Q264,V264 format 0x10000005 driver ffmpeg - dll h264_vdpau + dll h264 out VDPAU_H264 videocodec ffh264crystalhd @@ -1486,7 +1486,7 @@ fourcc DreX,DM4V,LMP4,DP02 fourcc QMP4 driver ffmpeg - dll mpeg4_vdpau + dll mpeg4 out VDPAU_MPEG4 videocodec ffodivxcrystalhd
--- a/fmt-conversion.c Sat Aug 10 04:02:17 2013 +0000 +++ b/fmt-conversion.c Sun Aug 11 18:28:58 2013 +0000 @@ -137,12 +137,6 @@ { IMGFMT_XVMC_MOCO_MPEG2, AV_PIX_FMT_XVMC_MPEG2_MC }, { IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC_MPEG2_IDCT }, - { IMGFMT_VDPAU_MPEG1, AV_PIX_FMT_VDPAU_MPEG1 }, - { IMGFMT_VDPAU_MPEG2, AV_PIX_FMT_VDPAU_MPEG2 }, - { IMGFMT_VDPAU_H264, AV_PIX_FMT_VDPAU_H264 }, - { IMGFMT_VDPAU_WMV3, AV_PIX_FMT_VDPAU_WMV3 }, - { IMGFMT_VDPAU_VC1, AV_PIX_FMT_VDPAU_VC1 }, - { IMGFMT_VDPAU_MPEG4, AV_PIX_FMT_VDPAU_MPEG4 }, { 0, AV_PIX_FMT_NONE } }; @@ -150,6 +144,7 @@ { int i; enum AVPixelFormat pix_fmt; + if (IMGFMT_IS_VDPAU(fmt)) return AV_PIX_FMT_VDPAU; for (i = 0; conversion_map[i].fmt; i++) if (conversion_map[i].fmt == fmt) break;
--- a/libmpcodecs/img_format.h Sat Aug 10 04:02:17 2013 +0000 +++ b/libmpcodecs/img_format.h Sun Aug 11 18:28:58 2013 +0000 @@ -296,6 +296,13 @@ int timestamp; // pts, 90000 Hz counter based } vo_mpegpes_t; +struct vdpau_frame_data { + struct vdpau_render_state *render_state; + const void *info; + unsigned bitstream_buffers_used; + const void *bitstream_buffers; +}; + const char *vo_format_name(int format); /**
--- a/libmpcodecs/vd_ffmpeg.c Sat Aug 10 04:02:17 2013 +0000 +++ b/libmpcodecs/vd_ffmpeg.c Sun Aug 11 18:28:58 2013 +0000 @@ -36,6 +36,10 @@ #include "vd_internal.h" +#if CONFIG_VDPAU +#include "libavcodec/vdpau.h" +#endif + static const vd_info_t info = { "FFmpeg's libavcodec codec family", "ffmpeg", @@ -201,19 +205,49 @@ return CONTROL_UNKNOWN; } +#if CONFIG_VDPAU +static int vdpau_render_wrapper(AVCodecContext *s, AVFrame *f, + const VdpPictureInfo *info, uint32_t count, const VdpBitstreamBuffer *buffers) +{ + mp_image_t *mpi = f->opaque; + sh_video_t *sh = s->opaque; + struct vdpau_frame_data data; + uint8_t *planes[4] = {(void *)&data}; + data.render_state = mpi->priv; + data.info = info; + data.bitstream_buffers_used = count; + data.bitstream_buffers = buffers; + mpcodecs_draw_slice(sh, planes, NULL, sh->disp_w, sh->disp_h, 0, 0); + return 0; +} +#endif + +static int pixfmt2imgfmt2(enum AVPixelFormat fmt, enum AVCodecID cid) +{ + if (fmt == AV_PIX_FMT_VDPAU) + switch (cid) { + case AV_CODEC_ID_H264: return IMGFMT_VDPAU_H264; + case AV_CODEC_ID_MPEG1VIDEO: return IMGFMT_VDPAU_MPEG1; + case AV_CODEC_ID_MPEG2VIDEO: return IMGFMT_VDPAU_MPEG2; + case AV_CODEC_ID_MPEG4: return IMGFMT_VDPAU_MPEG4; + case AV_CODEC_ID_WMV3: return IMGFMT_VDPAU_WMV3; + case AV_CODEC_ID_VC1: return IMGFMT_VDPAU_VC1; + } + return pixfmt2imgfmt(fmt); +} + static void set_format_params(struct AVCodecContext *avctx, enum AVPixelFormat fmt) { int imgfmt; if (fmt == PIX_FMT_NONE) return; - imgfmt = pixfmt2imgfmt(fmt); + imgfmt = pixfmt2imgfmt2(fmt, avctx->codec_id); if (IMGFMT_IS_HWACCEL(imgfmt)) { sh_video_t *sh = avctx->opaque; vd_ffmpeg_ctx *ctx = sh->context; ctx->do_dr1 = 1; ctx->nonref_dr = 0; - ctx->do_slices = 1; // HACK: FFmpeg thread handling is a major mess and // hinders any attempt to decide on hwaccel after the // codec is open. We really want this to change, so @@ -223,9 +257,16 @@ avctx->get_buffer = get_buffer; avctx->release_buffer = release_buffer; avctx->reget_buffer = get_buffer; - avctx->draw_horiz_band = draw_slice; mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedMPEG2); - avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; + if (IMGFMT_IS_VDPAU(imgfmt)) { + avctx->draw_horiz_band = NULL; + avctx->slice_flags = 0; + ctx->do_slices = 0; + } else { + avctx->draw_horiz_band = draw_slice; + avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; + ctx->do_slices = 1; + } } else { avctx->slice_flags &= ~(SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD); } @@ -459,6 +500,7 @@ mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantCloseCodec); av_freep(&avctx->extradata); + av_freep(&avctx->hwaccel_context); av_freep(&avctx->slice_offset); } @@ -470,6 +512,7 @@ static void draw_slice(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height){ + mp_image_t *mpi = src->opaque; sh_video_t *sh = s->opaque; uint8_t *source[MP_MAX_PLANES]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2]}; int strides[MP_MAX_PLANES] = {src->linesize[0], src->linesize[1], src->linesize[2]}; @@ -477,6 +520,10 @@ mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "BUG in FFmpeg, draw_slice called with NULL pointer!\n"); return; } + if (IMGFMT_IS_VDPAU(mpi->imgfmt)) { + mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "BUG in FFmpeg, draw_slice called for VDPAU!\n"); + return; + } if (height < 0) { int i; @@ -519,7 +566,7 @@ sh->original_aspect = aspect; ctx->last_sample_aspect_ratio = avctx->sample_aspect_ratio; ctx->pix_fmt = pix_fmt; - ctx->best_csp = pixfmt2imgfmt(pix_fmt); + ctx->best_csp = pixfmt2imgfmt2(pix_fmt, avctx->codec_id); } } @@ -644,6 +691,18 @@ if(IMGFMT_IS_HWACCEL(mpi->imgfmt)) { avctx->draw_horiz_band= draw_slice; } +#if CONFIG_VDPAU + if (IMGFMT_IS_VDPAU(mpi->imgfmt)) { + struct vdpau_render_state *render = mpi->priv; + AVVDPAUContext *vdpc; + avctx->draw_horiz_band= NULL; + if (!avctx->hwaccel_context) + avctx->hwaccel_context = av_alloc_vdpaucontext(); + vdpc = avctx->hwaccel_context; + vdpc->render2 = vdpau_render_wrapper; + mpi->planes[3] = render->surface; + } +#endif #if CONFIG_XVMC if(IMGFMT_IS_XVMC(mpi->imgfmt)) { struct xvmc_pix_fmt *render = mpi->priv; //same as data[2] @@ -1000,7 +1059,7 @@ int i; for(i=0;fmt[i]!=PIX_FMT_NONE;i++){ - imgfmt = pixfmt2imgfmt(fmt[i]); + imgfmt = pixfmt2imgfmt2(fmt[i], avctx->codec_id); if(!IMGFMT_IS_HWACCEL(imgfmt)) continue; mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_TryingPixfmt, i); if(init_vo(sh, fmt[i]) >= 0) {
--- a/libvo/vo_vdpau.c Sat Aug 10 04:02:17 2013 +0000 +++ b/libvo/vo_vdpau.c Sun Aug 11 18:28:58 2013 +0000 @@ -1009,8 +1009,8 @@ int x, int y) { VdpStatus vdp_st; - struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0]; - int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2; + struct vdpau_frame_data *rndr = (struct vdpau_frame_data *)image[0]; + int max_refs = image_format == IMGFMT_VDPAU_H264 ? ((VdpPictureInfoH264 *)rndr->info)->num_ref_frames : 2; if (handle_preemption() < 0) return VO_TRUE; @@ -1021,7 +1021,7 @@ && !create_vdp_decoder(image_format, vid_width, vid_height, max_refs)) return VO_FALSE; - vdp_st = vdp_decoder_render(decoder, rndr->surface, (void *)&rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); + vdp_st = vdp_decoder_render(decoder, rndr->render_state->surface, rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); CHECK_ST_WARNING("Failed VDPAU decoder rendering"); return VO_TRUE; }