diff options
Diffstat (limited to 'video/decode')
-rw-r--r-- | video/decode/vaapi.c | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c index 63c180c5a0..82855c04eb 100644 --- a/video/decode/vaapi.c +++ b/video/decode/vaapi.c @@ -64,9 +64,7 @@ struct priv { struct vaapi_context *va_context; struct vaapi_context va_context_storage; - VASurfaceID surfaces[MAX_SURFACES]; - - struct va_surface_pool *pool; + struct mp_image_pool *pool; int rt_format; struct mp_image_pool *sw_pool; @@ -162,19 +160,26 @@ static int is_direct_mapping(VADisplay display) // We achieve this by reserving surfaces in the pool as needed. // Releasing surfaces is necessary after filling the surface id list so // that reserved surfaces can be reused for decoding. -static bool preallocate_surfaces(struct lavc_ctx *ctx, int num, int w, int h) +static bool preallocate_surfaces(struct lavc_ctx *ctx, int num, int w, int h, + VASurfaceID out_surfaces[MAX_SURFACES]) { struct priv *p = ctx->hwdec_priv; - if (!va_surface_pool_reserve(p->pool, num, w, h)) { - MP_ERR(p, "Could not allocate surfaces.\n"); - return false; - } - for (int i = 0; i < num; i++) { - struct va_surface *s = va_surface_pool_get(p->pool, w, h); - p->surfaces[i] = s->id; - va_surface_release(s); + assert(num <= MAX_SURFACES); + struct mp_image *reserve[MAX_SURFACES] = {0}; + bool res = true; + + 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]); + if (out_surfaces[n] == VA_INVALID_ID) { + MP_ERR(p, "Could not allocate surfaces.\n"); + res = false; + break; + } } - return true; + for (int i = 0; i < num; i++) + talloc_free(reserve[i]); + return res; } static void destroy_decoder(struct lavc_ctx *ctx) @@ -191,8 +196,7 @@ static void destroy_decoder(struct lavc_ctx *ctx) p->va_context->config_id = VA_INVALID_ID; } - for (int n = 0; n < MAX_SURFACES; n++) - p->surfaces[n] = VA_INVALID_ID; + mp_image_pool_clear(p->pool); } static bool has_profile(VAProfile *va_profiles, int num_profiles, VAProfile p) @@ -251,7 +255,8 @@ static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h) goto error; } - if (!preallocate_surfaces(ctx, num_surfaces, w, h)) { + VASurfaceID surfaces[MAX_SURFACES]; + if (!preallocate_surfaces(ctx, num_surfaces, w, h, surfaces)) { MP_ERR(p, "Could not allocate surfaces.\n"); goto error; } @@ -287,7 +292,7 @@ static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h) status = vaCreateContext(p->display, p->va_context->config_id, w, h, VA_PROGRESSIVE, - p->surfaces, num_surfaces, + surfaces, num_surfaces, &p->va_context->context_id); if (!CHECK_VA_STATUS(p, "vaCreateContext()")) goto error; @@ -303,19 +308,13 @@ static struct mp_image *allocate_image(struct lavc_ctx *ctx, int format, { struct priv *p = ctx->hwdec_priv; - struct va_surface *s = va_surface_pool_get(p->pool, w, h); - if (s) { - for (int n = 0; n < MAX_SURFACES; n++) { - if (p->surfaces[n] == s->id) - return va_surface_wrap(s); - } - va_surface_release(s); - } - MP_ERR(p, "Insufficient number of surfaces.\n"); - return NULL; + struct mp_image *img = + mp_image_pool_get_no_alloc(p->pool, IMGFMT_VAAPI, w, h); + if (!img) + MP_ERR(p, "Insufficient number of surfaces.\n"); + return img; } - static void destroy_va_dummy_ctx(struct priv *p) { if (p->x11_display) @@ -355,7 +354,6 @@ static void uninit(struct lavc_ctx *ctx) return; destroy_decoder(ctx); - va_surface_pool_release(p->pool); if (p->x11_display) destroy_va_dummy_ctx(p); @@ -382,7 +380,8 @@ 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->ctx, p->rt_format); + p->pool = talloc_steal(p, mp_image_pool_new(MAX_SURFACES)); + va_pool_set_allocator(p->pool, p->ctx, p->rt_format); p->sw_pool = talloc_steal(p, mp_image_pool_new(17)); p->va_context->display = p->display; |