summaryrefslogtreecommitdiffstats
path: root/video/decode
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-17 18:22:25 +0100
committerwm4 <wm4@nowhere>2014-03-17 18:22:25 +0100
commit31fc5e85636f8e7b3bec5f133cb82b78e3c86ddb (patch)
tree702027b802cb1d2f00b266280faac3de1b5b13f2 /video/decode
parent88aa3b8c986e0fdb74ae805b6a09d43789fb903e (diff)
downloadmpv-31fc5e85636f8e7b3bec5f133cb82b78e3c86ddb.tar.bz2
mpv-31fc5e85636f8e7b3bec5f133cb82b78e3c86ddb.tar.xz
vaapi: replace image pool implementation with mp_image_pool
Although I at first thought it would be better to have a separate implementation for hwaccels because the difference to software images are too large, it turns out you can actually save some code with it. Note that the old implementation had a small memory management bug. This got painted over in commit 269c1e1, but is hereby solved properly. Also note that I couldn't test vf_vavpp.c (due to lack of hardware), and I hope I didn't accidentally break it.
Diffstat (limited to 'video/decode')
-rw-r--r--video/decode/vaapi.c59
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;