summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/hwdec_vaegl.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/hwdec_vaegl.c')
-rw-r--r--video/out/opengl/hwdec_vaegl.c103
1 files changed, 41 insertions, 62 deletions
diff --git a/video/out/opengl/hwdec_vaegl.c b/video/out/opengl/hwdec_vaegl.c
index 7b34d6bb5c..6c52cdde11 100644
--- a/video/out/opengl/hwdec_vaegl.c
+++ b/video/out/opengl/hwdec_vaegl.c
@@ -114,7 +114,7 @@ struct priv {
EGLImageKHR images[4];
VAImage current_image;
bool buffer_acquired;
- struct mp_image *current_ref;
+ int current_mpfmt;
EGLImageKHR (EGLAPIENTRY *CreateImageKHR)(EGLDisplay, EGLContext,
EGLenum, EGLClientBuffer,
@@ -125,7 +125,7 @@ struct priv {
static bool test_format(struct gl_hwdec *hw);
-static void unref_image(struct gl_hwdec *hw)
+static void unmap_frame(struct gl_hwdec *hw)
{
struct priv *p = hw->priv;
VAStatus status;
@@ -149,8 +149,6 @@ static void unref_image(struct gl_hwdec *hw)
p->current_image.image_id = VA_INVALID_ID;
}
- mp_image_unrefp(&p->current_ref);
-
va_unlock(p->ctx);
}
@@ -167,35 +165,13 @@ static void destroy_textures(struct gl_hwdec *hw)
static void destroy(struct gl_hwdec *hw)
{
struct priv *p = hw->priv;
- unref_image(hw);
+ unmap_frame(hw);
destroy_textures(hw);
+ if (p->ctx)
+ hwdec_devices_remove(hw->devs, &p->ctx->hwctx);
va_destroy(p->ctx);
}
-// Create an empty dummy VPP. This works around a weird bug that affects the
-// VA surface format, as it is reported by vaDeriveImage(). Before a VPP
-// context or a decoder context is created, the surface format will be reported
-// as YV12. Surfaces created after context creation will report NV12 (even
-// though surface creation does not take a context as argument!). Existing
-// surfaces will change their format from YV12 to NV12 as soon as the decoder
-// renders to them! Because we want know the surface format in advance (to
-// simplify our renderer configuration logic), we hope that this hack gives
-// us reasonable behavior.
-// See: https://bugs.freedesktop.org/show_bug.cgi?id=79848
-static void insane_hack(struct gl_hwdec *hw)
-{
- struct priv *p = hw->priv;
- VAConfigID config;
- if (vaCreateConfig(p->display, VAProfileNone, VAEntrypointVideoProc,
- NULL, 0, &config) == VA_STATUS_SUCCESS)
- {
- // We want to keep this until the VADisplay is destroyed. It will
- // implicitly free the context.
- VAContextID context;
- vaCreateContext(p->display, config, 0, 0, 0, NULL, 0, &context);
- }
-}
-
static int create(struct gl_hwdec *hw)
{
GL *gl = hw->gl;
@@ -205,9 +181,7 @@ static int create(struct gl_hwdec *hw)
p->current_image.buf = p->current_image.image_id = VA_INVALID_ID;
p->log = hw->log;
- if (hw->hwctx)
- return -1;
- if (!eglGetCurrentDisplay())
+ if (!eglGetCurrentContext())
return -1;
const char *exts = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
@@ -248,13 +222,13 @@ static int create(struct gl_hwdec *hw)
MP_VERBOSE(p, "using VAAPI EGL interop\n");
- insane_hack(hw);
if (!test_format(hw)) {
destroy(hw);
return -1;
}
- hw->hwctx = &p->ctx->hwctx;
+ p->ctx->hwctx.driver_name = hw->driver->name;
+ hwdec_devices_add(hw->devs, &p->ctx->hwctx);
return 0;
}
@@ -266,8 +240,6 @@ static int reinit(struct gl_hwdec *hw, struct mp_image_params *params)
// Recreate them to get rid of all previous image data (possibly).
destroy_textures(hw);
- assert(params->imgfmt == hw->driver->imgfmt);
-
gl->GenTextures(4, p->gl_textures);
for (int n = 0; n < 4; n++) {
gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
@@ -278,6 +250,20 @@ static int reinit(struct gl_hwdec *hw, struct mp_image_params *params)
}
gl->BindTexture(GL_TEXTURE_2D, 0);
+ p->current_mpfmt = va_fourcc_to_imgfmt(params->hw_subfmt);
+ if (p->current_mpfmt != IMGFMT_NV12 &&
+ p->current_mpfmt != IMGFMT_420P)
+ {
+ MP_FATAL(p, "unsupported VA image format %s\n",
+ mp_tag_str(params->hw_subfmt));
+ return -1;
+ }
+
+ MP_VERBOSE(p, "format: %s %s\n", mp_tag_str(params->hw_subfmt),
+ mp_imgfmt_to_name(p->current_mpfmt));
+
+ params->imgfmt = p->current_mpfmt;
+
return 0;
}
@@ -289,17 +275,15 @@ static int reinit(struct gl_hwdec *hw, struct mp_image_params *params)
attribs[num_attribs] = EGL_NONE; \
} while(0)
-static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image,
- GLuint *out_textures)
+static int map_frame(struct gl_hwdec *hw, struct mp_image *hw_image,
+ struct gl_hwdec_frame *out_frame)
{
struct priv *p = hw->priv;
GL *gl = hw->gl;
VAStatus status;
VAImage *va_image = &p->current_image;
- unref_image(hw);
-
- mp_image_setrefp(&p->current_ref, hw_image);
+ unmap_frame(hw);
va_lock(p->ctx);
@@ -308,21 +292,9 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image,
goto err;
int mpfmt = va_fourcc_to_imgfmt(va_image->format.fourcc);
- if (mpfmt != IMGFMT_NV12 && mpfmt != IMGFMT_420P) {
- MP_FATAL(p, "unsupported VA image format %s\n",
- mp_tag_str(va_image->format.fourcc));
- goto err;
- }
-
- if (!hw->converted_imgfmt) {
- MP_VERBOSE(p, "format: %s %s\n", mp_tag_str(va_image->format.fourcc),
- mp_imgfmt_to_name(mpfmt));
- hw->converted_imgfmt = mpfmt;
- }
-
- if (hw->converted_imgfmt != mpfmt) {
+ if (p->current_mpfmt != mpfmt) {
MP_FATAL(p, "mid-stream hwdec format change (%s -> %s) not supported\n",
- mp_imgfmt_to_name(hw->converted_imgfmt), mp_imgfmt_to_name(mpfmt));
+ mp_imgfmt_to_name(p->current_mpfmt), mp_imgfmt_to_name(mpfmt));
goto err;
}
@@ -361,12 +333,17 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image,
gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
- out_textures[n] = p->gl_textures[n];
+ out_frame->planes[n] = (struct gl_hwdec_plane){
+ .gl_texture = p->gl_textures[n],
+ .gl_target = GL_TEXTURE_2D,
+ .tex_w = mp_image_plane_w(&layout, n),
+ .tex_h = mp_image_plane_h(&layout, n),
+ };
}
gl->BindTexture(GL_TEXTURE_2D, 0);
if (va_image->format.fourcc == VA_FOURCC_YV12)
- MPSWAP(GLuint, out_textures[1], out_textures[2]);
+ MPSWAP(struct gl_hwdec_plane, out_frame->planes[1], out_frame->planes[2]);
va_unlock(p->ctx);
return 0;
@@ -374,7 +351,7 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image,
err:
va_unlock(p->ctx);
MP_FATAL(p, "mapping VAAPI EGL image failed\n");
- unref_image(hw);
+ unmap_frame(hw);
return -1;
}
@@ -387,12 +364,13 @@ static bool test_format(struct gl_hwdec *hw)
va_pool_set_allocator(alloc, p->ctx, VA_RT_FORMAT_YUV420);
struct mp_image *surface = mp_image_pool_get(alloc, IMGFMT_VAAPI, 64, 64);
if (surface) {
+ va_surface_init_subformat(surface);
struct mp_image_params params = surface->params;
if (reinit(hw, &params) >= 0) {
- GLuint textures[4];
- ok = map_image(hw, surface, textures) >= 0;
+ struct gl_hwdec_frame frame = {0};
+ ok = map_frame(hw, surface, &frame) >= 0;
}
- unref_image(hw);
+ unmap_frame(hw);
}
talloc_free(surface);
talloc_free(alloc);
@@ -406,6 +384,7 @@ const struct gl_hwdec_driver gl_hwdec_vaegl = {
.imgfmt = IMGFMT_VAAPI,
.create = create,
.reinit = reinit,
- .map_image = map_image,
+ .map_frame = map_frame,
+ .unmap = unmap_frame,
.destroy = destroy,
};