[PATCH] vdpau: Remove last traces of old ffmpeg vdpau api
From: Philip Langdale <philipl@cloudera.com> mplayer was switched to the new api a while ago, but retained traces of it in a few places - primarily through retaining vdpau_render_state as a trivial wrapper for a VdpVideoSurface. This change removes all these remaining traces. Signed-off-by: Philip Langdale <philipl@overt.org> --- fmt-conversion.c | 6 ---- libmpcodecs/img_format.h | 3 +- libmpcodecs/vd_ffmpeg.c | 13 +++------ libvo/vo_vdpau.c | 75 +++++++++++++++++++++++++----------------------- 4 files changed, 45 insertions(+), 52 deletions(-) diff --git a/fmt-conversion.c b/fmt-conversion.c index 0cf2bda..e51c29b 100644 --- a/fmt-conversion.c +++ b/fmt-conversion.c @@ -137,12 +137,6 @@ static const struct { { IMGFMT_444P, AV_PIX_FMT_YUVJ444P }, { IMGFMT_440P, AV_PIX_FMT_YUVJ440P }, { IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC }, - { 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 } }; diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h index 68581f5..582ecee 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -20,6 +20,7 @@ #define MPLAYER_IMG_FORMAT_H #include "config.h" +#include <inttypes.h> /* RGB/BGR Formats */ @@ -302,7 +303,7 @@ typedef struct { } vo_mpegpes_t; struct vdpau_frame_data { - struct vdpau_render_state *render_state; + uint32_t surface; const void *info; unsigned bitstream_buffers_used; const void *bitstream_buffers; diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index c515d0a..f1a57b9 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -216,7 +216,7 @@ static int vdpau_render_wrapper(AVCodecContext *s, AVFrame *f, sh_video_t *sh = s->opaque; struct vdpau_frame_data data; uint8_t *planes[4] = {(void *)&data}; - data.render_state = mpi->priv; + data.surface = (uintptr_t)mpi->priv; data.info = info; data.bitstream_buffers_used = count; data.bitstream_buffers = buffers; @@ -558,8 +558,7 @@ static void draw_slice(struct AVCodecContext *s, } #if CONFIG_VDPAU if (mpi && IMGFMT_IS_VDPAU(mpi->imgfmt)) { - struct vdpau_render_state *render = mpi->priv; - vdpau_render_wrapper(s, src, &render->info, render->bitstream_buffers_used, render->bitstream_buffers); + mp_msg(MSGT_DECVIDEO, MSGL_FATAL, "BUG in FFmpeg, draw_slice called for old-style VDPAU!\n"); return; } #endif @@ -764,9 +763,9 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){ } #if CONFIG_VDPAU if (ctx->use_hwaccel) { - struct vdpau_render_state *render = mpi->priv; + VdpVideoSurface surface = (uintptr_t)mpi->priv; avctx->draw_horiz_band= NULL; - mpi->planes[3] = render->surface; + mpi->planes[3] = surface; } #endif #if CONFIG_XVMC @@ -1128,10 +1127,6 @@ static enum AVPixelFormat get_format(struct AVCodecContext *avctx, if (fmt[i] == ctx->pix_fmt) return ctx->pix_fmt; for(i=0;fmt[i]!=AV_PIX_FMT_NONE;i++){ - // it is incorrect of FFmpeg to even offer these, filter them out - if(!(avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && - (fmt[i] == AV_PIX_FMT_VDPAU_MPEG1 || fmt[i] == AV_PIX_FMT_VDPAU_MPEG2)) - continue; imgfmt = pixfmt2imgfmt2(fmt[i], avctx->codec_id); if(!IMGFMT_IS_HWACCEL(imgfmt) || !is_in_format_list(sh, imgfmt)) continue; mp_msg(MSGT_DECVIDEO, MSGL_V, MSGTR_MPCODECS_TryingPixfmt, i); diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index f9a8057..322a66c 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -174,7 +174,7 @@ static VdpRect src_rect_vid; static VdpRect out_rect_vid; static int border_l, border_r, border_t, border_b; -static struct vdpau_render_state surface_render[MAX_VIDEO_SURFACES]; +static VdpVideoSurface surface_render[MAX_VIDEO_SURFACES]; static int surface_num; static int vid_surface_num; static uint32_t vid_width, vid_height; @@ -251,7 +251,7 @@ static void video_to_output_surface(void) return; if (deint < 2 || deint_surfaces[0] == VDP_INVALID_HANDLE) - push_deint_surface(surface_render[vid_surface_num].surface); + push_deint_surface(surface_render[vid_surface_num]); for (i = 0; i <= !!(deint > 1); i++) { int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; @@ -274,12 +274,12 @@ static void video_to_output_surface(void) vdp_st = vdp_video_mixer_render(video_mixer, VDP_INVALID_HANDLE, 0, field, 2, deint_surfaces + 1, deint_surfaces[0], - 1, &surface_render[vid_surface_num].surface, + 1, &surface_render[vid_surface_num], &src_rect_vid, output_surface, NULL, &out_rect_vid, 0, NULL); CHECK_ST_WARNING("Error when calling vdp_video_mixer_render") - push_deint_surface(surface_render[vid_surface_num].surface); + push_deint_surface(surface_render[vid_surface_num]); } } @@ -579,11 +579,11 @@ static void free_video_specific(void) } for (i = 0; i < MAX_VIDEO_SURFACES; i++) { - if (surface_render[i].surface != VDP_INVALID_HANDLE) { - vdp_st = vdp_video_surface_destroy(surface_render[i].surface); + if (surface_render[i] != VDP_INVALID_HANDLE) { + vdp_st = vdp_video_surface_destroy(surface_render[i]); CHECK_ST_WARNING("Error when calling vdp_video_surface_destroy") } - surface_render[i].surface = VDP_INVALID_HANDLE; + surface_render[i] = VDP_INVALID_HANDLE; } if (video_mixer != VDP_INVALID_HANDLE) { @@ -620,7 +620,7 @@ static int create_vdp_decoder(uint32_t format, uint32_t width, uint32_t height, case IMGFMT_VDPAU_MPEG4: vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; break; -#ifdef VDP_DECODER_PROFILE_HEVC_MAIN; +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN case IMGFMT_VDPAU_HEVC: vdp_decoder_profile = VDP_DECODER_PROFILE_HEVC_MAIN; mp_msg(MSGT_VO, MSGL_V, "[vdpau] Creating HEVC hardware decoder for %d reference frames.\n", max_refs); @@ -647,7 +647,7 @@ static void mark_vdpau_objects_uninitialized(void) int i; for (i = 0; i < MAX_VIDEO_SURFACES; i++) - surface_render[i].surface = VDP_INVALID_HANDLE; + surface_render[i] = VDP_INVALID_HANDLE; vdp_flip_queue = VDP_INVALID_HANDLE; vdp_flip_target = VDP_INVALID_HANDLE; for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) @@ -1015,7 +1015,7 @@ static void flip_page(void) { VdpStatus vdp_st; mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n", - surface_render[vid_surface_num].surface, output_surfaces[surface_num]); + surface_render[vid_surface_num], output_surfaces[surface_num]); if (handle_preemption() < 0) return; @@ -1055,34 +1055,45 @@ static int draw_slice(uint8_t *image[], int stride[], int w, int h, && !create_vdp_decoder(image_format, vid_width, vid_height, max_refs)) return VO_FALSE; - vdp_st = vdp_decoder_render(decoder, rndr->render_state->surface, rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); + vdp_st = vdp_decoder_render(decoder, rndr->surface, rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); CHECK_ST_WARNING("Failed VDPAU decoder rendering"); return VO_TRUE; } +static int get_surface_idx(VdpVideoSurface surface) +{ + int i; + for (i = 0; i < MAX_VIDEO_SURFACES; i++) { + if (surface == surface_render[i]) { + return i; + } + } + mp_msg(MSGT_VO, MSGL_FATAL, "Unknown VdpVideoSurface %u!\n", surface); + return -1; +} -static struct vdpau_render_state *get_surface(int number) +static VdpVideoSurface get_surface(int number) { if (number >= MAX_VIDEO_SURFACES) - return NULL; - if (surface_render[number].surface == VDP_INVALID_HANDLE) { + return VDP_INVALID_HANDLE; + if (surface_render[number] == VDP_INVALID_HANDLE) { VdpStatus vdp_st; vdp_st = vdp_video_surface_create(vdp_device, vdp_chroma_type, vid_width, vid_height, - &surface_render[number].surface); + &surface_render[number]); CHECK_ST_WARNING("Error when calling vdp_video_surface_create") if (vdp_st != VDP_STATUS_OK) - return NULL; + return VDP_INVALID_HANDLE; } - mp_msg(MSGT_VO, MSGL_DBG2, "VID CREATE: %u\n", surface_render[number].surface); - return &surface_render[number]; + mp_msg(MSGT_VO, MSGL_DBG2, "VID CREATE: %u\n", surface_render[number]); + return surface_render[number]; } static uint32_t draw_image(mp_image_t *mpi) { if (IMGFMT_IS_VDPAU(image_format)) { - struct vdpau_render_state *rndr = mpi->priv; - vid_surface_num = rndr - surface_render; + VdpVideoSurface surface = (uintptr_t)mpi->priv; + vid_surface_num = get_surface_idx(surface); mpi->usage_count++; if (deint_mpi[1]) deint_mpi[1]->usage_count--; @@ -1098,12 +1109,12 @@ static uint32_t draw_image(mp_image_t *mpi) } else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) { VdpStatus vdp_st; void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]}; - struct vdpau_render_state *rndr = get_surface(deint_counter); + VdpVideoSurface surface = get_surface(deint_counter); deint_counter = (deint_counter + 1) % 3; - vid_surface_num = rndr - surface_render; + vid_surface_num = get_surface_idx(surface); if (image_format == IMGFMT_NV12) destdata[1] = destdata[2]; - vdp_st = vdp_video_surface_put_bits_y_cb_cr(rndr->surface, + vdp_st = vdp_video_surface_put_bits_y_cb_cr(surface, vdp_pixel_format, (const void *const*)destdata, mpi->stride); // pitch @@ -1120,7 +1131,7 @@ static uint32_t draw_image(mp_image_t *mpi) static uint32_t get_image(mp_image_t *mpi) { - struct vdpau_render_state *rndr; + VdpVideoSurface surface; // no dr for non-decoding for now if (!IMGFMT_IS_VDPAU(image_format)) @@ -1128,8 +1139,8 @@ static uint32_t get_image(mp_image_t *mpi) if (mpi->type != MP_IMGTYPE_NUMBERED) return VO_FALSE; - rndr = get_surface(mpi->number); - if (!rndr) { + surface = get_surface(mpi->number); + if (surface == VDP_INVALID_HANDLE) { mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] no surfaces available in get_image\n"); // TODO: this probably breaks things forever, provide a dummy buffer? return VO_FALSE; @@ -1138,9 +1149,9 @@ static uint32_t get_image(mp_image_t *mpi) mpi->stride[0] = mpi->stride[1] = mpi->stride[2] = 0; mpi->planes[0] = mpi->planes[1] = mpi->planes[2] = NULL; // hack to get around a check and to avoid a special-case in vd_ffmpeg.c - mpi->planes[0] = (void *)rndr; + mpi->planes[0] = (void *)(uintptr_t)surface; mpi->num_planes = 1; - mpi->priv = rndr; + mpi->priv = (void *)(uintptr_t)surface; return VO_TRUE; } @@ -1214,18 +1225,10 @@ static void DestroyVdpauObjects(void) static void uninit(void) { - int i; - if (!vo_config_count) return; visible_buf = 0; - for (i = 0; i < MAX_VIDEO_SURFACES; i++) { - // Allocated in ff_vdpau_add_data_chunk() - av_freep(&surface_render[i].bitstream_buffers); - surface_render[i].bitstream_buffers_allocated = 0; - } - /* Destroy all vdpau objects */ DestroyVdpauObjects(); -- 2.1.4
On Fri, 21 Aug 2015 20:11:09 -0700 Philip Langdale <philipl@overt.org> wrote:
From: Philip Langdale <philipl@cloudera.com>
mplayer was switched to the new api a while ago, but retained traces of it in a few places - primarily through retaining vdpau_render_state as a trivial wrapper for a VdpVideoSurface.
This change removes all these remaining traces.
Hi, thanks for your patch. I attached a new version with this changes: - store the surface as VdpVideoSurface instead of uint32_t - in vd_ffmpeg renames use_hwaccel to use_vdpau for clarity - some additional cleanup in vd_ffmpeg - remove the ff*vdpauold codecs from codec.conf Work for me with and without vdpau. I haven't checked compilation without vdpau, but should be ok. Ciao, Roberto
On Sun, 23 Aug 2015 01:59:37 +0200 Roberto Togni <rxt@rtogni.it> wrote:
On Fri, 21 Aug 2015 20:11:09 -0700 Philip Langdale <philipl@overt.org> wrote:
From: Philip Langdale <philipl@cloudera.com>
mplayer was switched to the new api a while ago, but retained traces of it in a few places - primarily through retaining vdpau_render_state as a trivial wrapper for a VdpVideoSurface.
This change removes all these remaining traces.
Hi, thanks for your patch.
I attached a new version with this changes: - store the surface as VdpVideoSurface instead of uint32_t - in vd_ffmpeg renames use_hwaccel to use_vdpau for clarity - some additional cleanup in vd_ffmpeg - remove the ff*vdpauold codecs from codec.conf
Work for me with and without vdpau. I haven't checked compilation without vdpau, but should be ok.
Ciao, Roberto
Looks fine. Thanks. --phil
On Sat, 22 Aug 2015 19:24:39 -0700 Philip Langdale <philipl@overt.org> wrote:
On Sun, 23 Aug 2015 01:59:37 +0200 Roberto Togni <rxt@rtogni.it> wrote:
On Fri, 21 Aug 2015 20:11:09 -0700 Philip Langdale <philipl@overt.org> wrote:
From: Philip Langdale <philipl@cloudera.com>
mplayer was switched to the new api a while ago, but retained traces of it in a few places - primarily through retaining vdpau_render_state as a trivial wrapper for a VdpVideoSurface.
This change removes all these remaining traces.
Hi, thanks for your patch.
I attached a new version with this changes: - store the surface as VdpVideoSurface instead of uint32_t - in vd_ffmpeg renames use_hwaccel to use_vdpau for clarity - some additional cleanup in vd_ffmpeg - remove the ff*vdpauold codecs from codec.conf
Work for me with and without vdpau. I haven't checked compilation without vdpau, but should be ok.
Ciao, Roberto
Looks fine. Thanks.
Patch applied. Ciao, Roberto
Hi! [...] I sincerely hope that one day somebody will explain to me why working, tested code has to be removed because of code that we cannot test because nobody has the tools originally used. Carl Eugen
On Sat, 3 Oct 2015 22:25:20 +0200 Carl Eugen Hoyos <cehoyos@ag.or.at> wrote:
Hi!
[...]
I sincerely hope that one day somebody will explain to me why working, tested code has to be removed because of code that we cannot test because nobody has the tools originally used.
Hi, I have no problem if you want to restore the old vdpau decoder in MPlayer, but I don't have the resources to maintain a fork of all the codecs involved. If anybody can came up with a clean patch to support it (with FFmpeg 2.8 or by importing the code) that works along with the new decoder, and he's willing to maintain it so that compilation always works with FFmpeg git, he's welcome to do it. Ciao, Roberto
On Sat, 3 Oct 2015 22:25:20 +0200 Carl Eugen Hoyos <cehoyos@ag.or.at> wrote:
Hi!
[...]
I sincerely hope that one day somebody will explain to me why working, tested code has to be removed because of code that we cannot test because nobody has the tools originally used.
Because FFmpeg now has a better API that isn't as ridiculous as the old API, and fits in well with the other hwaccel APIs. But if you have so strong feelings about this, you really should have talked to the author of the new vdpau API. I plan going forward with my FFmpeg patch to completely remove the implementation of the old API.
wm4 <nfxjfg <at> googlemail.com> writes:
I sincerely hope that one day somebody will explain to me why working, tested code has to be removed because of code that we cannot test because nobody has the tools originally used.
Because FFmpeg now has a better API that isn't as ridiculous
How do you define better? Afair, and as far as you confirmed, many bugs were found in the new API. Why are you so sure we already found them all?
as the old API, and fits in well with the other hwaccel APIs.
You mean the "API" that needs new special code (and new callbacks) for every new hardware acceleration because unfortunately they do not share concepts?
But if you have so strong feelings about this, you really should have talked to the author of the new vdpau API.
He has worked so hard for so many years to make sure I don't talk to him anymore, I don't want to spoil his efforts.
I plan going forward with my FFmpeg patch to completely remove the implementation of the old API.
Please don't! Carl Eugen
On Sun, 4 Oct 2015 11:26:28 +0000 (UTC) Carl Eugen Hoyos <cehoyos@ag.or.at> wrote:
wm4 <nfxjfg <at> googlemail.com> writes:
But if you have so strong feelings about this, you really should have talked to the author of the new vdpau API.
He has worked so hard for so many years to make sure I don't talk to him anymore, I don't want to spoil his efforts.
Well, if you refuse to communicate, you got to live with the results, even if they're not ideal for you.
participants (4)
-
Carl Eugen Hoyos -
Philip Langdale -
Roberto Togni -
wm4