From 70af7ab8e55e117e62303b407f2886f29b5500d1 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 21 Dec 2013 18:11:01 +0100 Subject: vaapi: mp_msg conversions This ended up a little bit messy. In order to get a mp_log everywhere, mostly make use of the fact that va_surface already references global state anyway. --- video/decode/vaapi.c | 50 ++++++++++++++-------------- video/filter/vf_vavpp.c | 65 ++++++++++++++++++++---------------- video/out/gl_hwdec_vaglx.c | 10 +++--- video/out/vo_vaapi.c | 32 +++++++++--------- video/vaapi.c | 82 ++++++++++++++++++++++++---------------------- video/vaapi.h | 19 ++++++----- 6 files changed, 135 insertions(+), 123 deletions(-) diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c index 8a9ff4ae50..d4b1c41840 100644 --- a/video/decode/vaapi.c +++ b/video/decode/vaapi.c @@ -55,6 +55,7 @@ #define MAX_SURFACES (MAX_DECODER_SURFACES + ADDTIONAL_SURFACES) struct priv { + struct mp_log *log; struct mp_vaapi_ctx *ctx; VADisplay display; Display *x11_display; @@ -166,7 +167,7 @@ static bool preallocate_surfaces(struct lavc_ctx *ctx, int num) { struct priv *p = ctx->hwdec_priv; if (!va_surface_pool_reserve(p->pool, num, p->w, p->h)) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Could not allocate surfaces.\n"); + MP_ERR(p, "Could not allocate surfaces.\n"); return false; } for (int i = 0; i < num; i++) { @@ -218,57 +219,55 @@ static int create_decoder(struct lavc_ctx *ctx) const struct hwdec_profile_entry *pe = hwdec_find_profile(ctx, profiles); if (!pe) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Unsupported codec or profile.\n"); + MP_ERR(p, "Unsupported codec or profile.\n"); goto error; } int num_profiles = vaMaxNumProfiles(p->display); VAProfile *va_profiles = talloc_zero_array(tmp, VAProfile, num_profiles); status = vaQueryConfigProfiles(p->display, va_profiles, &num_profiles); - if (!check_va_status(status, "vaQueryConfigProfiles()")) + if (!CHECK_VA_STATUS(p, "vaQueryConfigProfiles()")) goto error; - mp_msg(MSGT_VO, MSGL_DBG2, "[vaapi] %d profiles available:\n", num_profiles); + MP_DBG(p, "%d profiles available:\n", num_profiles); for (int i = 0; i < num_profiles; i++) - mp_msg(MSGT_VO, MSGL_DBG2, " %s\n", str_va_profile(va_profiles[i])); + MP_DBG(p, " %s\n", str_va_profile(va_profiles[i])); VAProfile va_profile = pe->hw_profile; if (!has_profile(va_profiles, num_profiles, va_profile)) { - mp_msg(MSGT_VO, MSGL_ERR, - "[vaapi] Decoder profile '%s' not available.\n", + MP_ERR(p, "Decoder profile '%s' not available.\n", str_va_profile(va_profile)); goto error; } - mp_msg(MSGT_VO, MSGL_V, "[vaapi] Using profile '%s'.\n", - str_va_profile(va_profile)); + MP_VERBOSE(p, "Using profile '%s'.\n", str_va_profile(va_profile)); int num_surfaces = hwdec_get_max_refs(ctx); if (!is_direct_mapping(p->display)) { - mp_msg(MSGT_VO, MSGL_V, "[vaapi] No direct mapping.\n"); + MP_VERBOSE(p, "No direct mapping.\n"); // Note: not sure why it has to be *=2 rather than +=1. num_surfaces *= 2; } num_surfaces = MPMIN(num_surfaces, MAX_DECODER_SURFACES) + ADDTIONAL_SURFACES; if (num_surfaces > MAX_SURFACES) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Internal error: too many surfaces.\n"); + MP_ERR(p, "Internal error: too many surfaces.\n"); goto error; } if (!preallocate_surfaces(ctx, num_surfaces)) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Could not allocate surfaces.\n"); + MP_ERR(p, "Could not allocate surfaces.\n"); goto error; } int num_ep = vaMaxNumEntrypoints(p->display); VAEntrypoint *ep = talloc_zero_array(tmp, VAEntrypoint, num_ep); status = vaQueryConfigEntrypoints(p->display, va_profile, ep, &num_ep); - if (!check_va_status(status, "vaQueryConfigEntrypoints()")) + if (!CHECK_VA_STATUS(p, "vaQueryConfigEntrypoints()")) goto error; int entrypoint = find_entrypoint(p->format, ep, num_ep); if (entrypoint < 0) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Could not find VA entrypoint.\n"); + MP_ERR(p, "Could not find VA entrypoint.\n"); goto error; } @@ -277,23 +276,23 @@ static int create_decoder(struct lavc_ctx *ctx) }; status = vaGetConfigAttributes(p->display, va_profile, entrypoint, &attrib, 1); - if (!check_va_status(status, "vaGetConfigAttributes()")) + if (!CHECK_VA_STATUS(p, "vaGetConfigAttributes()")) goto error; if ((attrib.value & p->rt_format) == 0) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Chroma format not supported.\n"); + MP_ERR(p, "Chroma format not supported.\n"); goto error; } status = vaCreateConfig(p->display, va_profile, entrypoint, &attrib, 1, &p->va_context->config_id); - if (!check_va_status(status, "vaCreateConfig()")) + if (!CHECK_VA_STATUS(p, "vaCreateConfig()")) goto error; status = vaCreateContext(p->display, p->va_context->config_id, p->w, p->h, VA_PROGRESSIVE, p->surfaces, num_surfaces, &p->va_context->context_id); - if (!check_va_status(status, "vaCreateContext()")) + if (!CHECK_VA_STATUS(p, "vaCreateContext()")) goto error; res = 0; @@ -328,7 +327,7 @@ static struct mp_image *allocate_image(struct lavc_ctx *ctx, int format, } va_surface_release(s); } - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] Insufficient number of surfaces.\n"); + MP_ERR(p, "Insufficient number of surfaces.\n"); return NULL; } @@ -353,7 +352,7 @@ static bool create_va_dummy_ctx(struct priv *p) VADisplay *display = vaGetDisplay(p->x11_display); if (!display) goto destroy_ctx; - p->ctx = va_initialize(display); + p->ctx = va_initialize(display, p->log); if (!p->ctx) { vaTerminate(display); goto destroy_ctx; @@ -385,6 +384,7 @@ static int init_with_vactx(struct lavc_ctx *ctx, struct mp_vaapi_ctx *vactx) { struct priv *p = talloc_ptrtype(NULL, p); *p = (struct priv) { + .log = mp_log_new(p, ctx->log, "vaapi"), .ctx = vactx, .va_context = &p->va_context_storage, .rt_format = VA_RT_FORMAT_YUV420 @@ -398,7 +398,7 @@ static int init_with_vactx(struct lavc_ctx *ctx, struct mp_vaapi_ctx *vactx) } p->display = p->ctx->display; - p->pool = va_surface_pool_alloc(p->display, p->rt_format); + p->pool = va_surface_pool_alloc(p->ctx, p->rt_format); p->sw_pool = talloc_steal(p, mp_image_pool_new(17)); p->va_context->display = p->display; @@ -432,7 +432,7 @@ static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, static int probe_copy(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, const char *decoder) { - struct priv dummy = {0}; + struct priv dummy = {mp_null_log}; if (!create_va_dummy_ctx(&dummy)) return HWDEC_ERR_NO_CTX; destroy_va_dummy_ctx(&dummy); @@ -452,12 +452,10 @@ static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img) struct va_surface *surface = va_surface_in_mp_image(img); if (surface) { - struct mp_image *simg = - va_surface_download(surface, p->ctx->image_formats, p->sw_pool); + struct mp_image *simg = va_surface_download(surface, p->sw_pool); if (simg) { if (!p->printed_readback_warning) { - mp_msg(MSGT_VO, MSGL_WARN, "[vaapi] Using GPU readback. This " - "is usually inefficient.\n"); + MP_WARN(p, "Using GPU readback. This is usually inefficient.\n"); p->printed_readback_warning = true; } talloc_free(img); diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c index 6c96ae1bda..7ebb8f3eb0 100644 --- a/video/filter/vf_vavpp.c +++ b/video/filter/vf_vavpp.c @@ -24,11 +24,11 @@ #include "video/vaapi.h" #include "video/hwdec.h" -static inline bool is_success(VAStatus status, const char *msg) +static bool check_error(struct vf_instance *vf, VAStatus status, const char *msg) { if (status == VA_STATUS_SUCCESS) return true; - mp_msg(MSGT_VFILTER, MSGL_ERR, "[vavpp] %s: %s\n", msg, vaErrorStr(status)); + MP_ERR(vf, "%s: %s\n", msg, vaErrorStr(status)); return false; } @@ -78,8 +78,9 @@ static inline void realloc_refs(struct surface_refs *refs, int num) refs->num_required = num; } -static bool update_pipeline(struct vf_priv_s *p, bool deint) +static bool update_pipeline(struct vf_instance *vf, bool deint) { + struct vf_priv_s *p = vf->priv; VABufferID *filters = p->buffers; int num_filters = p->num_buffers; if (p->deint_type && !deint) { @@ -101,7 +102,7 @@ static bool update_pipeline(struct vf_priv_s *p, bool deint) caps.num_output_color_standards = VAProcColorStandardCount; VAStatus status = vaQueryVideoProcPipelineCaps(p->display, p->context, filters, num_filters, &caps); - if (!is_success(status, "vaQueryVideoProcPipelineCaps()")) + if (!check_error(vf, status, "vaQueryVideoProcPipelineCaps()")) return false; p->pipe.filters = filters; p->pipe.num_filters = num_filters; @@ -120,9 +121,10 @@ 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_priv_s *p, struct va_surface *in, +static struct mp_image *render(struct vf_instance *vf, struct va_surface *in, unsigned int flags) { + struct vf_priv_s *p = vf->priv; if (!p->pipe.filters || !in) return NULL; struct va_surface *out = va_surface_pool_get(p->pool, in->w, in->h); @@ -132,7 +134,7 @@ static struct mp_image *render(struct vf_priv_s *p, struct va_surface *in, int state = 0; do { // not a loop, just for break VAStatus status = vaBeginPicture(p->display, p->context, out->id); - if (!is_success(status, "vaBeginPicture()")) + if (!check_error(vf, status, "vaBeginPicture()")) break; state |= Begun; VABufferID buffer = VA_INVALID_ID; @@ -140,10 +142,10 @@ static struct mp_image *render(struct vf_priv_s *p, struct va_surface *in, status = vaCreateBuffer(p->display, p->context, VAProcPipelineParameterBufferType, sizeof(*param), 1, NULL, &buffer); - if (!is_success(status, "vaCreateBuffer()")) + if (!check_error(vf, status, "vaCreateBuffer()")) break; status = vaMapBuffer(p->display, buffer, (void**)¶m); - if (!is_success(status, "vaMapBuffer()")) + if (!check_error(vf, status, "vaMapBuffer()")) break; param->surface = in->id; param->surface_region = NULL; @@ -158,7 +160,7 @@ static struct mp_image *render(struct vf_priv_s *p, struct va_surface *in, param->num_forward_references = p->pipe.forward.num_required; param->num_backward_references = p->pipe.backward.num_required; status = vaRenderPicture(p->display, p->context, &buffer, 1); - if (!is_success(status, "vaRenderPicture()")) + if (!check_error(vf, status, "vaRenderPicture()")) break; state |= Rendered; } while (false); @@ -171,16 +173,17 @@ static struct mp_image *render(struct vf_priv_s *p, struct va_surface *in, } // return value: the number of created images -static int process(struct vf_priv_s *p, struct mp_image *in, +static int process(struct vf_instance *vf, struct mp_image *in, struct mp_image **out1, struct mp_image **out2) { + struct vf_priv_s *p = vf->priv; const bool deint = p->do_deint && p->deint_type > 0; - if (!update_pipeline(p, deint) || !p->pipe.filters) // no filtering + 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(p, surface, field | csp); + *out1 = render(vf, surface, field | csp); if (!*out1) // cannot render return 0; mp_image_copy_attributes(*out1, in); @@ -189,7 +192,7 @@ static int process(struct vf_priv_s *p, 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(p, surface, get_deint_field(p, 1, in) | csp); + *out2 = render(vf, surface, get_deint_field(p, 1, in) | csp); if (!*out2) // cannot render return 1; mp_image_copy_attributes(*out2, in); @@ -197,10 +200,11 @@ static int process(struct vf_priv_s *p, struct mp_image *in, return 2; } -static struct mp_image *upload(struct vf_priv_s *p, struct mp_image *in) +static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in) { + struct vf_priv_s *p = vf->priv; struct va_surface *surface = - va_surface_pool_get_by_imgfmt(p->pool, p->va->image_formats, in->imgfmt, in->w, in->h); + va_surface_pool_get_by_imgfmt(p->pool, in->imgfmt, in->w, in->h); if (!surface) surface = va_surface_pool_get(p->pool, in->w, in->h); // dummy else @@ -217,17 +221,17 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *in) const int rt_format = surface ? surface->rt_format : VA_RT_FORMAT_YUV420; if (!p->pool || va_surface_pool_rt_format(p->pool) != rt_format) { va_surface_pool_release(p->pool); - p->pool = va_surface_pool_alloc(p->display, rt_format); + p->pool = va_surface_pool_alloc(p->va, rt_format); } if (!surface) { - struct mp_image *tmp = upload(p, in); + struct mp_image *tmp = upload(vf, in); talloc_free(in); in = tmp; } struct mp_image *out1, *out2; const double pts = in->pts; - const int num = process(p, in, &out1, &out2); + const int num = process(vf, in, &out1, &out2); if (!num) vf_add_output_frame(vf, in); else { @@ -289,45 +293,48 @@ static int control(struct vf_instance *vf, int request, void* data) } } -static int va_query_filter_caps(struct vf_priv_s *p, VAProcFilterType type, +static int va_query_filter_caps(struct vf_instance *vf, VAProcFilterType type, void *caps, unsigned int count) { + struct vf_priv_s *p = vf->priv; VAStatus status = vaQueryVideoProcFilterCaps(p->display, p->context, type, caps, &count); - return is_success(status, "vaQueryVideoProcFilterCaps()") ? count : 0; + return check_error(vf, status, "vaQueryVideoProcFilterCaps()") ? count : 0; } -static VABufferID va_create_filter_buffer(struct vf_priv_s *p, int bytes, +static VABufferID va_create_filter_buffer(struct vf_instance *vf, int bytes, int num, void *data) { + struct vf_priv_s *p = vf->priv; VABufferID buffer; VAStatus status = vaCreateBuffer(p->display, p->context, VAProcFilterParameterBufferType, bytes, num, data, &buffer); - return is_success(status, "vaCreateBuffer()") ? buffer : VA_INVALID_ID; + return check_error(vf, status, "vaCreateBuffer()") ? buffer : VA_INVALID_ID; } -static bool initialize(struct vf_priv_s *p) +static bool initialize(struct vf_instance *vf) { + struct vf_priv_s *p = vf->priv; VAStatus status; VAConfigID config; status = vaCreateConfig(p->display, VAProfileNone, VAEntrypointVideoProc, NULL, 0, &config); - if (!is_success(status, "vaCreateConfig()")) // no entrypoint for video porc + if (!check_error(vf, status, "vaCreateConfig()")) // no entrypoint for video porc return false; p->config = config; VAContextID context; status = vaCreateContext(p->display, p->config, 0, 0, 0, NULL, 0, &context); - if (!is_success(status, "vaCreateContext()")) + if (!check_error(vf, status, "vaCreateContext()")) return false; p->context = context; VAProcFilterType filters[VAProcFilterCount]; int num_filters = VAProcFilterCount; status = vaQueryVideoProcFilters(p->display, p->context, filters, &num_filters); - if (!is_success(status, "vaQueryVideoProcFilters()")) + if (!check_error(vf, status, "vaQueryVideoProcFilters()")) return false; VABufferID buffers[VAProcFilterCount]; @@ -338,7 +345,7 @@ static bool initialize(struct vf_priv_s *p) if (!p->deint_type) continue; VAProcFilterCapDeinterlacing caps[VAProcDeinterlacingCount]; - int num = va_query_filter_caps(p, VAProcFilterDeinterlacing, caps, + int num = va_query_filter_caps(vf, VAProcFilterDeinterlacing, caps, VAProcDeinterlacingCount); if (!num) continue; @@ -350,7 +357,7 @@ static bool initialize(struct vf_priv_s *p) param.type = VAProcFilterDeinterlacing; param.algorithm = algorithm; buffers[VAProcFilterDeinterlacing] = - va_create_filter_buffer(p, sizeof(param), 1, ¶m); + va_create_filter_buffer(vf, sizeof(param), 1, ¶m); } } // check other filters } @@ -378,7 +385,7 @@ static int vf_open(vf_instance_t *vf) if (!p->va || !p->va->display) return false; p->display = p->va->display; - if (initialize(p)) + if (initialize(vf)) return true; uninit(vf); return false; diff --git a/video/out/gl_hwdec_vaglx.c b/video/out/gl_hwdec_vaglx.c index 53beceb197..47e7bb6e07 100644 --- a/video/out/gl_hwdec_vaglx.c +++ b/video/out/gl_hwdec_vaglx.c @@ -29,6 +29,7 @@ #include "video/hwdec.h" struct priv { + struct mp_log *log; struct mp_vaapi_ctx *ctx; VADisplay *display; GLuint gl_texture; @@ -42,7 +43,7 @@ static void destroy_texture(struct gl_hwdec *hw) if (p->vaglx_surface) { status = vaDestroySurfaceGLX(p->display, p->vaglx_surface); - check_va_status(status, "vaDestroySurfaceGLX()"); + CHECK_VA_STATUS(p, "vaDestroySurfaceGLX()"); p->vaglx_surface = NULL; } @@ -65,10 +66,11 @@ static int create(struct gl_hwdec *hw) return -1; struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; + p->log = hw->log; p->display = vaGetDisplayGLX(hw->mpgl->vo->x11->display); if (!p->display) return -1; - p->ctx = va_initialize(p->display); + p->ctx = va_initialize(p->display, p->log); if (!p->ctx) { vaTerminate(p->display); return -1; @@ -98,7 +100,7 @@ static int reinit(struct gl_hwdec *hw, const struct mp_image_params *params) status = vaCreateSurfaceGLX(p->display, GL_TEXTURE_2D, p->gl_texture, &p->vaglx_surface); - return check_va_status(status, "vaCreateSurfaceGLX()") ? 0 : -1; + return CHECK_VA_STATUS(p, "vaCreateSurfaceGLX()") ? 0 : -1; } static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, @@ -113,7 +115,7 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, status = vaCopySurfaceGLX(p->display, p->vaglx_surface, va_surface_id_in_mp_image(hw_image), va_get_colorspace_flag(hw_image->colorspace)); - if (!check_va_status(status, "vaCopySurfaceGLX()")) + if (!CHECK_VA_STATUS(p, "vaCopySurfaceGLX()")) return -1; out_textures[0] = p->gl_texture; diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index de5e05e4ec..d05b4afd44 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -134,7 +134,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] = - va_surface_pool_get_wrapped(p->pool, p->va_image_formats, imgfmt, w, h); + va_surface_pool_get_wrapped(p->pool, imgfmt, w, h); if (!p->swdec_surfaces[i]) return false; } @@ -190,8 +190,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi) // 4:2:0 should work everywhere int fmt = IMGFMT_420P; p->black_surface = - va_surface_pool_get_by_imgfmt(p->pool, p->va_image_formats, - fmt, w, h); + va_surface_pool_get_by_imgfmt(p->pool, fmt, w, h); if (p->black_surface) { struct mp_image *img = mp_image_alloc(fmt, w, h); mp_image_clear(img, 0, 0, w, h); @@ -221,7 +220,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi) sp->dst_x, sp->dst_y, sp->dst_w, sp->dst_h, flags); - check_va_status(status, "vaAssociateSubpicture()"); + CHECK_VA_STATUS(p, "vaAssociateSubpicture()"); } } @@ -244,7 +243,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi) p->dst_rect.y1 - p->dst_rect.y0, NULL, 0, flags); - check_va_status(status, "vaPutSurface()"); + CHECK_VA_STATUS(p, "vaPutSurface()"); for (int n = 0; n < MAX_OSD_PARTS; n++) { struct vaapi_osd_part *part = &p->osd_parts[n]; @@ -252,7 +251,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi) struct vaapi_subpic *sp = &part->subpic; status = vaDeassociateSubpicture(p->display, sp->id, &surface, 1); - check_va_status(status, "vaDeassociateSubpicture()"); + CHECK_VA_STATUS(p, "vaDeassociateSubpicture()"); } } @@ -292,8 +291,7 @@ static struct mp_image *get_screenshot(struct priv *p) va_surface_in_mp_image(p->output_surfaces[p->visible_surface]); if (!surface) return NULL; - struct mp_image *img = - va_surface_download(surface, p->va_image_formats, NULL); + struct mp_image *img = va_surface_download(surface, NULL); if (!img) return NULL; struct mp_image_params params = p->image_params; @@ -334,10 +332,10 @@ static int new_subpicture(struct priv *p, int w, int h, }; status = vaCreateImage(p->display, &p->osd_format, w, h, &m.image); - if (!check_va_status(status, "vaCreateImage()")) + if (!CHECK_VA_STATUS(p, "vaCreateImage()")) goto error; status = vaCreateSubpicture(p->display, m.image.image_id, &m.subpic_id); - if (!check_va_status(status, "vaCreateSubpicture()")) + if (!CHECK_VA_STATUS(p, "vaCreateSubpicture()")) goto error; *out = m; @@ -377,7 +375,7 @@ static void draw_osd_cb(void *pctx, struct sub_bitmaps *imgs) struct vaapi_osd_image *img = &part->image; struct mp_image vaimg; - if (va_image_map(p->display, &img->image, &vaimg) < 0) + if (va_image_map(p->mpvaapi, &img->image, &vaimg) < 0) goto error; // Clear borders and regions uncovered by sub-bitmaps @@ -398,7 +396,7 @@ static void draw_osd_cb(void *pctx, struct sub_bitmaps *imgs) vaimg.stride[0], sub->stride); } - if (va_image_unmap(p->display, &img->image) < 0) + if (va_image_unmap(p->mpvaapi, &img->image) < 0) goto error; part->subpic = (struct vaapi_subpic) { @@ -496,7 +494,7 @@ static int set_equalizer(struct priv *p, const char *name, int value) attr->value = ((value + 100) * r) / 200 + attr->min_value; status = vaSetDisplayAttributes(p->display, attr, 1); - if (!check_va_status(status, "vaSetDisplayAttributes()")) + if (!CHECK_VA_STATUS(p, "vaSetDisplayAttributes()")) return VO_FALSE; return VO_TRUE; } @@ -585,13 +583,13 @@ static int preinit(struct vo *vo) if (!p->display) return -1; - p->mpvaapi = va_initialize(p->display); + p->mpvaapi = va_initialize(p->display, p->log); if (!p->mpvaapi) { vaTerminate(p->display); return -1; } - p->pool = va_surface_pool_alloc(p->display, VA_RT_FORMAT_YUV420); + p->pool = va_surface_pool_alloc(p->mpvaapi, VA_RT_FORMAT_YUV420); p->va_image_formats = p->mpvaapi->image_formats; int max_subpic_formats = vaMaxNumSubpictureFormats(p->display); @@ -601,7 +599,7 @@ static int preinit(struct vo *vo) p->va_subpic_formats, p->va_subpic_flags, &p->va_num_subpic_formats); - if (!check_va_status(status, "vaQuerySubpictureFormats()")) + if (!CHECK_VA_STATUS(p, "vaQuerySubpictureFormats()")) p->va_num_subpic_formats = 0; MP_VERBOSE(vo, "%d subpicture formats available:\n", p->va_num_subpic_formats); @@ -634,7 +632,7 @@ static int preinit(struct vo *vo) if (p->va_display_attrs) { status = vaQueryDisplayAttributes(p->display, p->va_display_attrs, &p->va_num_display_attrs); - if (!check_va_status(status, "vaQueryDisplayAttributes()")) + if (!CHECK_VA_STATUS(p, "vaQueryDisplayAttributes()")) p->va_num_display_attrs = 0; } return 0; diff --git a/video/vaapi.c b/video/vaapi.c index 3bc54b69db..286e621ec1 100644 --- a/video/vaapi.c +++ b/video/vaapi.c @@ -24,13 +24,10 @@ #include "img_format.h" #include "mp_image_pool.h" -#define VA_VERBOSE(...) mp_msg(MSGT_VO, MSGL_V, "[vaapi] " __VA_ARGS__) -#define VA_ERROR(...) mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] " __VA_ARGS__) - -bool check_va_status(VAStatus status, const char *msg) +bool check_va_status(struct mp_log *log, VAStatus status, const char *msg) { if (status != VA_STATUS_SUCCESS) { - mp_msg(MSGT_VO, MSGL_ERR, "[vaapi] %s: %s\n", msg, vaErrorStr(status)); + mp_err(log, "%s: %s\n", msg, vaErrorStr(status)); return false; } return true; @@ -96,30 +93,32 @@ static void va_get_formats(struct mp_vaapi_ctx *ctx) int num = vaMaxNumImageFormats(ctx->display); VAImageFormat entries[num]; VAStatus status = vaQueryImageFormats(ctx->display, entries, &num); - if (!check_va_status(status, "vaQueryImageFormats()")) + if (!CHECK_VA_STATUS(ctx, "vaQueryImageFormats()")) return; struct va_image_formats *formats = talloc_ptrtype(ctx, formats); formats->entries = talloc_array(formats, VAImageFormat, num); formats->num = num; - VA_VERBOSE("%d image formats available:\n", num); + MP_VERBOSE(ctx, "%d image formats available:\n", num); for (int i = 0; i < num; i++) { formats->entries[i] = entries[i]; - VA_VERBOSE(" %s\n", VA_STR_FOURCC(entries[i].fourcc)); + MP_VERBOSE(ctx, " %s\n", VA_STR_FOURCC(entries[i].fourcc)); } ctx->image_formats = formats; } -struct mp_vaapi_ctx *va_initialize(VADisplay *display) +struct mp_vaapi_ctx *va_initialize(VADisplay *display, struct mp_log *plog) { + struct mp_log *log = mp_log_new(NULL, plog, "/vaapi"); int major_version, minor_version; int status = vaInitialize(display, &major_version, &minor_version); - if (!check_va_status(status, "vaInitialize()")) - return NULL; + if (!check_va_status(log, status, "vaInitialize()")) + goto error; - VA_VERBOSE("VA API version %d.%d\n", major_version, minor_version); + mp_verbose(log, "VA API version %d.%d\n", major_version, minor_version); struct mp_vaapi_ctx *res = talloc_ptrtype(NULL, res); *res = (struct mp_vaapi_ctx) { + .log = talloc_steal(res, log), .display = display, }; @@ -129,8 +128,9 @@ struct mp_vaapi_ctx *va_initialize(VADisplay *display) return res; error: - if (res->display) + if (res && res->display) vaTerminate(res->display); + talloc_free(log); talloc_free(res); return NULL; } @@ -161,6 +161,8 @@ VAImageFormat *va_image_format_from_imgfmt(const struct va_image_formats *format static void va_surface_destroy(struct va_surface *surface); struct va_surface_pool { + struct mp_log *log; + struct mp_vaapi_ctx *ctx; VADisplay display; int rt_format; int num_surfaces, lru_counter; @@ -168,6 +170,7 @@ struct va_surface_pool { }; typedef struct va_surface_priv { + struct mp_vaapi_ctx *ctx; VADisplay display; VAImage image; // used for software decoding case bool is_derived; // is image derived by vaDeriveImage()? @@ -176,11 +179,13 @@ typedef struct va_surface_priv { int order; // for LRU allocation } va_surface_priv_t; -struct va_surface_pool *va_surface_pool_alloc(VADisplay display, int rt_format) +struct va_surface_pool * va_surface_pool_alloc(struct mp_vaapi_ctx *ctx, int rt_format) { struct va_surface_pool *pool = talloc_ptrtype(NULL, pool); *pool = (struct va_surface_pool) { - .display = display, + .ctx = ctx, + .log = ctx->log, + .display = ctx->display, .rt_format = rt_format }; return pool; @@ -252,7 +257,7 @@ static struct va_surface *va_surface_alloc(struct va_surface_pool *pool, VASurfaceID id = VA_INVALID_ID; VAStatus status; status = vaCreateSurfaces(pool->display, w, h, pool->rt_format, 1, &id); - if (!check_va_status(status, "vaCreateSurfaces()")) + if (!CHECK_VA_STATUS(pool, "vaCreateSurfaces()")) return NULL; struct va_surface *surface = talloc_ptrtype(NULL, surface); @@ -265,17 +270,16 @@ static struct va_surface *va_surface_alloc(struct va_surface_pool *pool, surface->h = h; surface->rt_format = pool->rt_format; surface->p = talloc_zero(surface, va_surface_priv_t); + surface->p->ctx = pool->ctx; surface->p->display = pool->display; surface->p->image.image_id = surface->p->image.buf = VA_INVALID_ID; return surface; } struct mp_image *va_surface_pool_get_wrapped(struct va_surface_pool *pool, - const struct va_image_formats *formats, int imgfmt, int w, int h) { - return va_surface_wrap(va_surface_pool_get_by_imgfmt(pool, formats, imgfmt, - w, h)); + return va_surface_wrap(va_surface_pool_get_by_imgfmt(pool, imgfmt, w, h)); } int va_surface_pool_rt_format(const struct va_surface_pool *pool) @@ -346,7 +350,7 @@ static VAImage *va_surface_image_alloc(struct va_surface *surface, if (p->image.format.fourcc == format->fourcc && p->image.width == surface->w && p->image.height == surface->h) { p->is_derived = true; - VA_VERBOSE("Using vaDeriveImage()\n"); + MP_VERBOSE(p->ctx, "Using vaDeriveImage()\n"); } else { vaDestroyImage(p->display, p->image.image_id); status = VA_STATUS_ERROR_OPERATION_FAILED; @@ -356,7 +360,7 @@ static VAImage *va_surface_image_alloc(struct va_surface *surface, p->image.image_id = VA_INVALID_ID; status = vaCreateImage(p->display, format, surface->w, surface->h, &p->image); - if (!check_va_status(status, "vaCreateImage()")) { + if (!CHECK_VA_STATUS(p->ctx, "vaCreateImage()")) { p->image.image_id = VA_INVALID_ID; return NULL; } @@ -367,12 +371,12 @@ static VAImage *va_surface_image_alloc(struct va_surface *surface, struct va_surface *va_surface_pool_get_by_imgfmt(struct va_surface_pool *pool, - const struct va_image_formats *formats, int imgfmt, int w, int h) { if (imgfmt == IMGFMT_VAAPI) return va_surface_pool_get(pool, w, h); - VAImageFormat *format = va_image_format_from_imgfmt(formats, imgfmt); + VAImageFormat *format = + va_image_format_from_imgfmt(pool->ctx->image_formats, imgfmt); if (!format) return NULL; // WTF: no mapping from VAImageFormat -> VA_RT_FORMAT_ @@ -420,14 +424,14 @@ VASurfaceID va_surface_id(const struct va_surface *surface) return surface ? surface->id : VA_INVALID_ID; } -bool va_image_map(VADisplay display, VAImage *image, struct mp_image *mpi) +bool va_image_map(struct mp_vaapi_ctx *ctx, VAImage *image, struct mp_image *mpi) { int imgfmt = va_fourcc_to_imgfmt(image->format.fourcc); if (imgfmt == IMGFMT_NONE) return false; void *data = NULL; - const VAStatus status = vaMapBuffer(display, image->buf, &data); - if (!check_va_status(status, "vaMapBuffer()")) + const VAStatus status = vaMapBuffer(ctx->display, image->buf, &data); + if (!CHECK_VA_STATUS(ctx, "vaMapBuffer()")) return false; *mpi = (struct mp_image) {0}; @@ -447,10 +451,10 @@ bool va_image_map(VADisplay display, VAImage *image, struct mp_image *mpi) return true; } -bool va_image_unmap(VADisplay display, VAImage *image) +bool va_image_unmap(struct mp_vaapi_ctx *ctx, VAImage *image) { - const VAStatus status = vaUnmapBuffer(display, image->buf); - return check_va_status(status, "vaUnmapBuffer()"); + const VAStatus status = vaUnmapBuffer(ctx->display, image->buf); + return CHECK_VA_STATUS(ctx, "vaUnmapBuffer()"); } bool va_surface_upload(struct va_surface *surface, struct mp_image *mpi) @@ -463,17 +467,17 @@ bool va_surface_upload(struct va_surface *surface, struct mp_image *mpi) return false; struct mp_image img; - if (!va_image_map(p->display, &p->image, &img)) + if (!va_image_map(p->ctx, &p->image, &img)) return false; mp_image_copy(&img, mpi); - va_image_unmap(p->display, &p->image); + 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); - if (!check_va_status(status, "vaPutImage()")) + if (!CHECK_VA_STATUS(p->ctx, "vaPutImage()")) return false; } @@ -504,12 +508,12 @@ static struct mp_image *try_download(struct va_surface *surface, struct mp_image *dst = NULL; struct mp_image tmp; - if (va_image_map(surface->p->display, image, &tmp)) { + if (va_image_map(surface->p->ctx, image, &tmp)) { assert(tmp.imgfmt == imgfmt); dst = pool ? mp_image_pool_get(pool, imgfmt, tmp.w, tmp.h) : mp_image_alloc(imgfmt, tmp.w, tmp.h); mp_image_copy(dst, &tmp); - va_image_unmap(surface->p->display, image); + va_image_unmap(surface->p->ctx, image); } return dst; } @@ -518,11 +522,11 @@ static struct mp_image *try_download(struct va_surface *surface, // 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, - const struct va_image_formats *formats, struct mp_image_pool *pool) { + struct mp_vaapi_ctx *ctx = surface->p->ctx; VAStatus status = vaSyncSurface(surface->p->display, surface->id); - if (!check_va_status(status, "vaSyncSurface()")) + if (!CHECK_VA_STATUS(ctx, "vaSyncSurface()")) return NULL; VAImage *image = &surface->p->image; @@ -533,14 +537,14 @@ struct mp_image *va_surface_download(struct va_surface *surface, } // We have no clue which format will work, so try them all. - for (int i = 0; i < formats->num; i++) { - VAImageFormat *format = &formats->entries[i]; + for (int i = 0; i < ctx->image_formats->num; i++) { + VAImageFormat *format = &ctx->image_formats->entries[i]; struct mp_image *mpi = try_download(surface, format, pool); if (mpi) return mpi; } - VA_ERROR("failed to get surface data.\n"); + MP_ERR(ctx, "failed to get surface data.\n"); return NULL; } diff --git a/video/vaapi.h b/video/vaapi.h index 2dbf03a208..1136725af3 100644 --- a/video/vaapi.h +++ b/video/vaapi.h @@ -73,8 +73,10 @@ #include "mp_image.h" struct mp_image_pool; +struct mp_log; struct mp_vaapi_ctx { + struct mp_log *log; VADisplay display; struct va_image_formats *image_formats; }; @@ -89,28 +91,30 @@ struct va_surface { struct va_surface_priv *p; }; -bool check_va_status(VAStatus status, const char *msg); +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) int va_get_colorspace_flag(enum mp_csp csp); -struct mp_vaapi_ctx *va_initialize(VADisplay *display); +struct mp_vaapi_ctx *va_initialize(VADisplay *display, struct mp_log *log); void va_destroy(struct mp_vaapi_ctx *ctx); enum mp_imgfmt va_fourcc_to_imgfmt(uint32_t fourcc); uint32_t va_fourcc_from_imgfmt(int imgfmt); VAImageFormat * va_image_format_from_imgfmt(const struct va_image_formats *formats, int imgfmt); -bool va_image_map(VADisplay display, VAImage *image, struct mp_image *mpi); -bool va_image_unmap(VADisplay display, VAImage *image); +bool va_image_map(struct mp_vaapi_ctx *ctx, VAImage *image, struct mp_image *mpi); +bool va_image_unmap(struct mp_vaapi_ctx *ctx, VAImage *image); -struct va_surface_pool * va_surface_pool_alloc(VADisplay display, int rt_format); +struct va_surface_pool * va_surface_pool_alloc(struct mp_vaapi_ctx *ctx, int rt_format); void va_surface_pool_release(struct va_surface_pool *pool); void va_surface_pool_releasep(struct va_surface_pool **pool); void va_surface_pool_clear(struct va_surface_pool *pool); bool va_surface_pool_reserve(struct va_surface_pool *pool, int count, int w, int h); int va_surface_pool_rt_format(const struct va_surface_pool *pool); struct va_surface * va_surface_pool_get(struct va_surface_pool *pool, int w, int h); -struct va_surface * va_surface_pool_get_by_imgfmt(struct va_surface_pool *pool, const struct va_image_formats *formats, int imgfmt, int w, int h); -struct mp_image * va_surface_pool_get_wrapped(struct va_surface_pool *pool, const struct va_image_formats *formats, int imgfmt, int w, int h); +struct va_surface * va_surface_pool_get_by_imgfmt(struct va_surface_pool *pool, int imgfmt, int w, int h); +struct mp_image * va_surface_pool_get_wrapped(struct va_surface_pool *pool, int imgfmt, int w, int h); void va_surface_release(struct va_surface *surface); void va_surface_releasep(struct va_surface **surface); @@ -120,7 +124,6 @@ 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, - const struct va_image_formats *formats, struct mp_image_pool *pool); #endif -- cgit v1.2.3