From aa75a0e9d29e401dd048f6ec077b8c3c4129efee Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 11 Mar 2024 20:46:00 +0100 Subject: vo_drm: add support for YUYV format As the first aligned format this required a fix to reconfig(). Adding the other component-swapped formats in this group would be trivial but I checked the DRM database [1] and no driver exists that supports one of those but not YUYV and this is quite fringe as-is, so I opted not to. [1] --- DOCS/man/vo.rst | 15 +++++++++------ video/out/drm_common.c | 4 +++- video/out/drm_common.h | 11 +++++++---- video/out/vo_drm.c | 14 ++++++++++---- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index 2c9390114d..84c18f89bd 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -627,17 +627,20 @@ Available video output drivers are: lower resolution (the video when handled by the hwdec will be on the drmprime-video plane and at full 4K resolution) - ``--drm-format=`` + ``--drm-format=`` 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 - pixel/8 bits per channel packed RGB format with 8 bits of padding. - xrgb2101010 is a packed 30 bits per pixel/10 bits per channel packed RGB - format with 2 bits of padding. + choose the bit depth and color type of the DRM mode. + + xrgb8888 is your usual 24bpp packed RGB format with 8 bits of padding. + xrgb2101010 is a 30bpp packed RGB format with 2 bits of padding. + yuyv is a 32bpp packed YUV 4:2:2 format. No planar formats are currently + supported. There are cases when xrgb2101010 will work with the ``drm`` VO, but not with the ``drm`` backend for the ``gpu`` VO. This is because with the ``gpu`` VO, in addition to requiring support in your DRM driver, - requires support for xrgb2101010 in your EGL driver + requires support for xrgb2101010 in your EGL driver. + yuyv only ever works with the ``drm`` VO. ``--drm-draw-surface-size=<[WxH]>`` Sets the size of the surface used on the draw plane. The surface will diff --git a/video/out/drm_common.c b/video/out/drm_common.c index 1669e249eb..cc1df9442b 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -95,7 +95,8 @@ const struct m_sub_options drm_conf = { {"xrgb8888", DRM_OPTS_FORMAT_XRGB8888}, {"xrgb2101010", DRM_OPTS_FORMAT_XRGB2101010}, {"xbgr8888", DRM_OPTS_FORMAT_XBGR8888}, - {"xbgr2101010", DRM_OPTS_FORMAT_XBGR2101010})}, + {"xbgr2101010", DRM_OPTS_FORMAT_XBGR2101010}, + {"yuyv", DRM_OPTS_FORMAT_YUYV})}, {"drm-draw-surface-size", OPT_SIZE_BOX(draw_surface_size)}, {"drm-vrr-enabled", OPT_CHOICE(vrr_enabled, {"no", 0}, {"yes", 1}, {"auto", -1})}, @@ -106,6 +107,7 @@ const struct m_sub_options drm_conf = { .drm_atomic = 1, .draw_plane = DRM_OPTS_PRIMARY_PLANE, .drmprime_video_plane = DRM_OPTS_OVERLAY_PLANE, + .drm_format = DRM_OPTS_FORMAT_XRGB8888, }, .size = sizeof(struct drm_opts), }; diff --git a/video/out/drm_common.h b/video/out/drm_common.h index 581151f94a..9418b3f31e 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -23,10 +23,13 @@ #include #include "vo.h" -#define DRM_OPTS_FORMAT_XRGB8888 0 -#define DRM_OPTS_FORMAT_XRGB2101010 1 -#define DRM_OPTS_FORMAT_XBGR8888 2 -#define DRM_OPTS_FORMAT_XBGR2101010 3 +enum { + DRM_OPTS_FORMAT_XRGB8888, + DRM_OPTS_FORMAT_XRGB2101010, + DRM_OPTS_FORMAT_XBGR8888, + DRM_OPTS_FORMAT_XBGR2101010, + DRM_OPTS_FORMAT_YUYV, +}; struct framebuffer { int fd; diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c index db1981eb7a..7fc75193c7 100644 --- a/video/out/vo_drm.c +++ b/video/out/vo_drm.c @@ -43,6 +43,7 @@ pixfmt2imgfmt(MP_SELECT_LE_BE(AV_PIX_FMT_X2RGB10LE, AV_PIX_FMT_X2RGB10BE)) #define IMGFMT_XBGR2101010 \ pixfmt2imgfmt(MP_SELECT_LE_BE(AV_PIX_FMT_X2BGR10LE, AV_PIX_FMT_X2BGR10BE)) +#define IMGFMT_YUYV pixfmt2imgfmt(AV_PIX_FMT_YUYV422) #define BYTES_PER_PIXEL 4 #define BITS_PER_PIXEL 32 @@ -131,6 +132,10 @@ static struct framebuffer *setup_framebuffer(struct vo *vo) p->drm_format = DRM_FORMAT_XBGR8888; p->imgfmt = IMGFMT_XBGR8888; break; + case DRM_OPTS_FORMAT_YUYV: + p->drm_format = DRM_FORMAT_YUYV; + p->imgfmt = IMGFMT_YUYV; + break; default: if (drm->opts->drm_format != DRM_OPTS_FORMAT_XRGB8888) { MP_VERBOSE(vo, "Requested format not supported by VO, " @@ -187,14 +192,15 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) vo->dheight = drm->fb->height; vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd); - int w = p->dst.x1 - p->dst.x0; - int h = p->dst.y1 - p->dst.y0; + struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(p->imgfmt); + p->dst.x0 = MP_ALIGN_DOWN(p->dst.x0, fmt.align_x); + p->dst.y0 = MP_ALIGN_DOWN(p->dst.y0, fmt.align_y); p->sws->src = *params; p->sws->dst = (struct mp_image_params) { .imgfmt = p->imgfmt, - .w = w, - .h = h, + .w = mp_rect_w(p->dst), + .h = mp_rect_h(p->dst), .p_w = 1, .p_h = 1, }; -- cgit v1.2.3