2015-09-24 22:20:57 +00:00
|
|
|
/*
|
|
|
|
* This file is part of mpv.
|
|
|
|
*
|
2016-01-07 09:46:15 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2015-09-24 22:20:57 +00:00
|
|
|
*
|
|
|
|
* mpv is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2016-01-07 09:46:15 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2015-09-24 22:20:57 +00:00
|
|
|
*
|
2016-01-07 09:46:15 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2015-09-24 22:20:57 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
2017-10-07 16:49:56 +00:00
|
|
|
#include <unistd.h>
|
2015-09-24 22:20:57 +00:00
|
|
|
|
|
|
|
#include <va/va_drmcommon.h>
|
|
|
|
|
2017-06-18 13:00:36 +00:00
|
|
|
#include <libavutil/common.h>
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
#include <libavutil/hwcontext.h>
|
|
|
|
#include <libavutil/hwcontext_vaapi.h>
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
vo_opengl: refactor into vo_gpu
This is done in several steps:
1. refactor MPGLContext -> struct ra_ctx
2. move GL-specific stuff in vo_opengl into opengl/context.c
3. generalize context creation to support other APIs, and add --gpu-api
4. rename all of the --opengl- options that are no longer opengl-specific
5. move all of the stuff from opengl/* that isn't GL-specific into gpu/
(note: opengl/gl_utils.h became opengl/utils.h)
6. rename vo_opengl to vo_gpu
7. to handle window screenshots, the short-term approach was to just add
it to ra_swchain_fns. Long term (and for vulkan) this has to be moved to
ra itself (and vo_gpu altered to compensate), but this was a stop-gap
measure to prevent this commit from getting too big
8. move ra->fns->flush to ra_gl_ctx instead
9. some other minor changes that I've probably already forgotten
Note: This is one half of a major refactor, the other half of which is
provided by rossy's following commit. This commit enables support for
all linux platforms, while his version enables support for all non-linux
platforms.
Note 2: vo_opengl_cb.c also re-uses ra_gl_ctx so it benefits from the
--opengl- options like --opengl-early-flush, --opengl-finish etc. Should
be a strict superset of the old functionality.
Disclaimer: Since I have no way of compiling mpv on all platforms, some
of these ports were done blindly. Specifically, the blind ports included
context_mali_fbdev.c and context_rpi.c. Since they're both based on
egl_helpers, the port should have gone smoothly without any major
changes required. But if somebody complains about a compile error on
those platforms (assuming anybody actually uses them), you know where to
complain.
2017-09-14 06:04:55 +00:00
|
|
|
#include "video/out/gpu/hwdec.h"
|
2015-09-26 18:15:52 +00:00
|
|
|
#include "video/mp_image_pool.h"
|
vo_opengl: refactor into vo_gpu
This is done in several steps:
1. refactor MPGLContext -> struct ra_ctx
2. move GL-specific stuff in vo_opengl into opengl/context.c
3. generalize context creation to support other APIs, and add --gpu-api
4. rename all of the --opengl- options that are no longer opengl-specific
5. move all of the stuff from opengl/* that isn't GL-specific into gpu/
(note: opengl/gl_utils.h became opengl/utils.h)
6. rename vo_opengl to vo_gpu
7. to handle window screenshots, the short-term approach was to just add
it to ra_swchain_fns. Long term (and for vulkan) this has to be moved to
ra itself (and vo_gpu altered to compensate), but this was a stop-gap
measure to prevent this commit from getting too big
8. move ra->fns->flush to ra_gl_ctx instead
9. some other minor changes that I've probably already forgotten
Note: This is one half of a major refactor, the other half of which is
provided by rossy's following commit. This commit enables support for
all linux platforms, while his version enables support for all non-linux
platforms.
Note 2: vo_opengl_cb.c also re-uses ra_gl_ctx so it benefits from the
--opengl- options like --opengl-early-flush, --opengl-finish etc. Should
be a strict superset of the old functionality.
Disclaimer: Since I have no way of compiling mpv on all platforms, some
of these ports were done blindly. Specifically, the blind ports included
context_mali_fbdev.c and context_rpi.c. Since they're both based on
egl_helpers, the port should have gone smoothly without any major
changes required. But if somebody complains about a compile error on
those platforms (assuming anybody actually uses them), you know where to
complain.
2017-09-14 06:04:55 +00:00
|
|
|
#include "video/vaapi.h"
|
2018-12-30 22:59:48 +00:00
|
|
|
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
#include "video/out/placebo/ra_pl.h"
|
|
|
|
#include "video/out/vulkan/common.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if HAVE_GL
|
|
|
|
#include <EGL/egl.h>
|
|
|
|
#include <EGL/eglext.h>
|
|
|
|
#include "video/out/opengl/common.h"
|
|
|
|
#include "video/out/opengl/ra_gl.h"
|
2018-06-28 13:06:41 +00:00
|
|
|
#include "libmpv/render_gl.h"
|
2015-09-24 22:20:57 +00:00
|
|
|
|
2015-09-27 14:25:03 +00:00
|
|
|
#ifndef GL_OES_EGL_image
|
|
|
|
typedef void* GLeglImageOES;
|
|
|
|
#endif
|
|
|
|
#ifndef EGL_KHR_image
|
|
|
|
typedef void *EGLImageKHR;
|
|
|
|
#endif
|
|
|
|
|
2015-10-23 13:56:17 +00:00
|
|
|
#ifndef EGL_LINUX_DMA_BUF_EXT
|
|
|
|
#define EGL_LINUX_DMA_BUF_EXT 0x3270
|
2015-09-27 14:25:03 +00:00
|
|
|
#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
|
|
|
|
#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
|
|
|
|
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
|
|
|
|
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
|
|
|
|
#endif
|
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif // HAVE_GL
|
|
|
|
|
2015-09-27 18:09:10 +00:00
|
|
|
#if HAVE_VAAPI_X11
|
|
|
|
#include <va/va_x11.h>
|
|
|
|
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
static VADisplay *create_x11_va_display(struct ra *ra)
|
2015-09-27 18:09:10 +00:00
|
|
|
{
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
Display *x11 = ra_get_native_resource(ra, "x11");
|
2015-09-27 18:09:10 +00:00
|
|
|
return x11 ? vaGetDisplay(x11) : NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-09-27 19:24:35 +00:00
|
|
|
#if HAVE_VAAPI_WAYLAND
|
|
|
|
#include <va/va_wayland.h>
|
|
|
|
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
static VADisplay *create_wayland_va_display(struct ra *ra)
|
2015-09-27 19:24:35 +00:00
|
|
|
{
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
struct wl_display *wl = ra_get_native_resource(ra, "wl");
|
2015-09-27 19:24:35 +00:00
|
|
|
return wl ? vaGetDisplayWl(wl) : NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-01-20 18:41:29 +00:00
|
|
|
#if HAVE_VAAPI_DRM
|
|
|
|
#include <va/va_drm.h>
|
|
|
|
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
static VADisplay *create_drm_va_display(struct ra *ra)
|
2016-01-20 18:41:29 +00:00
|
|
|
{
|
2018-06-28 13:06:41 +00:00
|
|
|
mpv_opengl_drm_params *params = ra_get_native_resource(ra, "drm_params");
|
|
|
|
if (!params || params->render_fd < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return vaGetDisplayDRM(params->render_fd);
|
2016-01-20 18:41:29 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-01-21 12:32:29 +00:00
|
|
|
struct va_create_native {
|
2016-09-30 12:36:42 +00:00
|
|
|
const char *name;
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
VADisplay *(*create)(struct ra *ra);
|
2016-01-21 12:32:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct va_create_native create_native_cbs[] = {
|
2015-09-27 18:09:10 +00:00
|
|
|
#if HAVE_VAAPI_X11
|
2016-09-30 12:36:42 +00:00
|
|
|
{"x11", create_x11_va_display},
|
2015-09-27 19:24:35 +00:00
|
|
|
#endif
|
|
|
|
#if HAVE_VAAPI_WAYLAND
|
2016-09-30 12:36:42 +00:00
|
|
|
{"wayland", create_wayland_va_display},
|
2016-01-20 18:41:29 +00:00
|
|
|
#endif
|
|
|
|
#if HAVE_VAAPI_DRM
|
2016-09-30 12:36:42 +00:00
|
|
|
{"drm", create_drm_va_display},
|
2015-09-27 18:09:10 +00:00
|
|
|
#endif
|
2016-01-21 12:32:29 +00:00
|
|
|
};
|
|
|
|
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
static VADisplay *create_native_va_display(struct ra *ra, struct mp_log *log)
|
2016-01-21 12:32:29 +00:00
|
|
|
{
|
|
|
|
for (int n = 0; n < MP_ARRAY_SIZE(create_native_cbs); n++) {
|
2016-09-30 12:36:42 +00:00
|
|
|
const struct va_create_native *disp = &create_native_cbs[n];
|
|
|
|
mp_verbose(log, "Trying to open a %s VA display...\n", disp->name);
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
VADisplay *display = disp->create(ra);
|
2016-01-21 12:32:29 +00:00
|
|
|
if (display)
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
return NULL;
|
2015-09-27 18:09:10 +00:00
|
|
|
}
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner {
|
2015-09-24 22:20:57 +00:00
|
|
|
struct mp_vaapi_ctx *ctx;
|
|
|
|
VADisplay *display;
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
int *formats;
|
|
|
|
bool probing_formats; // temporary during init
|
|
|
|
};
|
|
|
|
|
|
|
|
struct priv {
|
|
|
|
int num_planes;
|
2018-12-30 22:59:48 +00:00
|
|
|
struct mp_image layout;
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct ra_tex *tex[4];
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
2015-09-24 22:20:57 +00:00
|
|
|
GLuint gl_textures[4];
|
|
|
|
EGLImageKHR images[4];
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif
|
2015-09-24 22:20:57 +00:00
|
|
|
VAImage current_image;
|
2015-09-25 10:14:19 +00:00
|
|
|
bool buffer_acquired;
|
2017-11-30 23:35:28 +00:00
|
|
|
#if VA_CHECK_VERSION(1, 1, 0)
|
2017-10-07 16:49:56 +00:00
|
|
|
bool esh_not_implemented;
|
|
|
|
VADRMPRIMESurfaceDescriptor desc;
|
|
|
|
bool surface_acquired;
|
|
|
|
#endif
|
2015-09-27 14:10:22 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
2015-09-27 14:10:22 +00:00
|
|
|
EGLImageKHR (EGLAPIENTRY *CreateImageKHR)(EGLDisplay, EGLContext,
|
|
|
|
EGLenum, EGLClientBuffer,
|
|
|
|
const EGLint *);
|
|
|
|
EGLBoolean (EGLAPIENTRY *DestroyImageKHR)(EGLDisplay, EGLImageKHR);
|
|
|
|
void (EGLAPIENTRY *EGLImageTargetTexture2DOES)(GLenum, GLeglImageOES);
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif
|
2015-09-24 22:20:57 +00:00
|
|
|
};
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static void determine_working_formats(struct ra_hwdec *hw);
|
2015-09-24 22:20:57 +00:00
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static void uninit(struct ra_hwdec *hw)
|
2015-09-24 22:20:57 +00:00
|
|
|
{
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner *p = hw->priv;
|
2016-05-09 17:42:03 +00:00
|
|
|
if (p->ctx)
|
|
|
|
hwdec_devices_remove(hw->devs, &p->ctx->hwctx);
|
2015-09-24 22:20:57 +00:00
|
|
|
va_destroy(p->ctx);
|
|
|
|
}
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static int init(struct ra_hwdec *hw)
|
2015-09-24 22:20:57 +00:00
|
|
|
{
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner *p = hw->priv;
|
2015-09-27 14:10:22 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
if (ra_is_gl(hw->ra)) {
|
|
|
|
if (!eglGetCurrentContext())
|
|
|
|
return -1;
|
2015-09-24 22:20:57 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
const char *exts = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
|
|
|
|
if (!exts)
|
|
|
|
return -1;
|
2016-01-22 18:54:32 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
GL *gl = ra_gl_get(hw->ra);
|
|
|
|
if (!strstr(exts, "EXT_image_dma_buf_import") ||
|
|
|
|
!strstr(exts, "EGL_KHR_image_base") ||
|
|
|
|
!strstr(gl->extensions, "GL_OES_EGL_image") ||
|
|
|
|
!(gl->mpgl_caps & MPGL_CAP_TEX_RG))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
MP_VERBOSE(hw, "using VAAPI EGL interop\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
if (ra_pl_get(hw->ra)) {
|
|
|
|
const struct pl_gpu *gpu = ra_pl_get(hw->ra);
|
|
|
|
if (!(gpu->import_caps.tex & PL_HANDLE_DMA_BUF)) {
|
|
|
|
MP_VERBOSE(hw, "VAAPI Vulkan interop requires support for "
|
|
|
|
"dma_buf import in Vulkan.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
MP_VERBOSE(hw, "using VAAPI Vulkan interop\n");
|
|
|
|
}
|
|
|
|
#endif
|
2015-09-24 22:20:57 +00:00
|
|
|
|
client API: add a new way to pass X11 Display etc. to render API
Hardware decoding things often need access to additional handles from
the windowing system, such as the X11 or Wayland display when using
vaapi. The opengl-cb had nothing dedicated for this, and used the weird
GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not
officially registered with OpenGL).
This was awkward, and a pain due to having to emulate GL context
behavior (like needing a TLS variable to store context for the pseudo GL
extension function). In addition (and not inherently due to this), we
could pass only one resource from mpv builtin context backends to
hwdecs. It was also all GL specific.
Replace this with a newer mechanism. It works for all RA backends, not
just GL. the API user can explicitly pass the objects at init time via
mpv_render_context_create(). Multiple resources are naturally possible.
The API uses MPV_RENDER_PARAM_* defines, but internally we use strings.
This is done for 2 reasons: 1. trying to leave libmpv and internal
mechanisms decoupled, 2. not having to add public API for some of the
internal resource types (especially D3D/GL interop stuff).
To remain sane, drop support for obscure half-working opengl-cb things,
like the DRM interop (was missing necessary things), the RPI window
thing (nobody used it), and obscure D3D interop things (not needed with
ANGLE, others were undocumented). In order not to break ABI and the C
API, we don't remove the associated structs from opengl_cb.h.
The parts which are still needed (in particular DRM interop) needs to be
ported to the render API.
2018-03-22 16:05:01 +00:00
|
|
|
p->display = create_native_va_display(hw->ra, hw->log);
|
2016-09-30 12:36:42 +00:00
|
|
|
if (!p->display) {
|
|
|
|
MP_VERBOSE(hw, "Could not create a VA display.\n");
|
2015-09-24 22:20:57 +00:00
|
|
|
return -1;
|
2016-09-30 12:36:42 +00:00
|
|
|
}
|
2015-09-24 22:20:57 +00:00
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
p->ctx = va_initialize(p->display, hw->log, true);
|
2015-09-24 22:20:57 +00:00
|
|
|
if (!p->ctx) {
|
|
|
|
vaTerminate(p->display);
|
|
|
|
return -1;
|
|
|
|
}
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
if (!p->ctx->av_device_ref) {
|
|
|
|
MP_VERBOSE(hw, "libavutil vaapi code rejected the driver?\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2015-09-24 22:20:57 +00:00
|
|
|
|
2015-11-09 10:58:38 +00:00
|
|
|
if (hw->probing && va_guess_if_emulated(p->ctx)) {
|
2015-09-24 22:20:57 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
determine_working_formats(hw);
|
|
|
|
if (!p->formats || !p->formats[0]) {
|
2015-09-26 18:15:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
p->ctx->hwctx.supported_formats = p->formats;
|
2016-05-09 17:42:03 +00:00
|
|
|
p->ctx->hwctx.driver_name = hw->driver->name;
|
|
|
|
hwdec_devices_add(hw->devs, &p->ctx->hwctx);
|
2015-09-24 22:20:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static void mapper_unmap(struct ra_hwdec_mapper *mapper)
|
|
|
|
{
|
|
|
|
struct priv_owner *p_owner = mapper->owner->priv;
|
|
|
|
VADisplay *display = p_owner->display;
|
|
|
|
struct priv *p = mapper->priv;
|
|
|
|
VAStatus status;
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
bool is_gl = ra_is_gl(mapper->ra);
|
|
|
|
#endif
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
const struct pl_gpu *gpu = ra_pl_get(mapper->ra);
|
|
|
|
#endif
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
|
|
|
|
for (int n = 0; n < 4; n++) {
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
if (is_gl) {
|
|
|
|
if (p->images[n])
|
|
|
|
p->DestroyImageKHR(eglGetCurrentDisplay(), p->images[n]);
|
|
|
|
p->images[n] = 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
if (gpu) {
|
|
|
|
ra_tex_free(mapper->ra, &mapper->tex[n]);
|
|
|
|
}
|
|
|
|
#endif
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
}
|
|
|
|
|
2017-11-30 23:35:28 +00:00
|
|
|
#if VA_CHECK_VERSION(1, 1, 0)
|
2017-10-07 16:49:56 +00:00
|
|
|
if (p->surface_acquired) {
|
|
|
|
for (int n = 0; n < p->desc.num_objects; n++)
|
|
|
|
close(p->desc.objects[n].fd);
|
|
|
|
p->surface_acquired = false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
if (p->buffer_acquired) {
|
|
|
|
status = vaReleaseBufferHandle(display, p->current_image.buf);
|
|
|
|
CHECK_VA_STATUS(mapper, "vaReleaseBufferHandle()");
|
|
|
|
p->buffer_acquired = false;
|
|
|
|
}
|
|
|
|
if (p->current_image.image_id != VA_INVALID_ID) {
|
|
|
|
status = vaDestroyImage(display, p->current_image.image_id);
|
|
|
|
CHECK_VA_STATUS(mapper, "vaDestroyImage()");
|
|
|
|
p->current_image.image_id = VA_INVALID_ID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mapper_uninit(struct ra_hwdec_mapper *mapper)
|
|
|
|
{
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv *p = mapper->priv;
|
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
if (ra_is_gl(mapper->ra)) {
|
|
|
|
GL *gl = ra_gl_get(mapper->ra);
|
|
|
|
gl->DeleteTextures(4, p->gl_textures);
|
|
|
|
for (int n = 0; n < 4; n++) {
|
|
|
|
p->gl_textures[n] = 0;
|
|
|
|
ra_tex_free(mapper->ra, &p->tex[n]);
|
|
|
|
}
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
}
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_fmt(struct ra_hwdec_mapper *mapper, int fmt)
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
{
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner *p_owner = mapper->owner->priv;
|
|
|
|
for (int n = 0; p_owner->formats && p_owner->formats[n]; n++) {
|
|
|
|
if (p_owner->formats[n] == fmt)
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static int mapper_init(struct ra_hwdec_mapper *mapper)
|
2015-09-24 22:20:57 +00:00
|
|
|
{
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner *p_owner = mapper->owner->priv;
|
|
|
|
struct priv *p = mapper->priv;
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
bool is_gl = ra_is_gl(mapper->ra);
|
|
|
|
#endif
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
|
|
|
|
p->current_image.buf = p->current_image.image_id = VA_INVALID_ID;
|
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
if (is_gl) {
|
|
|
|
// EGL_KHR_image_base
|
|
|
|
p->CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
|
|
|
|
p->DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
|
|
|
|
// GL_OES_EGL_image
|
|
|
|
p->EGLImageTargetTexture2DOES =
|
|
|
|
(void *)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
|
|
|
|
|
|
|
if (!p->CreateImageKHR || !p->DestroyImageKHR ||
|
|
|
|
!p->EGLImageTargetTexture2DOES)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
|
|
|
|
mapper->dst_params = mapper->src_params;
|
|
|
|
mapper->dst_params.imgfmt = mapper->src_params.hw_subfmt;
|
|
|
|
mapper->dst_params.hw_subfmt = 0;
|
|
|
|
|
|
|
|
struct ra_imgfmt_desc desc = {0};
|
|
|
|
|
|
|
|
if (!ra_get_imgfmt_desc(mapper->ra, mapper->dst_params.imgfmt, &desc))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
p->num_planes = desc.num_planes;
|
2018-12-30 22:59:48 +00:00
|
|
|
mp_image_set_params(&p->layout, &mapper->dst_params);
|
|
|
|
|
|
|
|
#if HAVE_GL
|
|
|
|
if (is_gl) {
|
|
|
|
GL *gl = ra_gl_get(mapper->ra);
|
|
|
|
gl->GenTextures(4, p->gl_textures);
|
|
|
|
for (int n = 0; n < desc.num_planes; n++) {
|
|
|
|
gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
|
|
|
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
gl->BindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
|
|
|
|
struct ra_tex_params params = {
|
|
|
|
.dimensions = 2,
|
|
|
|
.w = mp_image_plane_w(&p->layout, n),
|
|
|
|
.h = mp_image_plane_h(&p->layout, n),
|
|
|
|
.d = 1,
|
|
|
|
.format = desc.planes[n],
|
|
|
|
.render_src = true,
|
|
|
|
.src_linear = true,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (params.format->ctype != RA_CTYPE_UNORM)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
p->tex[n] = ra_create_wrapped_tex(mapper->ra, ¶ms,
|
|
|
|
p->gl_textures[n]);
|
|
|
|
if (!p->tex[n])
|
|
|
|
return -1;
|
|
|
|
}
|
vaapi: determine surface format in decoder, not in renderer
Until now, we have made the assumption that a driver will use only 1
hardware surface format. the format is dictated by the driver (you
don't create surfaces with a specific format - you just pass a
rt_format and get a surface that will be in a specific driver-chosen
format).
In particular, the renderer created a dummy surface to probe the format,
and hoped the decoder would produce the same format. Due to a driver
bug this required a workaround to actually get the same format as the
driver did.
Change this so that the format is determined in the decoder. The format
is then passed down as hw_subfmt, which allows the renderer to configure
itself with the correct format. If the hardware surface changes its
format midstream, the renderer can be reconfigured using the normal
mechanisms.
This calls va_surface_init_subformat() each time after the decoder
returns a surface. Since libavcodec/AVFrame has no concept of sub-
formats, this is unavoidable. It creates and destroys a derived
VAImage, but this shouldn't have any bad performance effects (at
least I didn't notice any measurable effects).
Note that vaDeriveImage() failures are silently ignored as some
drivers (the vdpau wrapper) support neither vaDeriveImage, nor EGL
interop. In addition, we still probe whether we can map an image
in the EGL interop code. This is important as it's the only way
to determine whether EGL interop is supported at all. With respect
to the driver bug mentioned above, it doesn't matter which format
the test surface has.
In vf_vavpp, also remove the rt_format guessing business. I think the
existing logic was a bit meaningless anyway. It's not even a given
that vavpp produces the same rt_format for output.
2016-04-11 18:46:05 +00:00
|
|
|
}
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif
|
vaapi: determine surface format in decoder, not in renderer
Until now, we have made the assumption that a driver will use only 1
hardware surface format. the format is dictated by the driver (you
don't create surfaces with a specific format - you just pass a
rt_format and get a surface that will be in a specific driver-chosen
format).
In particular, the renderer created a dummy surface to probe the format,
and hoped the decoder would produce the same format. Due to a driver
bug this required a workaround to actually get the same format as the
driver did.
Change this so that the format is determined in the decoder. The format
is then passed down as hw_subfmt, which allows the renderer to configure
itself with the correct format. If the hardware surface changes its
format midstream, the renderer can be reconfigured using the normal
mechanisms.
This calls va_surface_init_subformat() each time after the decoder
returns a surface. Since libavcodec/AVFrame has no concept of sub-
formats, this is unavoidable. It creates and destroys a derived
VAImage, but this shouldn't have any bad performance effects (at
least I didn't notice any measurable effects).
Note that vaDeriveImage() failures are silently ignored as some
drivers (the vdpau wrapper) support neither vaDeriveImage, nor EGL
interop. In addition, we still probe whether we can map an image
in the EGL interop code. This is important as it's the only way
to determine whether EGL interop is supported at all. With respect
to the driver bug mentioned above, it doesn't matter which format
the test surface has.
In vf_vavpp, also remove the rt_format guessing business. I think the
existing logic was a bit meaningless anyway. It's not even a given
that vavpp produces the same rt_format for output.
2016-04-11 18:46:05 +00:00
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
if (!p_owner->probing_formats && !check_fmt(mapper, mapper->dst_params.imgfmt))
|
|
|
|
{
|
|
|
|
MP_FATAL(mapper, "unsupported VA image format %s\n",
|
|
|
|
mp_imgfmt_to_name(mapper->dst_params.imgfmt));
|
|
|
|
return -1;
|
|
|
|
}
|
vaapi: determine surface format in decoder, not in renderer
Until now, we have made the assumption that a driver will use only 1
hardware surface format. the format is dictated by the driver (you
don't create surfaces with a specific format - you just pass a
rt_format and get a surface that will be in a specific driver-chosen
format).
In particular, the renderer created a dummy surface to probe the format,
and hoped the decoder would produce the same format. Due to a driver
bug this required a workaround to actually get the same format as the
driver did.
Change this so that the format is determined in the decoder. The format
is then passed down as hw_subfmt, which allows the renderer to configure
itself with the correct format. If the hardware surface changes its
format midstream, the renderer can be reconfigured using the normal
mechanisms.
This calls va_surface_init_subformat() each time after the decoder
returns a surface. Since libavcodec/AVFrame has no concept of sub-
formats, this is unavoidable. It creates and destroys a derived
VAImage, but this shouldn't have any bad performance effects (at
least I didn't notice any measurable effects).
Note that vaDeriveImage() failures are silently ignored as some
drivers (the vdpau wrapper) support neither vaDeriveImage, nor EGL
interop. In addition, we still probe whether we can map an image
in the EGL interop code. This is important as it's the only way
to determine whether EGL interop is supported at all. With respect
to the driver bug mentioned above, it doesn't matter which format
the test surface has.
In vf_vavpp, also remove the rt_format guessing business. I think the
existing logic was a bit meaningless anyway. It's not even a given
that vavpp produces the same rt_format for output.
2016-04-11 18:46:05 +00:00
|
|
|
|
2015-09-24 22:20:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ADD_ATTRIB(name, value) \
|
|
|
|
do { \
|
|
|
|
assert(num_attribs + 3 < MP_ARRAY_SIZE(attribs)); \
|
|
|
|
attribs[num_attribs++] = (name); \
|
|
|
|
attribs[num_attribs++] = (value); \
|
|
|
|
attribs[num_attribs] = EGL_NONE; \
|
|
|
|
} while(0)
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static int mapper_map(struct ra_hwdec_mapper *mapper)
|
2015-09-24 22:20:57 +00:00
|
|
|
{
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner *p_owner = mapper->owner->priv;
|
|
|
|
struct priv *p = mapper->priv;
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
bool is_gl = ra_is_gl(mapper->ra);
|
|
|
|
#endif
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
const struct pl_gpu *gpu = ra_pl_get(mapper->ra);
|
|
|
|
#endif
|
2015-09-24 22:20:57 +00:00
|
|
|
VAStatus status;
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
VADisplay *display = p_owner->display;
|
2015-09-24 22:20:57 +00:00
|
|
|
|
2017-11-30 23:35:28 +00:00
|
|
|
#if VA_CHECK_VERSION(1, 1, 0)
|
2017-10-07 16:49:56 +00:00
|
|
|
if (p->esh_not_implemented)
|
|
|
|
goto esh_failed;
|
|
|
|
|
|
|
|
status = vaExportSurfaceHandle(display, va_surface_id(mapper->src),
|
|
|
|
VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
|
|
|
|
VA_EXPORT_SURFACE_READ_ONLY |
|
|
|
|
VA_EXPORT_SURFACE_SEPARATE_LAYERS,
|
|
|
|
&p->desc);
|
2018-12-30 22:59:48 +00:00
|
|
|
if (!CHECK_VA_STATUS(mapper, "vaExportSurfaceHandle()")) {
|
2017-10-07 16:49:56 +00:00
|
|
|
if (status == VA_STATUS_ERROR_UNIMPLEMENTED)
|
|
|
|
p->esh_not_implemented = true;
|
|
|
|
goto esh_failed;
|
|
|
|
}
|
|
|
|
p->surface_acquired = true;
|
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
#if HAVE_GL
|
|
|
|
if (is_gl) {
|
|
|
|
GL *gl = ra_gl_get(mapper->ra);
|
|
|
|
for (int n = 0; n < p->num_planes; n++) {
|
|
|
|
int attribs[20] = {EGL_NONE};
|
|
|
|
int num_attribs = 0;
|
|
|
|
|
|
|
|
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, p->desc.layers[n].drm_format);
|
|
|
|
ADD_ATTRIB(EGL_WIDTH, p->tex[n]->params.w);
|
|
|
|
ADD_ATTRIB(EGL_HEIGHT, p->tex[n]->params.h);
|
|
|
|
|
|
|
|
#define ADD_PLANE_ATTRIBS(plane) do { \
|
|
|
|
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _FD_EXT, \
|
|
|
|
p->desc.objects[p->desc.layers[n].object_index[plane]].fd); \
|
|
|
|
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _OFFSET_EXT, \
|
|
|
|
p->desc.layers[n].offset[plane]); \
|
|
|
|
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _PITCH_EXT, \
|
|
|
|
p->desc.layers[n].pitch[plane]); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
ADD_PLANE_ATTRIBS(0);
|
|
|
|
if (p->desc.layers[n].num_planes > 1)
|
|
|
|
ADD_PLANE_ATTRIBS(1);
|
|
|
|
if (p->desc.layers[n].num_planes > 2)
|
|
|
|
ADD_PLANE_ATTRIBS(2);
|
|
|
|
if (p->desc.layers[n].num_planes > 3)
|
|
|
|
ADD_PLANE_ATTRIBS(3);
|
|
|
|
|
|
|
|
p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
|
|
|
|
EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
|
|
|
if (!p->images[n])
|
|
|
|
goto esh_failed;
|
|
|
|
|
|
|
|
gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
|
|
|
|
p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
|
|
|
|
|
|
|
|
mapper->tex[n] = p->tex[n];
|
|
|
|
}
|
|
|
|
gl->BindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
if (gpu) {
|
|
|
|
struct ra_imgfmt_desc desc = {0};
|
|
|
|
if (!ra_get_imgfmt_desc(mapper->ra, mapper->dst_params.imgfmt, &desc))
|
2017-10-07 16:49:56 +00:00
|
|
|
goto esh_failed;
|
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
for (int n = 0; n < p->desc.num_layers; n++) {
|
|
|
|
if (p->desc.layers[n].num_planes > 1) {
|
|
|
|
// Should never happen because we request separate layers
|
|
|
|
MP_ERR(mapper, "Multi-plane VA surfaces are not supported\n");
|
|
|
|
goto esh_failed;
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct ra_format *format = desc.planes[n];
|
|
|
|
int id = p->desc.layers[n].object_index[0];
|
|
|
|
int fd = p->desc.objects[id].fd;
|
|
|
|
uint32_t size = p->desc.objects[id].size;
|
|
|
|
uint32_t offset = p->desc.layers[n].offset[0];
|
|
|
|
|
|
|
|
struct pl_tex_params tex_params = {
|
|
|
|
.w = mp_image_plane_w(&p->layout, n),
|
|
|
|
.h = mp_image_plane_h(&p->layout, n),
|
|
|
|
.d = 0,
|
|
|
|
.format = format->priv,
|
|
|
|
.sampleable = true,
|
|
|
|
.sample_mode = format->linear_filter ? PL_TEX_SAMPLE_LINEAR
|
|
|
|
: PL_TEX_SAMPLE_NEAREST,
|
|
|
|
.import_handle = PL_HANDLE_DMA_BUF,
|
|
|
|
.shared_mem = (struct pl_shared_mem) {
|
|
|
|
.handle = {
|
|
|
|
.fd = fd,
|
|
|
|
},
|
|
|
|
.size = size,
|
|
|
|
.offset = offset,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct pl_tex *pltex = pl_tex_create(gpu, &tex_params);
|
|
|
|
if (!pltex) {
|
|
|
|
goto esh_failed;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ra_tex *ratex = talloc_ptrtype(NULL, ratex);
|
|
|
|
int ret = mppl_wrap_tex(mapper->ra, pltex, ratex);
|
|
|
|
if (!ret) {
|
|
|
|
pl_tex_destroy(gpu, &pltex);
|
|
|
|
talloc_free(ratex);
|
|
|
|
goto esh_failed;
|
|
|
|
}
|
|
|
|
mapper->tex[n] = ratex;
|
|
|
|
|
|
|
|
MP_TRACE(mapper, "Object %d with fd %d imported as %p\n",
|
|
|
|
id, fd, ratex);
|
|
|
|
}
|
2017-10-07 16:49:56 +00:00
|
|
|
}
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif
|
2017-10-07 16:49:56 +00:00
|
|
|
|
|
|
|
if (p->desc.fourcc == VA_FOURCC_YV12)
|
|
|
|
MPSWAP(struct ra_tex*, mapper->tex[1], mapper->tex[2]);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
esh_failed:
|
|
|
|
if (p->surface_acquired) {
|
|
|
|
for (int n = 0; n < p->desc.num_objects; n++)
|
|
|
|
close(p->desc.objects[n].fd);
|
|
|
|
p->surface_acquired = false;
|
|
|
|
}
|
2018-12-30 22:59:48 +00:00
|
|
|
#endif // VA_CHECK_VERSION
|
|
|
|
|
|
|
|
#if HAVE_GL
|
|
|
|
if (is_gl) {
|
|
|
|
GL *gl = ra_gl_get(mapper->ra);
|
|
|
|
VAImage *va_image = &p->current_image;
|
|
|
|
status = vaDeriveImage(display, va_surface_id(mapper->src), va_image);
|
|
|
|
if (!CHECK_VA_STATUS(mapper, "vaDeriveImage()"))
|
2017-02-17 16:20:33 +00:00
|
|
|
goto err;
|
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
VABufferInfo buffer_info = {.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME};
|
|
|
|
status = vaAcquireBufferHandle(display, va_image->buf, &buffer_info);
|
|
|
|
if (!CHECK_VA_STATUS(mapper, "vaAcquireBufferHandle()"))
|
2015-09-24 22:20:57 +00:00
|
|
|
goto err;
|
2018-12-30 22:59:48 +00:00
|
|
|
p->buffer_acquired = true;
|
|
|
|
|
|
|
|
int drm_fmts[8] = {
|
|
|
|
// 1 bytes per component, 1-4 components
|
|
|
|
MKTAG('R', '8', ' ', ' '), // DRM_FORMAT_R8
|
|
|
|
MKTAG('G', 'R', '8', '8'), // DRM_FORMAT_GR88
|
|
|
|
0, // untested (DRM_FORMAT_RGB888?)
|
|
|
|
0, // untested (DRM_FORMAT_RGBA8888?)
|
|
|
|
// 2 bytes per component, 1-4 components
|
|
|
|
MKTAG('R', '1', '6', ' '), // proposed DRM_FORMAT_R16
|
|
|
|
MKTAG('G', 'R', '3', '2'), // proposed DRM_FORMAT_GR32
|
|
|
|
0, // N/A
|
|
|
|
0, // N/A
|
|
|
|
};
|
2015-09-24 22:20:57 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
for (int n = 0; n < p->num_planes; n++) {
|
|
|
|
int attribs[20] = {EGL_NONE};
|
|
|
|
int num_attribs = 0;
|
|
|
|
|
|
|
|
const struct ra_format *fmt = p->tex[n]->params.format;
|
|
|
|
int n_comp = fmt->num_components;
|
|
|
|
int comp_s = fmt->component_size[n] / 8;
|
|
|
|
if (n_comp < 1 || n_comp > 3 || comp_s < 1 || comp_s > 2)
|
|
|
|
goto err;
|
|
|
|
int drm_fmt = drm_fmts[n_comp - 1 + (comp_s - 1) * 4];
|
|
|
|
if (!drm_fmt)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, drm_fmt);
|
|
|
|
ADD_ATTRIB(EGL_WIDTH, p->tex[n]->params.w);
|
|
|
|
ADD_ATTRIB(EGL_HEIGHT, p->tex[n]->params.h);
|
|
|
|
ADD_ATTRIB(EGL_DMA_BUF_PLANE0_FD_EXT, buffer_info.handle);
|
|
|
|
ADD_ATTRIB(EGL_DMA_BUF_PLANE0_OFFSET_EXT, va_image->offsets[n]);
|
|
|
|
ADD_ATTRIB(EGL_DMA_BUF_PLANE0_PITCH_EXT, va_image->pitches[n]);
|
|
|
|
|
|
|
|
p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
|
|
|
|
EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
|
|
|
if (!p->images[n])
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
|
|
|
|
p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
|
|
|
|
|
|
|
|
mapper->tex[n] = p->tex[n];
|
|
|
|
}
|
|
|
|
gl->BindTexture(GL_TEXTURE_2D, 0);
|
2015-09-24 22:20:57 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
if (va_image->format.fourcc == VA_FOURCC_YV12)
|
|
|
|
MPSWAP(struct ra_tex*, mapper->tex[1], mapper->tex[2]);
|
2015-09-25 10:07:20 +00:00
|
|
|
|
2018-12-30 22:59:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if HAVE_VULKAN
|
|
|
|
// Seems unnecessary to support Vulkan interop with old libva API.
|
|
|
|
if (gpu) {
|
|
|
|
mapper_unmap(mapper);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
#endif
|
2015-09-24 22:20:57 +00:00
|
|
|
|
|
|
|
err:
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
if (!p_owner->probing_formats)
|
|
|
|
MP_FATAL(mapper, "mapping VAAPI EGL image failed\n");
|
2015-09-24 22:20:57 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static bool try_format(struct ra_hwdec *hw, struct mp_image *surface)
|
2015-09-26 18:15:52 +00:00
|
|
|
{
|
|
|
|
bool ok = false;
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct ra_hwdec_mapper *mapper = ra_hwdec_mapper_create(hw, &surface->params);
|
|
|
|
if (mapper)
|
|
|
|
ok = ra_hwdec_mapper_map(mapper, surface) >= 0;
|
|
|
|
ra_hwdec_mapper_free(&mapper);
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
return ok;
|
|
|
|
}
|
2015-09-26 18:15:52 +00:00
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
static void determine_working_formats(struct ra_hwdec *hw)
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
{
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
struct priv_owner *p = hw->priv;
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
int num_formats = 0;
|
|
|
|
int *formats = NULL;
|
|
|
|
|
|
|
|
p->probing_formats = true;
|
|
|
|
|
2017-04-23 13:56:45 +00:00
|
|
|
AVHWFramesConstraints *fc =
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
av_hwdevice_get_hwframe_constraints(p->ctx->av_device_ref, NULL);
|
2017-04-23 13:56:45 +00:00
|
|
|
if (!fc) {
|
2017-10-23 08:53:28 +00:00
|
|
|
MP_WARN(hw, "failed to retrieve libavutil frame constraints\n");
|
2017-04-23 13:56:45 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
for (int n = 0; fc->valid_sw_formats[n] != AV_PIX_FMT_NONE; n++) {
|
|
|
|
AVBufferRef *fref = NULL;
|
|
|
|
struct mp_image *s = NULL;
|
|
|
|
AVFrame *frame = NULL;
|
|
|
|
fref = av_hwframe_ctx_alloc(p->ctx->av_device_ref);
|
|
|
|
if (!fref)
|
|
|
|
goto err;
|
|
|
|
AVHWFramesContext *fctx = (void *)fref->data;
|
|
|
|
fctx->format = AV_PIX_FMT_VAAPI;
|
|
|
|
fctx->sw_format = fc->valid_sw_formats[n];
|
|
|
|
fctx->width = 128;
|
|
|
|
fctx->height = 128;
|
|
|
|
if (av_hwframe_ctx_init(fref) < 0)
|
|
|
|
goto err;
|
|
|
|
frame = av_frame_alloc();
|
|
|
|
if (!frame)
|
|
|
|
goto err;
|
|
|
|
if (av_hwframe_get_buffer(fref, frame, 0) < 0)
|
|
|
|
goto err;
|
|
|
|
s = mp_image_from_av_frame(frame);
|
|
|
|
if (!s || !mp_image_params_valid(&s->params))
|
|
|
|
goto err;
|
|
|
|
if (try_format(hw, s))
|
|
|
|
MP_TARRAY_APPEND(p, formats, num_formats, s->params.hw_subfmt);
|
|
|
|
err:
|
|
|
|
talloc_free(s);
|
|
|
|
av_frame_free(&frame);
|
|
|
|
av_buffer_unref(&fref);
|
2015-09-26 18:15:52 +00:00
|
|
|
}
|
2017-04-23 13:56:45 +00:00
|
|
|
av_hwframe_constraints_free(&fc);
|
2015-09-26 18:15:52 +00:00
|
|
|
|
vo_opengl, vaapi: properly probe 10 bit rendering support
There are going to be users who have a Mesa installation which do not
support 10 bit, but a GPU which can decode to 10 bit. So it's probably
better not to hardcode whether it is supported.
Introduce a more general way to signal supported formats from renderer
to decoder. Obviously this is imperfect, because it still isn't part of
proper format negotation (for example, what if there's a vavpp filter,
which accepts anything). Still slightly better than before.
I don't know any way to probe for vaapi dmabuf/EGL dmabuf support
properly (in particular testing specific formats, not just general
availability). So we stay with the current approach and try to create
and map dummy surfaces on init to probe for support. Overdo it and check
all formats that AVHWFramesConstraints reports, instead of only NV12 and
P010 surfaces.
Since we can support unknown formats now, add explicitly checks to the
EGL/dmabuf mapper code to reject unsupported formats. I also noticed
that libavutil signals support for RGB0/BGR0, but couldn't get it to
work. Remove the DRM formats that are unused/didn't work the way I tried
to use them.
With this, 10 bit decoding + rendering should work, provided you have
a capable CPU and a patched Mesa. The required Mesa patch adds support
for the R16 and GR32 formats. It was sent by a Kodi developer to the
Mesa developer mailing list and was not accepted yet.
2017-01-13 12:36:02 +00:00
|
|
|
done:
|
|
|
|
MP_TARRAY_APPEND(p, formats, num_formats, 0); // terminate it
|
|
|
|
p->formats = formats;
|
|
|
|
p->probing_formats = false;
|
|
|
|
|
|
|
|
MP_VERBOSE(hw, "Supported formats:\n");
|
|
|
|
for (int n = 0; formats[n]; n++)
|
|
|
|
MP_VERBOSE(hw, " %s\n", mp_imgfmt_to_name(formats[n]));
|
2015-09-26 18:15:52 +00:00
|
|
|
}
|
|
|
|
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
const struct ra_hwdec_driver ra_hwdec_vaegl = {
|
2016-02-01 19:02:52 +00:00
|
|
|
.name = "vaapi-egl",
|
vo_opengl: separate hwdec context and mapping, port it to use ra
This does two separate rather intrusive things:
1. Make the hwdec context (which does initialization, provides the
device to the decoder, and other basic state) and frame mapping
(getting textures from a mp_image) separate. This is more
flexible, and you could map multiple images at once. It will
help removing some hwdec special-casing from video.c.
2. Switch all hwdec API use to ra. Of course all code is still
GL specific, but in theory it would be possible to support other
backends. The most important change is that the hwdec interop
returns ra objects, instead of anything GL specific. This removes
the last dependency on GL-specific header files from video.c.
I'm mixing these separate changes because both requires essentially
rewriting all the glue code, so better do them at once. For the same
reason, this change isn't done incrementally.
hwdec_ios.m is untested, since I can't test it. Apart from superficial
mistakes, this also requires dealing with Apple's texture format
fuckups: they force you to use GL_LUMINANCE[_ALPHA] instead of GL_RED
and GL_RG. We also need to report the correct format via ra_tex to
the renderer, which is done by find_la_variant(). It's unknown whether
this works correctly.
hwdec_rpi.c as well as vo_rpi.c are still broken. (I need to pull my
RPI out of a dusty pile of devices and cables, so, later.)
2017-08-10 15:48:33 +00:00
|
|
|
.priv_size = sizeof(struct priv_owner),
|
|
|
|
.imgfmts = {IMGFMT_VAAPI, 0},
|
|
|
|
.init = init,
|
|
|
|
.uninit = uninit,
|
|
|
|
.mapper = &(const struct ra_hwdec_mapper_driver){
|
|
|
|
.priv_size = sizeof(struct priv),
|
|
|
|
.init = mapper_init,
|
|
|
|
.uninit = mapper_uninit,
|
|
|
|
.map = mapper_map,
|
|
|
|
.unmap = mapper_unmap,
|
|
|
|
},
|
2015-09-24 22:20:57 +00:00
|
|
|
};
|