hc
2023-02-18 a08c8b75ee83d7f62c9aefc23bfb42082aa4076c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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