diff options
author | James Cowgill <james410@cowgill.org.uk> | 2016-07-04 11:19:11 +0200 |
---|---|---|
committer | James Cowgill <james410@cowgill.org.uk> | 2016-07-04 11:19:11 +0200 |
commit | b3df5144ae0631b8634e535ba90245e8cdfd2a0a (patch) | |
tree | bc955df92f24b7140d3e0d4ec56edcfa74b32c5b /video/out/opengl/hwdec_vaegl.c | |
parent | 36e11d485bf132c7ae9cf5c3433ae40d63adb54d (diff) |
Imported Upstream version 0.18.0
Diffstat (limited to 'video/out/opengl/hwdec_vaegl.c')
-rw-r--r-- | video/out/opengl/hwdec_vaegl.c | 103 |
1 files changed, 41 insertions, 62 deletions
diff --git a/video/out/opengl/hwdec_vaegl.c b/video/out/opengl/hwdec_vaegl.c index 7b34d6b..6c52cdd 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, ¶ms) >= 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, }; |