mirror of
https://github.com/mpv-player/mpv
synced 2025-03-30 07:18:17 +00:00
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.
This commit is contained in:
parent
11f915f5ef
commit
9f2970f28a
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user