From 911198cdddb45f2e3f97134b67fca7310cbf8516 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 23 Oct 2023 01:41:25 +0200 Subject: [PATCH] dmabuf: Add NV16, NV61, NV24 and NV42 and sanitize them and NV21. --- gdk/gdkdmabuf.c | 76 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c index b3ef559ea5..afcf6a1df7 100644 --- a/gdk/gdkdmabuf.c +++ b/gdk/gdkdmabuf.c @@ -133,15 +133,31 @@ download_nv12 (guchar *dst_data, { const guchar *y_data, *uv_data; gsize x, y, y_stride, uv_stride; - gsize U, V; + gsize U, V, X_SUB, Y_SUB; - if (dmabuf->fourcc == DRM_FORMAT_NV21) + switch (dmabuf->fourcc) { - U = 1; V = 0; - } - else - { - U = 0; V = 1; + case DRM_FORMAT_NV12: + U = 0; V = 1; X_SUB = 2; Y_SUB = 2; + break; + case DRM_FORMAT_NV21: + U = 1; V = 0; X_SUB = 2; Y_SUB = 2; + break; + case DRM_FORMAT_NV16: + U = 0; V = 1; X_SUB = 2; Y_SUB = 1; + break; + case DRM_FORMAT_NV61: + U = 1; V = 0; X_SUB = 2; Y_SUB = 1; + break; + case DRM_FORMAT_NV24: + U = 0; V = 1; X_SUB = 1; Y_SUB = 1; + break; + case DRM_FORMAT_NV42: + U = 1; V = 0; X_SUB = 1; Y_SUB = 1; + break; + default: + g_assert_not_reached (); + return; } y_stride = dmabuf->planes[0].stride; @@ -149,31 +165,23 @@ download_nv12 (guchar *dst_data, g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride); uv_stride = dmabuf->planes[1].stride; uv_data = src_data[1] + dmabuf->planes[1].offset; - g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + 1) / 2 * uv_stride); + g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + Y_SUB - 1) / Y_SUB * uv_stride); - for (y = 0; y < height; y += 2) + for (y = 0; y < height; y += Y_SUB) { - guchar *dst2_data = dst_data + dst_stride; - const guchar *y2_data = y_data + y_stride; - - for (x = 0; x < width; x += 2) + for (x = 0; x < width; x += X_SUB) { int r, g, b; + gsize xs, ys; - get_uv_values (&itu601_wide, uv_data[x + U], uv_data[x + V], &r, &g, &b); + get_uv_values (&itu601_wide, uv_data[x / X_SUB * 2 + U], uv_data[x / X_SUB * 2 + V], &r, &g, &b); - set_rgb_values (&dst_data[3 * x], y_data[x], r, g, b); - if (x + 1 < width) - set_rgb_values (&dst_data[3 * (x + 1)], y_data[x], r, g, b); - if (y + 1 < height) - { - set_rgb_values (&dst2_data[3 * x], y2_data[x], r, g, b); - if (x + 1 < width) - set_rgb_values (&dst2_data[3 * (x + 1)], y2_data[x], r, g, b); - } + for (ys = 0; ys < Y_SUB && y + ys < height; ys++) + for (xs = 0; xs < X_SUB && x + xs < width; xs++) + set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b); } - dst_data += 2 * dst_stride; - y_data += 2 * y_stride; + dst_data += Y_SUB * dst_stride; + y_data += Y_SUB * y_stride; uv_data += uv_stride; } } @@ -246,6 +254,10 @@ static const GdkDrmFormatInfo supported_formats[] = { /* YUV formats */ { DRM_FORMAT_NV12, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, { DRM_FORMAT_NV21, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, + { DRM_FORMAT_NV16, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, + { DRM_FORMAT_NV61, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, + { DRM_FORMAT_NV24, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, + { DRM_FORMAT_NV42, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, { DRM_FORMAT_YUYV, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv }, { DRM_FORMAT_YVYU, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv }, { DRM_FORMAT_VYUY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv }, @@ -511,6 +523,9 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest, switch (dest->fourcc) { case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: if (dest->n_planes == 1) { dest->n_planes = 2; @@ -520,6 +535,17 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest, } break; + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV42: + if (dest->n_planes == 1) + { + dest->n_planes = 2; + dest->planes[1].fd = dest->planes[0].fd; + dest->planes[1].stride = dest->planes[0].stride * 2; + dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height; + } + break; + default: break; }