mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
dmabuf: Add support for 3 plane YUV formats
This commit is contained in:
parent
911198cddd
commit
8f70f4b85e
161
gdk/gdkdmabuf.c
161
gdk/gdkdmabuf.c
@ -186,6 +186,87 @@ download_nv12 (guchar *dst_data,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
download_yuv_3 (guchar *dst_data,
|
||||
gsize dst_stride,
|
||||
GdkMemoryFormat dst_format,
|
||||
gsize width,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
{
|
||||
const guchar *y_data, *u_data, *v_data;
|
||||
gsize x, y, y_stride, u_stride, v_stride;
|
||||
gsize U, V, X_SUB, Y_SUB;
|
||||
|
||||
switch (dmabuf->fourcc)
|
||||
{
|
||||
case DRM_FORMAT_YUV410:
|
||||
U = 1; V = 2; X_SUB = 4; Y_SUB = 4;
|
||||
break;
|
||||
case DRM_FORMAT_YVU410:
|
||||
U = 2; V = 1; X_SUB = 4; Y_SUB = 4;
|
||||
break;
|
||||
case DRM_FORMAT_YUV411:
|
||||
U = 1; V = 2; X_SUB = 4; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YVU411:
|
||||
U = 2; V = 1; X_SUB = 4; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YUV420:
|
||||
U = 1; V = 2; X_SUB = 2; Y_SUB = 2;
|
||||
break;
|
||||
case DRM_FORMAT_YVU420:
|
||||
U = 2; V = 1; X_SUB = 2; Y_SUB = 2;
|
||||
break;
|
||||
case DRM_FORMAT_YUV422:
|
||||
U = 1; V = 2; X_SUB = 2; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YVU422:
|
||||
U = 2; V = 1; X_SUB = 2; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YUV444:
|
||||
U = 1; V = 2; X_SUB = 1; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YVU444:
|
||||
U = 2; V = 1; X_SUB = 1; Y_SUB = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
y_stride = dmabuf->planes[0].stride;
|
||||
y_data = src_data[0] + dmabuf->planes[0].offset;
|
||||
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
|
||||
u_stride = dmabuf->planes[U].stride;
|
||||
u_data = src_data[U] + dmabuf->planes[U].offset;
|
||||
g_return_if_fail (sizes[U] >= dmabuf->planes[U].offset + (height + Y_SUB - 1) / Y_SUB * u_stride);
|
||||
v_stride = dmabuf->planes[V].stride;
|
||||
v_data = src_data[V] + dmabuf->planes[V].offset;
|
||||
g_return_if_fail (sizes[V] >= dmabuf->planes[V].offset + (height + Y_SUB - 1) / Y_SUB * v_stride);
|
||||
|
||||
for (y = 0; y < height; y += Y_SUB)
|
||||
{
|
||||
for (x = 0; x < width; x += X_SUB)
|
||||
{
|
||||
int r, g, b;
|
||||
gsize xs, ys;
|
||||
|
||||
get_uv_values (&itu601_wide, u_data[x / X_SUB], v_data[x / X_SUB], &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 += Y_SUB * dst_stride;
|
||||
y_data += Y_SUB * y_stride;
|
||||
u_data += u_stride;
|
||||
v_data += v_stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
download_yuyv (guchar *dst_data,
|
||||
gsize dst_stride,
|
||||
@ -262,6 +343,16 @@ static const GdkDrmFormatInfo supported_formats[] = {
|
||||
{ DRM_FORMAT_YVYU, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_VYUY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_UYVY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_YUV410, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU410, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV411, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU411, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV420, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU420, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV422, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU422, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV444, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU444, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
};
|
||||
|
||||
static const GdkDrmFormatInfo *
|
||||
@ -546,6 +637,76 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV410:
|
||||
case DRM_FORMAT_YVU410:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 3) / 4;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * ((height + 3) / 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV411:
|
||||
case DRM_FORMAT_YVU411:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 3) / 4;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV420:
|
||||
case DRM_FORMAT_YVU420:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 1) / 2;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * ((height + 1) / 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV422:
|
||||
case DRM_FORMAT_YVU422:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 1) / 2;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV444:
|
||||
case DRM_FORMAT_YVU444:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = dest->planes[0].stride;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user