From b276d982a27c421495582b120b0215ad578b7367 Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
Date: Mon, 4 Nov 2019 11:11:59 +0800
|
Subject: [PATCH 2/6] Support PIXMAN_nv12 format
|
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
pixman/pixman-access.c | 86 ++++++++++++++++++++++++++++++++++++++++++
|
pixman/pixman.c | 3 +-
|
pixman/pixman.h | 6 ++-
|
3 files changed, 93 insertions(+), 2 deletions(-)
|
|
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
|
index 7c5ce78..1e5c0ba 100644
|
--- a/pixman/pixman-access.c
|
+++ b/pixman/pixman-access.c
|
@@ -192,6 +192,25 @@
|
((uint8_t *) ((bits) + offset0 + \
|
((stride) >> 1) * ((line) >> 1)))
|
|
+/*
|
+ * NV12 setup and access macros
|
+ */
|
+
|
+#define NV12_SETUP(image) \
|
+ bits_image_t *__bits_image = (bits_image_t *)image; \
|
+ uint32_t *bits = __bits_image->bits; \
|
+ int stride = __bits_image->rowstride; \
|
+ int offset0 = stride < 0 ? \
|
+ (-stride) * ((__bits_image->height - 1) >> 1) - stride : \
|
+ stride * __bits_image->height
|
+
|
+#define NV12_Y(line) \
|
+ ((uint8_t *) ((bits) + (stride) * (line)))
|
+
|
+#define NV12_UV(line) \
|
+ ((uint8_t *) ((bits) + offset0 + \
|
+ (stride) * ((line) >> 1)))
|
+
|
/* Misc. helpers */
|
|
static force_inline void
|
@@ -845,6 +864,42 @@ fetch_scanline_yv12 (bits_image_t *image,
|
}
|
}
|
|
+static void
|
+fetch_scanline_nv12 (bits_image_t *image,
|
+ int x,
|
+ int line,
|
+ int width,
|
+ uint32_t * buffer,
|
+ const uint32_t *mask)
|
+{
|
+ NV12_SETUP (image);
|
+ uint8_t *y_line = NV12_Y (line);
|
+ uint8_t *uv_line = NV12_UV (line);
|
+ int i;
|
+
|
+ for (i = 0; i < width; i++)
|
+ {
|
+ int16_t y, u, v;
|
+ int32_t r, g, b;
|
+
|
+ y = y_line[x + i] - 16;
|
+ u = uv_line[(x + i) & -2] - 128;
|
+ v = uv_line[((x + i) & -2) + 1] - 128;
|
+
|
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
|
+ r = 0x012b27 * y + 0x019a2e * v;
|
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
|
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
|
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
|
+ b = 0x012b27 * y + 0x0206a2 * u;
|
+
|
+ *buffer++ = 0xff000000 |
|
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
|
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
|
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
|
+ }
|
+}
|
+
|
/**************************** Pixel wise fetching *****************************/
|
|
#ifndef PIXMAN_FB_ACCESSORS
|
@@ -1036,6 +1091,32 @@ fetch_pixel_yv12 (bits_image_t *image,
|
(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
|
}
|
|
+static uint32_t
|
+fetch_pixel_nv12 (bits_image_t *image,
|
+ int offset,
|
+ int line)
|
+{
|
+ NV12_SETUP (image);
|
+ int16_t y = NV12_Y (line)[offset] - 16;
|
+ int16_t u = NV12_UV (line)[offset & -2] - 128;
|
+ int16_t v = NV12_UV (line)[(offset & -2) + 1] - 128;
|
+ int32_t r, g, b;
|
+
|
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
|
+ r = 0x012b27 * y + 0x019a2e * v;
|
+
|
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
|
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
|
+
|
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
|
+ b = 0x012b27 * y + 0x0206a2 * u;
|
+
|
+ return 0xff000000 |
|
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
|
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
|
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
|
+}
|
+
|
/*********************************** Store ************************************/
|
|
#ifndef PIXMAN_FB_ACCESSORS
|
@@ -1509,6 +1590,11 @@ static const format_info_t accessors[] =
|
fetch_pixel_yv12, fetch_pixel_generic_float,
|
NULL, NULL },
|
|
+ { PIXMAN_nv12,
|
+ fetch_scanline_nv12, fetch_scanline_generic_float,
|
+ fetch_pixel_nv12, fetch_pixel_generic_float,
|
+ NULL, NULL },
|
+
|
{ PIXMAN_null },
|
};
|
|
diff --git a/pixman/pixman.c b/pixman/pixman.c
|
index c09b528..d8a2d24 100644
|
--- a/pixman/pixman.c
|
+++ b/pixman/pixman.c
|
@@ -1070,6 +1070,7 @@ pixman_format_supported_source (pixman_format_code_t format)
|
/* YUV formats */
|
case PIXMAN_yuy2:
|
case PIXMAN_yv12:
|
+ case PIXMAN_nv12:
|
return TRUE;
|
|
default:
|
@@ -1092,7 +1093,7 @@ PIXMAN_EXPORT pixman_bool_t
|
pixman_format_supported_destination (pixman_format_code_t format)
|
{
|
/* YUV formats cannot be written to at the moment */
|
- if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
|
+ if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 || format == PIXMAN_nv12)
|
return FALSE;
|
|
return pixman_format_supported_source (format);
|
diff --git a/pixman/pixman.h b/pixman/pixman.h
|
index 08303b5..3bb2fa5 100644
|
--- a/pixman/pixman.h
|
+++ b/pixman/pixman.h
|
@@ -861,6 +861,9 @@ struct pixman_indexed
|
#define PIXMAN_TYPE_ARGB_SRGB 10
|
#define PIXMAN_TYPE_RGBA_FLOAT 11
|
|
+/* HACK: Use maximum value to avoid conflict */
|
+#define PIXMAN_TYPE_NV12 0x3f
|
+
|
#define PIXMAN_FORMAT_COLOR(f) \
|
(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \
|
PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \
|
@@ -941,7 +944,8 @@ typedef enum {
|
|
/* YUV formats */
|
PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
|
- PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0)
|
+ PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0),
|
+ PIXMAN_nv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_NV12,0,0,0,0),
|
} pixman_format_code_t;
|
|
/* Querying supported format values. */
|
--
|
2.20.1
|