summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLongChair <longchair@hotmail.com>2018-04-29 15:09:16 +0200
committerJan Ekström <jeebjp@gmail.com>2018-05-01 20:48:02 +0300
commit9f2970f28a28076897fda1100de2b6eb9a92be79 (patch)
tree7cd8db166d6b6c621684cdd9750866c9842c454a
parent11f915f5ef7d622a225bee6ab98ee6a9da34991f (diff)
downloadmpv-9f2970f28a28076897fda1100de2b6eb9a92be79.tar.bz2
mpv-9f2970f28a28076897fda1100de2b6eb9a92be79.tar.xz
drm/atomic: refactor hwdec_drmprime_drm with native resources
That new API was introduced and allows to have several native resources. Thisuses that mechanisma for drm resources rather than the deprecated opengl-cb structs. This patch therefore add two structs that can be used with the drm atomic interop. - mpv_opengl_drm_params : which will hold all the drm handles - mpv_opengl_drm_osd_size : which will hold osd layer size This commit adds a drm-osd-size=WxH parameter to commandline which allows to define the OSD plane dimension. OSD can be upscaled to screen resolution when having OSD at video resolution is too heavy. This is especially useful for UHD modes on embedded devices where the GPU cannot handle UHD modes at a decent framerate.
-rw-r--r--DOCS/man/vo.rst12
-rw-r--r--libmpv/render.h12
-rw-r--r--libmpv/render_gl.h31
-rw-r--r--video/out/drm_common.c1
-rw-r--r--video/out/drm_common.h1
-rw-r--r--video/out/gpu/libmpv_gpu.c9
-rw-r--r--video/out/opengl/context_drm_egl.c35
-rw-r--r--video/out/opengl/hwdec_drmprime_drm.c47
8 files changed, 113 insertions, 35 deletions
diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index 672f3c68f6..96ab1f7cf9 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -488,11 +488,6 @@ Available video output drivers are:
Mode ID to use (resolution and frame rate).
(default: 0)
- ``--drm-overlay=<number>``
- Select the DRM overlay index to use.
- Overlay index is zero based, and related to crtc.
- (default: 0)
-
``--drm-format=<xrgb8888,xrgb2101010>``
Select the DRM format to use (default: xrgb8888). This allows you to
choose the bit depth of the DRM mode. xrgb8888 is your usual 24 bit per
@@ -506,6 +501,13 @@ Available video output drivers are:
This currently only has an effect when used together with the ``drm``
backend for the ``gpu`` VO. The ``drm`` VO always uses xrgb8888.
+ ``--drm-osd-size=<[WxH]>``
+ Sets the OSD OpenGL size to the specified size. OSD will then be upscaled
+ to the current screen resolution. This option can be useful when using
+ several layers in high resolutions with a GPU which cannot handle it.
+ Note : this option is only available with DRM atomic support.
+ (default: display resolution)
+
``mediacodec_embed`` (Android)
Renders ``IMGFMT_MEDIACODEC`` frames directly to an ``android.view.Surface``.
Requires ``--hwdec=mediacodec`` for hardware decoding, along with
diff --git a/libmpv/render.h b/libmpv/render.h
index 5a39d4e1c6..253b2b43f9 100644
--- a/libmpv/render.h
+++ b/libmpv/render.h
@@ -276,6 +276,18 @@ typedef enum mpv_render_param_type {
* in the same way.
*/
MPV_RENDER_PARAM_SKIP_RENDERING = 13,
+ /**
+ * DRM display, contains drm display handles.
+ * Valid for mpv_render_context_create().
+ * Type : struct mpv_opengl_drm_params*
+ */
+ MPV_RENDER_PARAM_DRM_DISPLAY = 14,
+ /**
+ * DRM osd size, contains osd dimensions.
+ * Valid for mpv_render_context_create().
+ * Type : struct mpv_opengl_drm_osd_size*
+ */
+ MPV_RENDER_PARAM_DRM_OSD_SIZE = 15,
} mpv_render_param_type;
/**
diff --git a/libmpv/render_gl.h b/libmpv/render_gl.h
index a4872a066b..574be86ffd 100644
--- a/libmpv/render_gl.h
+++ b/libmpv/render_gl.h
@@ -147,6 +147,37 @@ typedef struct mpv_opengl_fbo {
int internal_format;
} mpv_opengl_fbo;
+typedef struct mpv_opengl_drm_params {
+ /**
+ * DRM fd (int). set this to -1 if invalid.
+ */
+ int fd;
+
+ /**
+ * Currently used crtc id
+ */
+ int crtc_id;
+
+ /**
+ * Currently used connector id
+ */
+ int connector_id;
+
+ /**
+ * Pointer to a drmModeAtomicReq pointer that is being used for the renderloop.
+ * This pointer should hold a pointer to the atomic request pointer
+ * The atomic request pointer is usually changed at every renderloop.
+ */
+ struct _drmModeAtomicReq **atomic_request_ptr;
+} mpv_opengl_drm_params;
+
+typedef struct mpv_opengl_drm_osd_size {
+ /**
+ * size of the OSD in pixels.
+ */
+ int width, height;
+} mpv_opengl_drm_osd_size;
+
#ifdef __cplusplus
}
#endif
diff --git a/video/out/drm_common.c b/video/out/drm_common.c
index 68c64d4298..8723f59bd3 100644
--- a/video/out/drm_common.c
+++ b/video/out/drm_common.c
@@ -51,6 +51,7 @@ const struct m_sub_options drm_conf = {
OPT_CHOICE("drm-format", drm_format, 0,
({"xrgb8888", DRM_OPTS_FORMAT_XRGB8888},
{"xrgb2101010", DRM_OPTS_FORMAT_XRGB2101010})),
+ OPT_SIZE_BOX("drm-osd-size", drm_osd_size, 0),
{0},
},
.size = sizeof(struct drm_opts),
diff --git a/video/out/drm_common.h b/video/out/drm_common.h
index ba1209e43c..16064a47fb 100644
--- a/video/out/drm_common.h
+++ b/video/out/drm_common.h
@@ -50,6 +50,7 @@ struct drm_opts {
int drm_mode_id;
int drm_overlay_id;
int drm_format;
+ struct m_geometry drm_osd_size;
};
bool vt_switcher_init(struct vt_switcher *s, struct mp_log *log);
diff --git a/video/out/gpu/libmpv_gpu.c b/video/out/gpu/libmpv_gpu.c
index f687c97b51..fce2acfa4d 100644
--- a/video/out/gpu/libmpv_gpu.c
+++ b/video/out/gpu/libmpv_gpu.c
@@ -1,6 +1,7 @@
#include "config.h"
#include "hwdec.h"
#include "libmpv_gpu.h"
+#include "libmpv/render_gl.h"
#include "video.h"
#include "video/out/libmpv.h"
@@ -31,6 +32,14 @@ static const struct native_resource_entry native_resource_map[] = {
.name = "wl",
.size = 0,
},
+ [MPV_RENDER_PARAM_DRM_DISPLAY] = {
+ .name = "drm_params",
+ .size = sizeof (mpv_opengl_drm_params),
+ },
+ [MPV_RENDER_PARAM_DRM_OSD_SIZE] = {
+ .name = "drm_osd_size",
+ .size = sizeof (mpv_opengl_drm_osd_size),
+ },
};
static int init(struct render_backend *ctx, mpv_render_param *params)
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index e56055bc97..cf37cb524a 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -28,7 +28,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include "libmpv/opengl_cb.h"
+#include "libmpv/render_gl.h"
#include "video/out/drm_common.h"
#include "common/common.h"
#include "osdep/timer.h"
@@ -80,7 +80,8 @@ struct priv {
bool vt_switcher_active;
struct vt_switcher vt_switcher;
- struct mpv_opengl_cb_drm_params drm_params;
+ struct mpv_opengl_drm_params drm_params;
+ struct mpv_opengl_drm_osd_size osd_size;
};
// Not general. Limited to only the formats being used in this module
@@ -194,11 +195,11 @@ static bool init_gbm(struct ra_ctx *ctx)
}
MP_VERBOSE(ctx->vo, "Initializing GBM surface (%d x %d)\n",
- p->kms->mode.hdisplay, p->kms->mode.vdisplay);
+ p->osd_size.width, p->osd_size.height);
p->gbm.surface = gbm_surface_create(
p->gbm.device,
- p->kms->mode.hdisplay,
- p->kms->mode.vdisplay,
+ p->osd_size.width,
+ p->osd_size.height,
p->gbm_format,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
if (!p->gbm.surface) {
@@ -325,7 +326,7 @@ static bool drm_atomic_egl_start_frame(struct ra_swapchain *sw, struct ra_fbo *o
if (p->kms->atomic_context) {
if (!p->kms->atomic_context->request) {
p->kms->atomic_context->request = drmModeAtomicAlloc();
- p->drm_params.atomic_request = p->kms->atomic_context->request;
+ p->drm_params.atomic_request_ptr = &p->kms->atomic_context->request;
}
return ra_gl_ctx_start_frame(sw, out_fbo);
}
@@ -383,7 +384,7 @@ static void drm_egl_swap_buffers(struct ra_ctx *ctx)
if (atomic_ctx) {
drmModeAtomicFree(atomic_ctx->request);
- p->drm_params.atomic_request = atomic_ctx->request = drmModeAtomicAlloc();
+ atomic_ctx->request = drmModeAtomicAlloc();
}
gbm_surface_release_buffer(p->gbm.surface, p->gbm.bo);
@@ -495,6 +496,20 @@ static bool drm_egl_init(struct ra_ctx *ctx)
return false;
}
+ if (ctx->vo->opts->drm_opts->drm_osd_size.wh_valid) {
+ if (p->kms->atomic_context) {
+ p->osd_size.width = ctx->vo->opts->drm_opts->drm_osd_size.w;
+ p->osd_size.height = ctx->vo->opts->drm_opts->drm_osd_size.h;
+ } else {
+ p->osd_size.width = p->kms->mode.hdisplay;
+ p->osd_size.height = p->kms->mode.vdisplay;
+ MP_WARN(ctx, "Setting OSD size is only available with DRM atomic, defaulting to screen resolution\n");
+ }
+ } else {
+ p->osd_size.width = p->kms->mode.hdisplay;
+ p->osd_size.height = p->kms->mode.vdisplay;
+ }
+
uint32_t argb_format;
uint32_t xrgb_format;
if (DRM_OPTS_FORMAT_XRGB2101010 == ctx->vo->opts->drm_opts->drm_format) {
@@ -550,9 +565,10 @@ static bool drm_egl_init(struct ra_ctx *ctx)
}
p->drm_params.fd = p->kms->fd;
+ p->drm_params.connector_id = p->kms->connector->connector_id;
p->drm_params.crtc_id = p->kms->crtc_id;
if (p->kms->atomic_context)
- p->drm_params.atomic_request = p->kms->atomic_context->request;
+ p->drm_params.atomic_request_ptr = &p->kms->atomic_context->request;
struct ra_gl_ctx_params params = {
.swap_buffers = drm_egl_swap_buffers,
.external_swapchain = p->kms->atomic_context ? &drm_atomic_swapchain :
@@ -561,7 +577,8 @@ static bool drm_egl_init(struct ra_ctx *ctx)
if (!ra_gl_ctx_init(ctx, &p->gl, params))
return false;
- ra_add_native_resource(ctx->ra, "opengl-cb-drm-params", &p->drm_params);
+ ra_add_native_resource(ctx->ra, "drm_params", &p->drm_params);
+ ra_add_native_resource(ctx->ra, "drm_osd_size", &p->osd_size);
return true;
}
diff --git a/video/out/opengl/hwdec_drmprime_drm.c b/video/out/opengl/hwdec_drmprime_drm.c
index 422612287c..0c7f86a584 100644
--- a/video/out/opengl/hwdec_drmprime_drm.c
+++ b/video/out/opengl/hwdec_drmprime_drm.c
@@ -29,7 +29,7 @@
#include "video/hwdec.h"
#include "common/msg.h"
#include "options/m_config.h"
-#include "libmpv/opengl_cb.h"
+#include "libmpv/render_gl.h"
#include "video/out/drm_common.h"
#include "video/out/drm_prime.h"
#include "video/out/gpu/hwdec.h"
@@ -117,25 +117,34 @@ static int overlay_frame(struct ra_hwdec *hw, struct mp_image *hw_image,
struct drm_frame next_frame = {0};
int ret;
+ // grab atomic request from native resources
+ if (p->ctx) {
+ struct mpv_opengl_drm_params *drm_params;
+ drm_params = (mpv_opengl_drm_params *)ra_get_native_resource(hw->ra, "drm_params");
+ if (!drm_params) {
+ MP_ERR(hw, "Failed to retrieve drm params from native resources\n");
+ return -1;
+ }
+ if (drm_params->atomic_request_ptr) {
+ request = *drm_params->atomic_request_ptr;
+ } else {
+ MP_ERR(hw, "drm params pointer to atomic request is invalid");
+ return -1;
+ }
+ }
+
if (hw_image) {
- // grab opengl-cb windowing info to eventually upscale the overlay
- // as egl windows could be upscaled to primary plane.
- struct mpv_opengl_cb_window_pos *glparams =
- ra_get_native_resource(hw->ra, "opengl-cb-window-pos");
- if (glparams) {
- scale_dst_rect(hw, glparams->width, glparams->height, dst, &p->dst);
+ // grab osd windowing info to eventually upscale the overlay
+ // as egl windows could be upscaled to osd plane.
+ struct mpv_opengl_drm_osd_size *osd_size = ra_get_native_resource(hw->ra, "drm_osd_size");
+ if (osd_size) {
+ scale_dst_rect(hw, osd_size->width, osd_size->height, dst, &p->dst);
} else {
p->dst = *dst;
}
p->src = *src;
- // grab drm interop info
- struct mpv_opengl_cb_drm_params *drmparams =
- ra_get_native_resource(hw->ra, "opengl-cb-drm-params");
- if (drmparams)
- request = (drmModeAtomicReq *)drmparams->atomic_request;
-
next_frame.image = hw_image;
desc = (AVDRMFrameDescriptor *)hw_image->planes[0];
@@ -210,15 +219,11 @@ static int init(struct ra_hwdec *hw)
drm_overlay = opts->drm_overlay_id;
talloc_free(tmp);
- struct mpv_opengl_cb_drm_params *params =
- ra_get_native_resource(hw->ra, "opengl-cb-drm-params");
- if (!params) {
- MP_VERBOSE(hw, "Could not get drm interop info.\n");
- goto err;
- }
+ struct mpv_opengl_drm_params *drm_params;
- if (params->fd) {
- p->ctx = drm_atomic_create_context(p->log, params->fd, params->crtc_id,
+ drm_params = ra_get_native_resource(hw->ra, "drm_params");
+ if (drm_params) {
+ p->ctx = drm_atomic_create_context(p->log, drm_params->fd, drm_params->crtc_id,
drm_overlay);
if (!p->ctx) {
mp_err(p->log, "Failed to retrieve DRM atomic context.\n");