1From 25eecfea63e8151fb472edcacabe1b979accc45d Mon Sep 17 00:00:00 2001
2From: Jiajian Wu <jair.wu@rock-chips.com>
3Date: Mon, 12 Jun 2023 17:07:55 +0800
4Subject: [PATCH] gst-libs: Support NV16_10LE40
5
6Signed-off-by: Jiajian Wu <jair.wu@rock-chips.com>
7---
8 gst-libs/gst/video/video-converter.c |   3 +
9 gst-libs/gst/video/video-format.c    | 161 +++++++++++++++++++++++++++
10 gst-libs/gst/video/video-format.h    |   6 +-
11 gst-libs/gst/video/video-info.c      |   7 ++
12 tests/check/libs/video.c             |   1 +
13 5 files changed, 176 insertions(+), 2 deletions(-)
14
15diff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c
16index c49d9a0..5a5fc6e 100644
17--- a/gst-libs/gst/video/video-converter.c
18+++ b/gst-libs/gst/video/video-converter.c
19@@ -2781,6 +2781,8 @@ get_rga_format (GstVideoFormat format)
20       return RK_FORMAT_YCbCr_422_P;
21     case GST_VIDEO_FORMAT_NV12_10LE40:
22       return RK_FORMAT_YCbCr_420_SP_10B;
23+    case GST_VIDEO_FORMAT_NV16_10LE40:
24+      return RK_FORMAT_YCbCr_422_SP_10B;
25     default:
26       return RK_FORMAT_UNKNOWN;
27   }
28@@ -7524,6 +7526,7 @@ get_scale_format (GstVideoFormat format, gint plane)
29     case GST_VIDEO_FORMAT_NV12_10LE32:
30     case GST_VIDEO_FORMAT_NV16_10LE32:
31     case GST_VIDEO_FORMAT_NV12_10LE40:
32+    case GST_VIDEO_FORMAT_NV16_10LE40:
33     case GST_VIDEO_FORMAT_BGR10A2_LE:
34     case GST_VIDEO_FORMAT_RGB10A2_LE:
35     case GST_VIDEO_FORMAT_Y444_16BE:
36diff --git a/gst-libs/gst/video/video-format.c b/gst-libs/gst/video/video-format.c
37index d869f9a..fcebf74 100644
38--- a/gst-libs/gst/video/video-format.c
39+++ b/gst-libs/gst/video/video-format.c
40@@ -5663,6 +5663,162 @@ pack_NV12_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
41   }
42 }
43
44+#define PACK_NV16_10LE40 GST_VIDEO_FORMAT_AYUV64, unpack_NV16_10LE40, 1, pack_NV16_10LE40
45+static void
46+unpack_NV16_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
47+    gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
48+    const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
49+{
50+  gint i;
51+  guint16 *restrict d = dest;
52+  const guint8 *restrict sy = GET_PLANE_LINE (0, y);
53+  const guint8 *restrict suv = GET_PLANE_LINE (1, y);
54+  guint16 Y0 = 0, Y1 = 0, Yn = 0, Un = 0, Vn = 0;
55+  guint32 UV = 0;
56+
57+  for (i = 0; i < width; i++) {
58+    gboolean update_c = FALSE;
59+
60+    switch (i & 3) {
61+      case 0:
62+        Y0 = GST_READ_UINT16_LE (sy);
63+        Yn = Y0 & 0x3ff;
64+        sy += 2;
65+
66+        UV = GST_READ_UINT32_LE (suv);
67+        Un = UV & 0x3ff;
68+        Vn = (UV >> 10) & 0x3ff;
69+        suv += 4;
70+
71+        Yn <<= 6;
72+        Un <<= 6;
73+        Vn <<= 6;
74+        update_c = TRUE;
75+        break;
76+      case 1:
77+        Y1 = GST_READ_UINT16_LE (sy);
78+        Yn = (Y0 >> 10) | ((Y1 & 0xf) << 6);
79+        sy += 2;
80+
81+        Yn <<= 6;
82+        break;
83+      case 2:
84+        Yn = (Y1 >> 4) & 0x3ff;
85+
86+        Un = (UV >> 20) & 0x3ff;
87+        Vn = (UV >> 30);
88+        UV = GST_READ_UINT8 (suv);
89+        Vn |= (UV << 2);
90+        suv++;
91+
92+        Yn <<= 6;
93+        Un <<= 6;
94+        Vn <<= 6;
95+        update_c = TRUE;
96+        break;
97+      case 3:
98+        Y0 = GST_READ_UINT8 (sy);
99+        Yn = (Y1 >> 14) | (Y0 << 2);
100+        sy++;
101+
102+        Yn <<= 6;
103+        break;
104+    }
105+
106+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
107+      Yn |= Yn >> 10;
108+      if (update_c) {
109+        Un |= Un >> 10;
110+        Vn |= Vn >> 10;
111+      }
112+    }
113+
114+    d[i * 4 + 0] = 0xffff;
115+    d[i * 4 + 1] = Yn;
116+    d[i * 4 + 2] = Un;
117+    d[i * 4 + 3] = Vn;
118+  }
119+}
120+
121+static void
122+pack_NV16_10LE40 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
123+    const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
124+    const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
125+    gint y, gint width)
126+{
127+  gint i;
128+  guint8 *restrict dy = GET_PLANE_LINE (0, y);
129+  guint8 *restrict duv = GET_PLANE_LINE (1, y);
130+  guint16 Y0 = 0, Y1 = 0, Y2 = 0, Y3 = 0;
131+  guint16 U0 = 0, V0 = 0, U1 = 0, V1 = 0;
132+  const guint16 *restrict s = src;
133+
134+  for (i = 0; i < width; i++) {
135+    switch (i & 3) {
136+      case 0:
137+        Y0 = s[i * 4 + 1] >> 6;
138+        GST_WRITE_UINT8 (dy, Y0 & 0xff);
139+        dy++;
140+
141+        U0 = s[i * 4 + 2] >> 6;
142+        V0 = s[i * 4 + 3] >> 6;
143+
144+        GST_WRITE_UINT8 (duv, U0 & 0xff);
145+        duv++;
146+
147+        GST_WRITE_UINT8 (duv, (U0 >> 8) | ((V0 & 0x3f) << 2));
148+        duv++;
149+
150+        break;
151+      case 1:
152+        Y1 = s[i * 4 + 1] >> 6;
153+        GST_WRITE_UINT8 (dy, (Y0 >> 8) | ((Y1 & 0x3f) << 2));
154+        dy++;
155+        break;
156+      case 2:
157+        Y2 = s[i * 4 + 1] >> 6;
158+        GST_WRITE_UINT8 (dy, (Y1 >> 6) | ((Y2 & 0xf) << 4));
159+        dy++;
160+
161+        U1 = s[i * 4 + 2] >> 6;
162+        V1 = s[i * 4 + 3] >> 6;
163+
164+        GST_WRITE_UINT8 (duv, (V0 >> 6) | ((U1 & 0xf) << 4));
165+        duv++;
166+
167+        GST_WRITE_UINT8 (duv, (U1 >> 4) | ((V1 & 0x3) << 6));
168+        duv++;
169+
170+        GST_WRITE_UINT8 (duv, V1 >> 2);
171+        duv++;
172+        break;
173+      case 3:
174+        Y3 = s[i * 4 + 1] >> 6;
175+        GST_WRITE_UINT8 (dy, (Y2 >> 4) | ((Y3 & 0x3) << 6));
176+        dy++;
177+        GST_WRITE_UINT8 (dy, (Y3 >> 2));
178+        dy++;
179+        break;
180+    }
181+  }
182+
183+  switch (width & 3) {
184+    case 0:
185+      break;
186+    case 1:
187+      GST_WRITE_UINT8 (dy, Y0 >> 8);
188+      GST_WRITE_UINT8 (duv, V0 >> 6);
189+      break;
190+    case 2:
191+      GST_WRITE_UINT8 (dy, Y1 >> 6);
192+      GST_WRITE_UINT8 (duv, V0 >> 6);
193+      break;
194+    case 3:
195+      GST_WRITE_UINT8 (dy, Y2 >> 4);
196+      break;
197+  }
198+}
199+
200 #define PACK_VUYA GST_VIDEO_FORMAT_AYUV, unpack_VUYA, 1, pack_VUYA
201 static void
202 unpack_VUYA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
203@@ -7225,6 +7381,9 @@ static const VideoFormat formats[] = {
204   MAKE_YUV_C_LE_FORMAT (NV12_10LE40, "raw video",
205       GST_MAKE_FOURCC ('R', 'K', '2', '0'), DPTH10_10_10, PSTR0, PLANE011,
206       OFFS0, SUB420, PACK_NV12_10LE40),
207+  MAKE_YUV_C_LE_FORMAT (NV16_10LE40, "raw video",
208+      GST_MAKE_FOURCC ('R', 'K', '6', '0'), DPTH10_10_10, PSTR0, PLANE011,
209+      OFFS0, SUB422, PACK_NV16_10LE40),
210   MAKE_YUV_FORMAT (Y210, "raw video", GST_MAKE_FOURCC ('Y', '2', '1', '0'),
211       DPTH10_10_10, PSTR488, PLANE0, OFFS0, SUB422, PACK_Y210),
212   MAKE_YUV_FORMAT (Y410, "raw video", GST_MAKE_FOURCC ('Y', '4', '1', '0'),
213@@ -7547,6 +7706,8 @@ gst_video_format_from_fourcc (guint32 fourcc)
214       return GST_VIDEO_FORMAT_NV16_10LE32;
215     case GST_MAKE_FOURCC ('R', 'K', '2', '0'):
216       return GST_VIDEO_FORMAT_NV12_10LE40;
217+    case GST_MAKE_FOURCC ('R', 'K', '6', '0'):
218+      return GST_VIDEO_FORMAT_NV16_10LE40;
219     case GST_MAKE_FOURCC ('Y', '4', '1', '0'):
220       return GST_VIDEO_FORMAT_Y410;
221     case GST_MAKE_FOURCC ('V', 'U', 'Y', 'A'):
222diff --git a/gst-libs/gst/video/video-format.h b/gst-libs/gst/video/video-format.h
223index 7a645cc..fb35ed6 100644
224--- a/gst-libs/gst/video/video-format.h
225+++ b/gst-libs/gst/video/video-format.h
226@@ -145,6 +145,7 @@ G_BEGIN_DECLS
227  * @GST_VIDEO_FORMAT_NV12_16L32S: NV12 with 16x32 Y tiles and 16x16 UV tiles. (Since: 1.22)
228  * @GST_VIDEO_FORMAT_NV12_8L128 : NV12 with 8x128 tiles in linear order (Since: 1.22)
229  * @GST_VIDEO_FORMAT_NV12_10BE_8L128 : NV12 10bit big endian with 8x128 tiles in linear order (Since: 1.22)
230+ * @GST_VIDEO_FORMAT_NV16_10LE40: Fully packed variant of NV16_10LE32 (Since: 1.22)
231  *
232  * Enum value describing the most common video formats.
233  *
234@@ -234,6 +235,7 @@ typedef enum {
235   GST_VIDEO_FORMAT_NV12_10LE32,
236   GST_VIDEO_FORMAT_NV16_10LE32,
237   GST_VIDEO_FORMAT_NV12_10LE40,
238+  GST_VIDEO_FORMAT_NV16_10LE40,
239   GST_VIDEO_FORMAT_Y210,
240   GST_VIDEO_FORMAT_Y410,
241   GST_VIDEO_FORMAT_VUYA,
242@@ -874,7 +876,7 @@ gconstpointer  gst_video_format_get_palette          (GstVideoFormat format, gsi
243     "GBR_12BE, Y444_12LE, GBR_12LE, I422_12BE, I422_12LE, Y212_BE, Y212_LE, I420_12BE, " \
244     "I420_12LE, P012_BE, P012_LE, Y444_10BE, GBR_10BE, Y444_10LE, GBR_10LE, r210, " \
245     "I422_10BE, I422_10LE, NV16_10LE32, Y210, v210, UYVP, I420_10BE, I420_10LE, " \
246-    "P010_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \
247+    "P010_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, NV16_10LE40, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \
248     "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \
249     "YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, " \
250     "BGR16, RGB15, BGR15, RGB8P, GRAY16_BE, GRAY16_LE, GRAY10_LE32, GRAY8 }"
251@@ -887,7 +889,7 @@ gconstpointer  gst_video_format_get_palette          (GstVideoFormat format, gsi
252     "GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, " \
253     "I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, " \
254     "I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, " \
255-    "P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \
256+    "P010_10LE, NV12_10LE32, NV12_10LE40, NV16_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \
257     "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \
258     "YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, " \
259     "BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }"
260diff --git a/gst-libs/gst/video/video-info.c b/gst-libs/gst/video/video-info.c
261index d543e31..6eabc07 100644
262--- a/gst-libs/gst/video/video-info.c
263+++ b/gst-libs/gst/video/video-info.c
264@@ -1219,6 +1219,13 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
265         cr_h = GST_ROUND_UP_2 (cr_h);
266       info->size = info->offset[1] + info->stride[0] * cr_h;
267       break;
268+    case GST_VIDEO_FORMAT_NV16_10LE40:
269+      info->stride[0] = ((width * 5 >> 2) + 4) / 5 * 5;
270+      info->stride[1] = info->stride[0];
271+      info->offset[0] = 0;
272+      info->offset[1] = info->stride[0] * height;
273+      info->size = info->offset[1] + info->stride[0] * height;
274+      break;
275     case GST_VIDEO_FORMAT_NV12_8L128:
276     {
277       gint tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0);
278diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c
279index 875f322..90c159a 100644
280--- a/tests/check/libs/video.c
281+++ b/tests/check/libs/video.c
282@@ -3212,6 +3212,7 @@ GST_START_TEST (test_video_formats_pstrides)
283         || fmt == GST_VIDEO_FORMAT_NV12_10LE32
284         || fmt == GST_VIDEO_FORMAT_NV16_10LE32
285         || fmt == GST_VIDEO_FORMAT_NV12_10LE40
286+        || fmt == GST_VIDEO_FORMAT_NV16_10LE40
287         || fmt == GST_VIDEO_FORMAT_Y410
288         || fmt == GST_VIDEO_FORMAT_NV12_8L128
289         || fmt == GST_VIDEO_FORMAT_NV12_10BE_8L128) {
290--
2912.25.1
292
293