From 49d13f76ca727488de8622a8d176b5f71853bc61 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 17 Mar 2014 18:22:35 +0100 Subject: vaapi: make struct va_surface private It's not really needed to be public. Other code can just use mp_image. The only disadvantage is that the other code needs to call an accessor to get the VASurfaceID. --- video/decode/vaapi.c | 19 +++++----- video/filter/vf_vavpp.c | 22 ++++++------ video/out/gl_hwdec_vaglx.c | 2 +- video/out/vo_vaapi.c | 17 +++++---- video/vaapi.c | 86 ++++++++++++++++++++++++---------------------- video/vaapi.h | 22 ++++-------- 6 files changed, 78 insertions(+), 90 deletions(-) diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c index 82855c04eb..d9267936d0 100644 --- a/video/decode/vaapi.c +++ b/video/decode/vaapi.c @@ -170,7 +170,7 @@ static bool preallocate_surfaces(struct lavc_ctx *ctx, int num, int w, int h, for (int n = 0; n < num; n++) { reserve[n] = mp_image_pool_get(p->pool, IMGFMT_VAAPI, w, h); - out_surfaces[n] = va_surface_id_in_mp_image(reserve[n]); + out_surfaces[n] = va_surface_id(reserve[n]); if (out_surfaces[n] == VA_INVALID_ID) { MP_ERR(p, "Could not allocate surfaces.\n"); res = false; @@ -433,17 +433,14 @@ static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img) { struct priv *p = ctx->hwdec_priv; - struct va_surface *surface = va_surface_in_mp_image(img); - if (surface) { - struct mp_image *simg = va_surface_download(surface, p->sw_pool); - if (simg) { - if (!p->printed_readback_warning) { - MP_WARN(p, "Using GPU readback. This is usually inefficient.\n"); - p->printed_readback_warning = true; - } - talloc_free(img); - return simg; + struct mp_image *simg = va_surface_download(img, p->sw_pool); + if (simg) { + if (!p->printed_readback_warning) { + MP_WARN(p, "Using GPU readback. This is usually inefficient.\n"); + p->printed_readback_warning = true; } + talloc_free(img); + return simg; } return img; } diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c index a1a7d3adf0..9a797990eb 100644 --- a/video/filter/vf_vavpp.c +++ b/video/filter/vf_vavpp.c @@ -123,11 +123,12 @@ static inline int get_deint_field(struct vf_priv_s *p, int i, return !!(mpi->fields & MP_IMGFIELD_TOP_FIRST) ^ i ? VA_TOP_FIELD : VA_BOTTOM_FIELD; } -static struct mp_image *render(struct vf_instance *vf, struct va_surface *in, +static struct mp_image *render(struct vf_instance *vf, struct mp_image *in, unsigned int flags) { struct vf_priv_s *p = vf->priv; - if (!p->pipe.filters || !in) + VASurfaceID in_id = va_surface_id(in); + if (!p->pipe.filters || in_id == VA_INVALID_ID) return NULL; struct mp_image *img = mp_image_pool_get(p->pool, IMGFMT_VAAPI, in->w, in->h); if (!img) @@ -135,7 +136,7 @@ static struct mp_image *render(struct vf_instance *vf, struct va_surface *in, enum {Begun = 1, Rendered = 2}; int state = 0; do { // not a loop, just for break - VASurfaceID id = va_surface_id_in_mp_image(img); + VASurfaceID id = va_surface_id(img); if (id == VA_INVALID_ID) break; VAStatus status = vaBeginPicture(p->display, p->context, id); @@ -152,7 +153,7 @@ static struct mp_image *render(struct vf_instance *vf, struct va_surface *in, status = vaMapBuffer(p->display, buffer, (void**)¶m); if (!check_error(vf, status, "vaMapBuffer()")) break; - param->surface = in->id; + param->surface = in_id; param->surface_region = NULL; param->output_region = NULL; param->output_background_color = 0; @@ -185,10 +186,9 @@ static int process(struct vf_instance *vf, struct mp_image *in, const bool deint = p->do_deint && p->deint_type > 0; if (!update_pipeline(vf, deint) || !p->pipe.filters) // no filtering return 0; - struct va_surface *surface = va_surface_in_mp_image(in); const unsigned int csp = va_get_colorspace_flag(p->params.colorspace); const unsigned int field = get_deint_field(p, 0, in); - *out1 = render(vf, surface, field | csp); + *out1 = render(vf, in, field | csp); if (!*out1) // cannot render return 0; mp_image_copy_attributes(*out1, in); @@ -197,7 +197,7 @@ static int process(struct vf_instance *vf, struct mp_image *in, const double add = (in->pts - p->prev_pts)*0.5; if (p->prev_pts == MP_NOPTS_VALUE || add <= 0.0 || add > 0.5) // no pts, skip it return 1; - *out2 = render(vf, surface, get_deint_field(p, 1, in) | csp); + *out2 = render(vf, in, get_deint_field(p, 1, in) | csp); if (!*out2) // cannot render return 1; mp_image_copy_attributes(*out2, in); @@ -211,7 +211,7 @@ static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in) struct mp_image *out = mp_image_pool_get(p->pool, IMGFMT_VAAPI, in->w, in->h); if (!out) return NULL; - if (va_surface_upload_image(out, in) < 0) { + if (va_surface_upload(out, in) < 0) { talloc_free(out); return NULL; } @@ -222,15 +222,15 @@ static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in) static int filter_ext(struct vf_instance *vf, struct mp_image *in) { struct vf_priv_s *p = vf->priv; - struct va_surface *surface = va_surface_in_mp_image(in); - const int rt_format = surface ? surface->rt_format : VA_RT_FORMAT_YUV420; + int rt_format = in->imgfmt == IMGFMT_VAAPI ? va_surface_rt_format(in) + : VA_RT_FORMAT_YUV420; if (!p->pool || p->current_rt_format != rt_format) { talloc_free(p->pool); p->pool = mp_image_pool_new(20); va_pool_set_allocator(p->pool, p->va, rt_format); p->current_rt_format = rt_format; } - if (!surface) { + if (in->imgfmt != IMGFMT_VAAPI) { struct mp_image *tmp = upload(vf, in); talloc_free(in); in = tmp; diff --git a/video/out/gl_hwdec_vaglx.c b/video/out/gl_hwdec_vaglx.c index 47e7bb6e07..278718c67a 100644 --- a/video/out/gl_hwdec_vaglx.c +++ b/video/out/gl_hwdec_vaglx.c @@ -113,7 +113,7 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, return -1; status = vaCopySurfaceGLX(p->display, p->vaglx_surface, - va_surface_id_in_mp_image(hw_image), + va_surface_id(hw_image), va_get_colorspace_flag(hw_image->colorspace)); if (!CHECK_VA_STATUS(p, "vaCopySurfaceGLX()")) return -1; diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index fc9e93b2c4..266313d4ca 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -137,7 +137,7 @@ static bool alloc_swdec_surfaces(struct priv *p, int w, int h, int imgfmt) free_video_specific(p); for (int i = 0; i < MAX_OUTPUT_SURFACES; i++) { p->swdec_surfaces[i] = mp_image_pool_get(p->pool, IMGFMT_VAAPI, w, h); - if (va_surface_image_alloc_imgfmt(p->swdec_surfaces[i], imgfmt) < 0) + if (va_surface_alloc_imgfmt(p->swdec_surfaces[i], imgfmt) < 0) return false; } return true; @@ -184,7 +184,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi) { VAStatus status; - VASurfaceID surface = va_surface_id_in_mp_image(mpi); + VASurfaceID surface = va_surface_id(mpi); if (surface == VA_INVALID_ID) { if (!p->black_surface) { int w = p->image_params.w, h = p->image_params.h; @@ -194,12 +194,12 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi) if (p->black_surface) { struct mp_image *img = mp_image_alloc(fmt, w, h); mp_image_clear(img, 0, 0, w, h); - if (va_surface_upload_image(p->black_surface, img) < 0) + if (va_surface_upload(p->black_surface, img) < 0) mp_image_unrefp(&p->black_surface); talloc_free(img); } } - surface = va_surface_id_in_mp_image(p->black_surface); + surface = va_surface_id(p->black_surface); } int fields = mpi ? mpi->fields : 0; @@ -273,7 +273,7 @@ static void draw_image(struct vo *vo, struct mp_image *mpi) if (mpi->imgfmt != IMGFMT_VAAPI) { struct mp_image *dst = p->swdec_surfaces[p->output_surface]; - if (!dst || va_surface_upload_image(dst, mpi) < 0) { + if (!dst || va_surface_upload(dst, mpi) < 0) { MP_WARN(vo, "Could not upload surface.\n"); return; } @@ -286,11 +286,10 @@ static void draw_image(struct vo *vo, struct mp_image *mpi) static struct mp_image *get_screenshot(struct priv *p) { - struct va_surface *surface = - va_surface_in_mp_image(p->output_surfaces[p->visible_surface]); - if (!surface) + struct mp_image *hwimg = p->output_surfaces[p->visible_surface]; + if (!hwimg) return NULL; - struct mp_image *img = va_surface_download(surface, NULL); + struct mp_image *img = va_surface_download(hwimg, NULL); if (!img) return NULL; struct mp_image_params params = p->image_params; diff --git a/video/vaapi.c b/video/vaapi.c index edb16ffd48..1574f3bab9 100644 --- a/video/vaapi.c +++ b/video/vaapi.c @@ -159,6 +159,13 @@ VAImageFormat *va_image_format_from_imgfmt(const struct va_image_formats *format return NULL; } +struct va_surface { + VASurfaceID id; // VA_INVALID_ID if unallocated + int w, h, rt_format; // parameters of allocated image (0/0/-1 unallocated) + + struct va_surface_priv *p; +}; + typedef struct va_surface_priv { struct mp_vaapi_ctx *ctx; VADisplay display; @@ -166,6 +173,24 @@ typedef struct va_surface_priv { bool is_derived; // is image derived by vaDeriveImage()? } va_surface_priv_t; +VASurfaceID va_surface_id(struct mp_image *mpi) +{ + return mpi && mpi->imgfmt == IMGFMT_VAAPI ? + (VASurfaceID)(uintptr_t)mpi->planes[3] : VA_INVALID_ID; +} + +static struct va_surface *va_surface_in_mp_image(struct mp_image *mpi) +{ + return mpi && mpi->imgfmt == IMGFMT_VAAPI ? + (struct va_surface*)mpi->planes[0] : NULL; +} + +int va_surface_rt_format(struct mp_image *mpi) +{ + struct va_surface *surface = va_surface_in_mp_image(mpi); + return surface ? surface->rt_format : 0; +} + static void va_surface_destroy(struct va_surface *surface) { if (!surface) @@ -262,7 +287,7 @@ static VAImage *va_surface_image_alloc(struct va_surface *surface, // img must be a VAAPI surface; make sure its internal VAImage is allocated // to a format corresponding to imgfmt (or return an error). -int va_surface_image_alloc_imgfmt(struct mp_image *img, int imgfmt) +int va_surface_alloc_imgfmt(struct mp_image *img, int imgfmt) { struct va_surface *surface = va_surface_in_mp_image(img); if (!surface) @@ -276,23 +301,6 @@ int va_surface_image_alloc_imgfmt(struct mp_image *img, int imgfmt) return 0; } -VASurfaceID va_surface_id_in_mp_image(const struct mp_image *mpi) -{ - return mpi && mpi->imgfmt == IMGFMT_VAAPI ? - (VASurfaceID)(uintptr_t)mpi->planes[3] : VA_INVALID_ID; -} - -struct va_surface *va_surface_in_mp_image(struct mp_image *mpi) -{ - return mpi && mpi->imgfmt == IMGFMT_VAAPI ? - (struct va_surface*)mpi->planes[0] : NULL; -} - -VASurfaceID va_surface_id(const struct va_surface *surface) -{ - return surface ? surface->id : VA_INVALID_ID; -} - bool va_image_map(struct mp_vaapi_ctx *ctx, VAImage *image, struct mp_image *mpi) { int imgfmt = va_fourcc_to_imgfmt(image->format.fourcc); @@ -326,44 +334,37 @@ bool va_image_unmap(struct mp_vaapi_ctx *ctx, VAImage *image) return CHECK_VA_STATUS(ctx, "vaUnmapBuffer()"); } -bool va_surface_upload(struct va_surface *surface, struct mp_image *mpi) +// va_dst: copy destination, must be IMGFMT_VAAPI +// sw_src: copy source, must be a software surface +int va_surface_upload(struct mp_image *va_dst, struct mp_image *sw_src) { + struct va_surface *surface = va_surface_in_mp_image(va_dst); + if (!surface) + return -1; va_surface_priv_t *p = surface->p; VAImageFormat *format = - va_image_format_from_imgfmt(p->ctx->image_formats, mpi->imgfmt); + va_image_format_from_imgfmt(p->ctx->image_formats, sw_src->imgfmt); if (!format) - return false; + return -1; if (!va_surface_image_alloc(surface, format)) - return false; + return -1; struct mp_image img; if (!va_image_map(p->ctx, &p->image, &img)) - return false; - mp_image_copy(&img, mpi); + return -1; + mp_image_copy(&img, sw_src); va_image_unmap(p->ctx, &p->image); if (!p->is_derived) { VAStatus status = vaPutImage2(p->display, surface->id, p->image.image_id, - 0, 0, mpi->w, mpi->h, - 0, 0, mpi->w, mpi->h); + 0, 0, sw_src->w, sw_src->h, + 0, 0, sw_src->w, sw_src->h); if (!CHECK_VA_STATUS(p->ctx, "vaPutImage()")) - return false; + return -1; } - return true; -} - -// va_dst: copy destination, must be IMGFMT_VAAPI -// sw_src: copy source, must be a software surface -int va_surface_upload_image(struct mp_image *va_dst, struct mp_image *sw_src) -{ - struct va_surface *surface = va_surface_in_mp_image(va_dst); - if (!surface) - return -1; - if (!va_surface_upload(surface, sw_src)) - return -1; return 0; } @@ -402,11 +403,12 @@ static struct mp_image *try_download(struct va_surface *surface, } // pool is optional (used for allocating returned images). -// Note: unlike va_surface_upload(), this will attempt to (re)create the -// VAImage stored with the va_surface. -struct mp_image *va_surface_download(struct va_surface *surface, +struct mp_image *va_surface_download(struct mp_image *src, struct mp_image_pool *pool) { + struct va_surface *surface = va_surface_in_mp_image(src); + if (!surface) + return NULL; struct mp_vaapi_ctx *ctx = surface->p->ctx; VAStatus status = vaSyncSurface(surface->p->display, surface->id); if (!CHECK_VA_STATUS(ctx, "vaSyncSurface()")) diff --git a/video/vaapi.h b/video/vaapi.h index 0396d01320..c555161999 100644 --- a/video/vaapi.h +++ b/video/vaapi.h @@ -81,16 +81,8 @@ struct mp_vaapi_ctx { struct va_image_formats *image_formats; }; -struct va_surface_pool; struct va_image_formats; -struct va_surface { - VASurfaceID id; // VA_INVALID_ID if unallocated - int w, h, rt_format; // parameters of allocated image (0/0/-1 unallocated) - - struct va_surface_priv *p; -}; - bool check_va_status(struct mp_log *log, VAStatus status, const char *msg); #define CHECK_VA_STATUS(ctx, msg) check_va_status((ctx)->log, status, msg) @@ -109,14 +101,12 @@ bool va_image_unmap(struct mp_vaapi_ctx *ctx, VAImage *image void va_pool_set_allocator(struct mp_image_pool *pool, struct mp_vaapi_ctx *ctx, int rt_format); -struct va_surface * va_surface_in_mp_image(struct mp_image *mpi); -VASurfaceID va_surface_id(const struct va_surface *surface); -VASurfaceID va_surface_id_in_mp_image(const struct mp_image *mpi); -bool va_surface_upload(struct va_surface *surface, struct mp_image *mpi); -struct mp_image * va_surface_download(struct va_surface *surface, - struct mp_image_pool *pool); +VASurfaceID va_surface_id(struct mp_image *mpi); +int va_surface_rt_format(struct mp_image *mpi); +struct mp_image *va_surface_download(struct mp_image *src, + struct mp_image_pool *pool); -int va_surface_image_alloc_imgfmt(struct mp_image *img, int imgfmt); -int va_surface_upload_image(struct mp_image *va_dst, struct mp_image *sw_src); +int va_surface_alloc_imgfmt(struct mp_image *img, int imgfmt); +int va_surface_upload(struct mp_image *va_dst, struct mp_image *sw_src); #endif -- cgit v1.2.3