Complete Yocto mirror with license table for TQMa6UL (2038-compliance)

- 264 license table entries with exact download URLs (224/264 resolved)
- Complete sources/ directory with all BitBake recipes
- Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl)
- Full traceability for Softwarefreigabeantrag
- GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4
- License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
Siggi (OpenClaw Agent)
2026-03-01 20:58:18 +00:00
commit 16accb6b24
15086 changed files with 1292356 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
From 5ab1ba5414cdc01e62910cd5f235fc9bb045578e Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sun, 21 May 2023 00:02:55 +0200
Subject: [PATCH 1/9] rgb2bayer: Support video/x-bayer 10/12/14/16 bit depths
Add support for conversion to 10/12/14/16 bit bayer pattern.
The implementation is rather simplistic, just take the ARGB
input, generate 16-bit data out of it instead of 8-bit, shift
them as required by the output bitness, and apply endian swap.
Example usage:
```
$ gst-launch-1.0 videotestsrc num-buffers=1 ! \
video/x-raw,width=512,height=512,format=ARGB ! \
rgb2bayer ! \
video/x-bayer,format=bggr12le ! \
filesink location=/tmp/bayer12.raw
```
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/0763fb107d4f5e05991283d8a7861511820596ac]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
docs/plugins/gst_plugins_cache.json | 2 +-
gst/bayer/gstrgb2bayer.c | 116 +++++++++++++++++++++++-----
gst/bayer/gstrgb2bayer.h | 2 +
3 files changed, 101 insertions(+), 19 deletions(-)
diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json
index 7ede158aff..7b09ab6b9c 100644
--- a/docs/plugins/gst_plugins_cache.json
+++ b/docs/plugins/gst_plugins_cache.json
@@ -3975,7 +3975,7 @@
"presence": "always"
},
"src": {
- "caps": "video/x-bayer:\n format: { bggr, gbrg, grbg, rggb }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
+ "caps": "video/x-bayer:\n format: { bggr, rggb, grbg, gbrg, bggr10le, rggb10le, grbg10le, gbrg10le, bggr10be, rggb10be, grbg10be, gbrg10be, bggr12le, rggb12le, grbg12le, gbrg12le, bggr12be, rggb12be, grbg12be, gbrg12be, bggr14le, rggb14le, grbg14le, gbrg14le, bggr14be, rggb14be, grbg14be, gbrg14be, bggr16le, rggb16le, grbg16le, gbrg16le, bggr16be, rggb16be, grbg16be, gbrg16be }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
"direction": "src",
"presence": "always"
}
diff --git a/gst/bayer/gstrgb2bayer.c b/gst/bayer/gstrgb2bayer.c
index 8adeb779a9..4e3c2ad8e3 100644
--- a/gst/bayer/gstrgb2bayer.c
+++ b/gst/bayer/gstrgb2bayer.c
@@ -28,6 +28,8 @@
#include "gstbayerelements.h"
#include "gstrgb2bayer.h"
+#define DIV_ROUND_UP(s,v) (((s) + ((v)-1)) / (v))
+
#define GST_CAT_DEFAULT gst_rgb2bayer_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@@ -64,12 +66,32 @@ static GstStaticPadTemplate gst_rgb2bayer_sink_template =
);
#endif
+#define BAYER_CAPS_GEN(mask, bits, endian) \
+ " "#mask#bits#endian
+
+#define BAYER_CAPS_ORD(bits, endian) \
+ BAYER_CAPS_GEN(bggr, bits, endian)"," \
+ BAYER_CAPS_GEN(rggb, bits, endian)"," \
+ BAYER_CAPS_GEN(grbg, bits, endian)"," \
+ BAYER_CAPS_GEN(gbrg, bits, endian)
+
+#define BAYER_CAPS_BITS(bits) \
+ BAYER_CAPS_ORD(bits, le)"," \
+ BAYER_CAPS_ORD(bits, be)
+
+#define BAYER_CAPS_ALL \
+ BAYER_CAPS_ORD(,)"," \
+ BAYER_CAPS_BITS(10)"," \
+ BAYER_CAPS_BITS(12)"," \
+ BAYER_CAPS_BITS(14)"," \
+ BAYER_CAPS_BITS(16)
+
static GstStaticPadTemplate gst_rgb2bayer_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-bayer,"
- "format=(string){bggr,gbrg,grbg,rggb},"
+ "format=(string){" BAYER_CAPS_ALL " },"
"width=[1,MAX],height=[1,MAX]," "framerate=(fraction)[0/1,MAX]")
);
@@ -164,6 +186,7 @@ static gboolean
gst_rgb2bayer_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
gsize * size)
{
+ GstRGB2Bayer *rgb2bayer = GST_RGB_2_BAYER (trans);
GstStructure *structure;
int width;
int height;
@@ -176,7 +199,8 @@ gst_rgb2bayer_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
name = gst_structure_get_name (structure);
/* Our name must be either video/x-bayer video/x-raw */
if (g_str_equal (name, "video/x-bayer")) {
- *size = GST_ROUND_UP_4 (width) * height;
+ *size =
+ GST_ROUND_UP_4 (width) * height * DIV_ROUND_UP (rgb2bayer->bpp, 8);
return TRUE;
} else {
/* For output, calculate according to format */
@@ -212,21 +236,53 @@ gst_rgb2bayer_set_caps (GstBaseTransform * trans, GstCaps * incaps,
gst_structure_get_int (structure, "height", &rgb2bayer->height);
format = gst_structure_get_string (structure, "format");
- if (g_str_equal (format, "bggr")) {
+ if (g_str_has_prefix (format, "bggr")) {
rgb2bayer->format = GST_RGB_2_BAYER_FORMAT_BGGR;
- } else if (g_str_equal (format, "gbrg")) {
+ } else if (g_str_has_prefix (format, "gbrg")) {
rgb2bayer->format = GST_RGB_2_BAYER_FORMAT_GBRG;
- } else if (g_str_equal (format, "grbg")) {
+ } else if (g_str_has_prefix (format, "grbg")) {
rgb2bayer->format = GST_RGB_2_BAYER_FORMAT_GRBG;
- } else if (g_str_equal (format, "rggb")) {
+ } else if (g_str_has_prefix (format, "rggb")) {
rgb2bayer->format = GST_RGB_2_BAYER_FORMAT_RGGB;
} else {
return FALSE;
}
+ if (strlen (format) == 4) { /* 8bit bayer */
+ rgb2bayer->bpp = 8;
+ } else if (strlen (format) == 8) { /* 10/12/14/16 le/be bayer */
+ rgb2bayer->bpp = (gint) g_ascii_strtoull (format + 4, NULL, 10);
+ if (rgb2bayer->bpp & 1) /* odd rgb2bayer->bpp bayer formats not supported */
+ return FALSE;
+ if (rgb2bayer->bpp < 10 || rgb2bayer->bpp > 16) /* bayer 10,12,14,16 only */
+ return FALSE;
+
+ if (g_str_has_suffix (format, "le"))
+ rgb2bayer->bigendian = 0;
+ else if (g_str_has_suffix (format, "be"))
+ rgb2bayer->bigendian = 1;
+ else
+ return FALSE;
+ } else
+ return FALSE;
+
return TRUE;
}
+static guint16
+bayer_scale_and_swap (GstRGB2Bayer * rgb2bayer, guint8 r8)
+{
+ guint16 r16 = (r8 << (rgb2bayer->bpp - 8)) | (r8 >> (16 - rgb2bayer->bpp));
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ if (rgb2bayer->bigendian)
+ r16 = GUINT16_SWAP_LE_BE (r16);
+#else
+ if (!rgb2bayer->bigendian)
+ r16 = GUINT16_SWAP_LE_BE (r16);
+#endif
+ return r16;
+}
+
static GstFlowReturn
gst_rgb2bayer_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
@@ -239,6 +295,7 @@ gst_rgb2bayer_transform (GstBaseTransform * trans, GstBuffer * inbuf,
int height = rgb2bayer->height;
int width = rgb2bayer->width;
GstVideoFrame frame;
+ int bayer16 = (rgb2bayer->bpp > 8);
if (!gst_video_frame_map (&frame, &rgb2bayer->info, inbuf, GST_MAP_READ))
goto map_failed;
@@ -251,18 +308,41 @@ gst_rgb2bayer_transform (GstBaseTransform * trans, GstBuffer * inbuf,
dest = map.data;
src = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
- for (j = 0; j < height; j++) {
- guint8 *dest_line = dest + GST_ROUND_UP_4 (width) * j;
- guint8 *src_line = src + frame.info.stride[0] * j;
-
- for (i = 0; i < width; i++) {
- int is_blue = ((j & 1) << 1) | (i & 1);
- if (is_blue == rgb2bayer->format) {
- dest_line[i] = src_line[i * 4 + 3];
- } else if ((is_blue ^ 3) == rgb2bayer->format) {
- dest_line[i] = src_line[i * 4 + 1];
- } else {
- dest_line[i] = src_line[i * 4 + 2];
+ if (bayer16) {
+ for (j = 0; j < height; j++) {
+ guint16 *dest_line16 = (guint16 *)
+ (dest + GST_ROUND_UP_4 (width) * j * DIV_ROUND_UP (rgb2bayer->bpp,
+ 8));
+ guint8 *src_line = src + frame.info.stride[0] * j;
+
+ for (i = 0; i < width; i++) {
+ int is_blue = ((j & 1) << 1) | (i & 1);
+ if (is_blue == rgb2bayer->format) {
+ dest_line16[i] =
+ bayer_scale_and_swap (rgb2bayer, src_line[i * 4 + 3]);
+ } else if ((is_blue ^ 3) == rgb2bayer->format) {
+ dest_line16[i] =
+ bayer_scale_and_swap (rgb2bayer, src_line[i * 4 + 1]);
+ } else {
+ dest_line16[i] =
+ bayer_scale_and_swap (rgb2bayer, src_line[i * 4 + 2]);
+ }
+ }
+ }
+ } else {
+ for (j = 0; j < height; j++) {
+ guint8 *dest_line = dest + GST_ROUND_UP_4 (width) * j;
+ guint8 *src_line = src + frame.info.stride[0] * j;
+
+ for (i = 0; i < width; i++) {
+ int is_blue = ((j & 1) << 1) | (i & 1);
+ if (is_blue == rgb2bayer->format) {
+ dest_line[i] = src_line[i * 4 + 3];
+ } else if ((is_blue ^ 3) == rgb2bayer->format) {
+ dest_line[i] = src_line[i * 4 + 1];
+ } else {
+ dest_line[i] = src_line[i * 4 + 2];
+ }
}
}
}
diff --git a/gst/bayer/gstrgb2bayer.h b/gst/bayer/gstrgb2bayer.h
index b6e79fd4e2..b2eade10f2 100644
--- a/gst/bayer/gstrgb2bayer.h
+++ b/gst/bayer/gstrgb2bayer.h
@@ -49,6 +49,8 @@ struct _GstRGB2Bayer
GstVideoInfo info;
int width, height;
int format;
+ int bpp;
+ int bigendian;
};
struct _GstRGB2BayerClass
--
2.44.1

View File

@@ -0,0 +1,32 @@
From 806796f2b65e16ea31728d591372321474854d6b Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Wed, 7 Jun 2023 23:33:05 +0200
Subject: [PATCH 2/9] bayer2rgb: Disable in-place transform
The bayer2rgb process implemented doesn't support in-place tranform.
This element doesn't implement a "transform_ip" vmethod of
GstBaseTransform it will revert to using the "tranform" vmethod.
It's misleading to set it to TRUE, here. Change this to FALSE.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/484e31c1d9f4de1ecb8432b5c3360407efe30736]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index 109bab2467..c1892a2ee1 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -206,7 +206,7 @@ static void
gst_bayer2rgb_init (GstBayer2RGB * filter)
{
gst_bayer2rgb_reset (filter);
- gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
+ gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), FALSE);
}
/* No properties are implemented, so only a warning is produced */
--
2.44.1

View File

@@ -0,0 +1,35 @@
From f90db8f634f8542034748e36aed25b1b28bcbd08 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sat, 20 May 2023 16:01:13 +0200
Subject: [PATCH 3/9] bayer2rgb: Inline the j=0 value
The j variable is used as an iterator further down in this code, but
here it can be just inlined in the macro parameters to make the code
easier to read. This is done in preparation for further changes. No
functional change.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/ddcb45ffc0193e782886cdf31a775da7e42b3c10]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index c1892a2ee1..07d3d2b3ff 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -431,9 +431,8 @@ gst_bayer2rgb_process (GstBayer2RGB * bayer2rgb, uint8_t * dest,
gst_bayer2rgb_split_and_upsample_horiz (LINE (3 * 2 + 0), LINE (3 * 2 + 1),
src + 1 * src_stride, bayer2rgb->width);
- j = 0;
- gst_bayer2rgb_split_and_upsample_horiz (LINE (j * 2 + 0), LINE (j * 2 + 1),
- src + j * src_stride, bayer2rgb->width);
+ gst_bayer2rgb_split_and_upsample_horiz (LINE (0 * 2 + 0), LINE (0 * 2 + 1),
+ src + 0 * src_stride, bayer2rgb->width);
for (j = 0; j < bayer2rgb->height; j++) {
if (j < bayer2rgb->height - 1) {
--
2.44.1

View File

@@ -0,0 +1,43 @@
From d349f60d45379e92106fb9051e9d50161ab2e18f Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sat, 20 May 2023 21:43:13 +0200
Subject: [PATCH 4/9] bayer2rgb: Fold src_stride into gst_bayer2rgb_process()
The source stride parameter can be easily obtained from GstBayer2RGB
structure, do it within gst_bayer2rgb_process() and drop the parameter.
No functional change.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/8bec6828f4c08fe3bff672f12e9fa0b47d345931]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index 07d3d2b3ff..6f1540d0f6 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -386,8 +386,9 @@ typedef void (*process_func) (guint8 * d0, const guint8 * s0, const guint8 * s1,
static void
gst_bayer2rgb_process (GstBayer2RGB * bayer2rgb, uint8_t * dest,
- int dest_stride, uint8_t * src, int src_stride)
+ int dest_stride, uint8_t * src)
{
+ const int src_stride = GST_ROUND_UP_4 (bayer2rgb->width);
int j;
guint8 *tmp;
process_func merge[2] = { NULL, NULL };
@@ -472,8 +473,7 @@ gst_bayer2rgb_transform (GstBaseTransform * base, GstBuffer * inbuf,
}
output = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
- gst_bayer2rgb_process (filter, output, frame.info.stride[0],
- map.data, GST_ROUND_UP_4 (filter->width));
+ gst_bayer2rgb_process (filter, output, frame.info.stride[0], map.data);
gst_video_frame_unmap (&frame);
gst_buffer_unmap (inbuf, &map);
--
2.44.1

View File

@@ -0,0 +1,67 @@
From 9e37b8439bc3d24b44bd6447cc970d0feb906f5b Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sat, 20 May 2023 16:03:10 +0200
Subject: [PATCH 5/9] bayer2rgb: Pass all parameters to LINE() macro
Pass all three parameters used by the LINE() macro to the LINE() macro
and unroll the code for readability. Add more comments regarding which
of these LINE()s point to which data in the temporary buffer to make
the code less confusing.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/fbd02b3e2a6feda532a75b5372d0a47e411c62e0]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index 6f1540d0f6..8d5dc9b282 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -428,23 +428,34 @@ gst_bayer2rgb_process (GstBayer2RGB * bayer2rgb, uint8_t * dest,
}
tmp = g_malloc (2 * 4 * bayer2rgb->width);
-#define LINE(x) (tmp + ((x)&7) * bayer2rgb->width)
+#define LINE(t, x, b) ((t) + (((x) & 7) * ((b)->width)))
- gst_bayer2rgb_split_and_upsample_horiz (LINE (3 * 2 + 0), LINE (3 * 2 + 1),
+ gst_bayer2rgb_split_and_upsample_horiz ( /* src line 1 */
+ LINE (tmp, 3 * 2 + 0, bayer2rgb), /* tmp buffer line 6 */
+ LINE (tmp, 3 * 2 + 1, bayer2rgb), /* tmp buffer line 7 */
src + 1 * src_stride, bayer2rgb->width);
- gst_bayer2rgb_split_and_upsample_horiz (LINE (0 * 2 + 0), LINE (0 * 2 + 1),
+
+ gst_bayer2rgb_split_and_upsample_horiz ( /* src line 0 */
+ LINE (tmp, 0 * 2 + 0, bayer2rgb), /* tmp buffer line 0 */
+ LINE (tmp, 0 * 2 + 1, bayer2rgb), /* tmp buffer line 1 */
src + 0 * src_stride, bayer2rgb->width);
for (j = 0; j < bayer2rgb->height; j++) {
if (j < bayer2rgb->height - 1) {
- gst_bayer2rgb_split_and_upsample_horiz (LINE ((j + 1) * 2 + 0),
- LINE ((j + 1) * 2 + 1), src + (j + 1) * src_stride, bayer2rgb->width);
+ gst_bayer2rgb_split_and_upsample_horiz ( /* src line (j + 1) */
+ LINE (tmp, (j + 1) * 2 + 0, bayer2rgb), /* tmp buffer line 2/4/6/0 */
+ LINE (tmp, (j + 1) * 2 + 1, bayer2rgb), /* tmp buffer line 3/5/7/1 */
+ src + (j + 1) * src_stride, bayer2rgb->width);
}
- merge[j & 1] (dest + j * dest_stride,
- LINE (j * 2 - 2), LINE (j * 2 - 1),
- LINE (j * 2 + 0), LINE (j * 2 + 1),
- LINE (j * 2 + 2), LINE (j * 2 + 3), bayer2rgb->width >> 1);
+ merge[j & 1] (dest + j * dest_stride, /* output line j */
+ LINE (tmp, j * 2 - 2, bayer2rgb), /* PREVIOUS: even: BG g0 , odd: GR b0 */
+ LINE (tmp, j * 2 - 1, bayer2rgb), /* PREVIOUS: even: BG r0 , odd: GR g0 */
+ LINE (tmp, j * 2 + 0, bayer2rgb), /* CURRENT: even: BG b1 , odd: GR g1 */
+ LINE (tmp, j * 2 + 1, bayer2rgb), /* CURRENT: even: BG g1 , odd: GR r1 */
+ LINE (tmp, j * 2 + 2, bayer2rgb), /* NEXT: even: BG g2 , odd: GR b2 */
+ LINE (tmp, j * 2 + 3, bayer2rgb), /* NEXT: even: BG r2 , odd: GR g2 */
+ bayer2rgb->width >> 1);
}
g_free (tmp);
--
2.44.1

View File

@@ -0,0 +1,58 @@
From 1e6f43e570b050db7b29cd8f21181375273f21a6 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sat, 20 May 2023 23:34:15 +0200
Subject: [PATCH 6/9] bayer2rgb: Pass filter pointer into
gst_bayer2rgb_split_and_upsample_horiz()
Instead of passing a single element of GstBayer2RGB structure into the
gst_bayer2rgb_split_and_upsample_horiz(), pass the entire pointer and
let the funciton pick out whatever it needs out of the structure. This
is a preparatory patch. No functional change.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/4efe11a705362e856c1d7b58e8573c12e50842cb]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index 8d5dc9b282..f5ef97c0b4 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -353,8 +353,9 @@ gst_bayer2rgb_get_unit_size (GstBaseTransform * base, GstCaps * caps,
static void
gst_bayer2rgb_split_and_upsample_horiz (guint8 * dest0, guint8 * dest1,
- const guint8 * src, int n)
+ const guint8 * src, GstBayer2RGB * bayer2rgb)
{
+ int n = bayer2rgb->width;
int i;
dest0[0] = src[0];
@@ -433,19 +434,19 @@ gst_bayer2rgb_process (GstBayer2RGB * bayer2rgb, uint8_t * dest,
gst_bayer2rgb_split_and_upsample_horiz ( /* src line 1 */
LINE (tmp, 3 * 2 + 0, bayer2rgb), /* tmp buffer line 6 */
LINE (tmp, 3 * 2 + 1, bayer2rgb), /* tmp buffer line 7 */
- src + 1 * src_stride, bayer2rgb->width);
+ src + 1 * src_stride, bayer2rgb);
gst_bayer2rgb_split_and_upsample_horiz ( /* src line 0 */
LINE (tmp, 0 * 2 + 0, bayer2rgb), /* tmp buffer line 0 */
LINE (tmp, 0 * 2 + 1, bayer2rgb), /* tmp buffer line 1 */
- src + 0 * src_stride, bayer2rgb->width);
+ src + 0 * src_stride, bayer2rgb);
for (j = 0; j < bayer2rgb->height; j++) {
if (j < bayer2rgb->height - 1) {
gst_bayer2rgb_split_and_upsample_horiz ( /* src line (j + 1) */
LINE (tmp, (j + 1) * 2 + 0, bayer2rgb), /* tmp buffer line 2/4/6/0 */
LINE (tmp, (j + 1) * 2 + 1, bayer2rgb), /* tmp buffer line 3/5/7/1 */
- src + (j + 1) * src_stride, bayer2rgb->width);
+ src + (j + 1) * src_stride, bayer2rgb);
}
merge[j & 1] (dest + j * dest_stride, /* output line j */
--
2.44.1

View File

@@ -0,0 +1,80 @@
From 58a72a1656173a35af2d91d6bb63985477fe36cd Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sat, 20 May 2023 16:55:48 +0200
Subject: [PATCH 7/9] bayer2rgb: Add comment on bayer_orc_horiz_upsample
Explain how the bayer_orc_horiz_upsample function works and
what it does with the pixels, as this may not be obvious.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/920851945f77cd55cea2bafd175368abaf9f0ac5]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 52 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index f5ef97c0b4..a64540fb49 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -358,6 +358,58 @@ gst_bayer2rgb_split_and_upsample_horiz (guint8 * dest0, guint8 * dest1,
int n = bayer2rgb->width;
int i;
+ /*
+ * Pre-process line of source data in 'src' into two neighboring
+ * lines of temporary data 'dest0' and 'dest1' as follows. Note
+ * that first two pixels of both 'dest0' and 'dest1' are special,
+ * and so are the last two pixels of both 'dest0' and 'dest1' .
+ *
+ * The gist of this transformation is this:
+ * - Assume the source data contain this BG bayer pattern on input
+ * data line 0 (this is the same as src[0, 1, 2, 3, 4, 5 ...]):
+ * src 0 : B0 G0 B1 G1 B2 G2
+ * - This gets transformed into two lines:
+ * line 0: B0 avg(B0, B1) B1 avg(B1, B2) B2 avg(B2, B3)...
+ * line 1: G0 G0 avg(G0, G1) G1 avg(G1, G2) G2...
+ * - Notice ^^ ^^ ^^^^^^^^^^^ ^^ ^^^^^^^^^^^
+ * These are interpolated BG pairs, one for each input bayer pixel.
+ *
+ * The immediatelly following call to this function operates on the next
+ * input data line 1 as follows:
+ * - Assume the source data contain this GR bayer pattern on line 1:
+ * src 0 : G0 R0 G1 R1 G2 R2
+ * - This gets transformed into two lines:
+ * line 2: G0 avg(G0, G1) G1 avg(G1, G2) G2 avg(G2, G3)...
+ * line 3: R0 R0 avg(R0, R1) R1 avg(R1, R2) R2...
+ * - Notice ^^ ^^ ^^^^^^^^^^^ ^^ ^^^^^^^^^^^
+ * These are interpolated GR pairs, one for each input bayer pixel.
+ *
+ * First two pixels are special, two more pixels as an example of the rest:
+ * || 0 | 1 || 2 | 3 ::
+ * ------||--------+----------------++----------------+----------------+:
+ * DEST0 || src[0] | avg(src[0, 2]) || src[2] | avg(src[2, 4]) ::
+ * ------||--------+----------------++----------------+----------------+:
+ * DEST1 || src[1] | src[1] || avg(src[1, 3]) | src[3] ::
+ * ------||--------+----------------++----------------+----------------+:
+ *
+ * Inner block of pixels:
+ * : | n | n+1 :
+ * :-------+--------------------+------------------:
+ * : DEST0 | src[n] | avg(src[n, n+2]) :
+ * :-------+--------------------+------------------:
+ * : DEST1 | avg(src[n-1, n+1]) | src[n+1] :
+ * :-------+--------------------+------------------:
+ *
+ * Last two pixels:
+ * w is EVEN w is ODD
+ * : | w-2 | w-1 || : | w-2 | w-1 ||
+ * :-------+----------+----------|| :-------+----------+----------||
+ * : DEST0 | src[w-2] | src[w-2] || : DEST0 | src[w-3] | src[w-1] ||
+ * :-------+----------+----------|| :-------+----------+----------||
+ * : DEST1 | src[w-3] | src[w-1] || : DEST1 | src[w-2] | src[w-2] ||
+ * :-------+----------+----------|| :-------+----------+----------||
+ */
+
dest0[0] = src[0];
dest1[0] = src[1];
dest0[1] = (src[0] + src[2] + 1) >> 1;
--
2.44.1

View File

@@ -0,0 +1,119 @@
From 5a88810a6f551b4de02e7cb53da1c8466b382a28 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Sat, 20 May 2023 23:33:14 +0200
Subject: [PATCH 8/9] bayer2rgb: Add comments explaining
gst_bayer2rgb_process()
Add comments regarding which LINE()s point to which data in the
temporary buffer and a large comment explaining how the buffer
is processed. This will hopefully be useful to someone, as the
code is not obvious. No functional change.
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/9d1a750117fed527eed63e2049f333757074dfc8]
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4686>
---
gst/bayer/gstbayer2rgb.c | 70 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c
index a64540fb49..3dfae46ddd 100644
--- a/gst/bayer/gstbayer2rgb.c
+++ b/gst/bayer/gstbayer2rgb.c
@@ -483,11 +483,13 @@ gst_bayer2rgb_process (GstBayer2RGB * bayer2rgb, uint8_t * dest,
tmp = g_malloc (2 * 4 * bayer2rgb->width);
#define LINE(t, x, b) ((t) + (((x) & 7) * ((b)->width)))
+ /* Pre-process source line 1 into bottom two lines 6 and 7 as PREVIOUS line */
gst_bayer2rgb_split_and_upsample_horiz ( /* src line 1 */
LINE (tmp, 3 * 2 + 0, bayer2rgb), /* tmp buffer line 6 */
LINE (tmp, 3 * 2 + 1, bayer2rgb), /* tmp buffer line 7 */
src + 1 * src_stride, bayer2rgb);
+ /* Pre-process source line 0 into top two lines 0 and 1 as CURRENT line */
gst_bayer2rgb_split_and_upsample_horiz ( /* src line 0 */
LINE (tmp, 0 * 2 + 0, bayer2rgb), /* tmp buffer line 0 */
LINE (tmp, 0 * 2 + 1, bayer2rgb), /* tmp buffer line 1 */
@@ -495,12 +497,80 @@ gst_bayer2rgb_process (GstBayer2RGB * bayer2rgb, uint8_t * dest,
for (j = 0; j < bayer2rgb->height; j++) {
if (j < bayer2rgb->height - 1) {
+ /*
+ * Pre-process NEXT source line (j + 1) into two consecutive lines
+ * (2 * (j + 1) + 0) % 8
+ * and
+ * (2 * (j + 1) + 1) % 8
+ *
+ * This cycle here starts with j=0, and therefore
+ * - reads source line 1
+ * - writes tmp buffer lines 2,3
+ * The cycle continues with source line 2 and tmp buffer lines 4,5 etc.
+ */
gst_bayer2rgb_split_and_upsample_horiz ( /* src line (j + 1) */
LINE (tmp, (j + 1) * 2 + 0, bayer2rgb), /* tmp buffer line 2/4/6/0 */
LINE (tmp, (j + 1) * 2 + 1, bayer2rgb), /* tmp buffer line 3/5/7/1 */
src + (j + 1) * src_stride, bayer2rgb);
}
+ /*
+ * Use the pre-processed tmp buffer lines and construct resulting frame.
+ * Assume j=0, the tmp buffer content looks as follows:
+ * line 0: B0 avg(B0, B1) B1 avg(B1, B2) B2 avg(B2, B3)...
+ * line 1: G0 G0 avg(G0, G1) G1 avg(G1, G2) G2...
+ * line 2: G0 avg(G0, G1) G1 avg(G1, G2) G2 avg(G2, G3)...
+ * line 3: R0 R0 avg(R0, R1) R1 avg(R1, R2) R2...
+ * line 4: empty
+ * line 5: empty
+ * line 6: G0 avg(G0, G1) G1 avg(G1, G2) G2 avg(G2, G3)...
+ * line 7: R0 R0 avg(R0, R1) R1 avg(R1, R2) R2...
+ * Line 0,1 and 6,7 were populated in pre-process step outside of this loop.
+ * Line 2,3 was populated just above this comment.
+ * The code is currently processing source line 0 (not tmp buffer line 0)
+ * and uses the following tmp buffer lines in the process as inputs to the
+ * merge function:
+ * - tmp buffer line -2 => tmp buffer line 6 => orc g0 values
+ * - tmp buffer line -1 => tmp buffer line 7 => orc r0 values
+ * - tmp buffer line +0 => tmp buffer line 0 => orc b1 values
+ * - tmp buffer line +1 => tmp buffer line 1 => orc g1 values
+ * - tmp buffer line +2 => tmp buffer line 2 => orc g2 values
+ * - tmp buffer line +3 => tmp buffer line 3 => orc r2 values
+ * With j=0, the merge function used is one of bayer_orc_merge_bg_*
+ *
+ * A good material regarding the ORC functions below is
+ * https://www.siliconimaging.com/RGB%20Bayer.htm
+ * chapter
+ * "Interpolating the green component"
+ *
+ * The bayer_orc_merge_bg_* performs BG interpolation.
+ * # average R from PREVIOUS line and NEXT line
+ * r = [ avg(r0[0], r2[0]) , avg(r0[1], r2[1]) ]
+ * # average G from PREVIOUS line and NEXT line
+ * g = [ avg(g0[0], g2[0]) , avg(g0[1], g2[1]) ]
+ * # copy CURRENT line G into variable t
+ * t = [ g1[0] , g1[1] ]
+ * # average G from PREVIOUS, CURRENT, NEXT line
+ * g = [ avg(g[0], g1[0]) , avg(g[1], g1[1]) ]
+ * # reorder the content of g and t variables using bit operations
+ * # (the "g first, t second" order is here because the B pixel we
+ * # are now processing does not have its own G value, it only has
+ * # G value extrapolated from surrouding G pixels. The following
+ * # G pixel has its own G value, so we use it as-is, without any
+ * # extrapolation)
+ * g = [ g, 0 ]
+ * t = [ 0, t ]
+ * g = [ g, t ]
+ * # generate resulting (e.g. BGRx) data
+ * bg = [ b1[0] , g , b1[1] , t ]
+ * ra = [ r[0] , 255 , r[1] , 255 ]
+ * d = [ b1[0] , g , r[0] , 255 , b1[1] , t , r[1] , 255 ]
+ *
+ * In the next cycle, j=1, line 4,5 would be populated with BG values
+ * calculated from source line 2, merge function would use tmp buffer
+ * inputs from lines 0,1,2,3,4,5 i.e. b0,g0,g1,r1,b2,g2 and the merge
+ * function would be bayer_orc_merge_gr_* .
+ */
merge[j & 1] (dest + j * dest_stride, /* output line j */
LINE (tmp, j * 2 - 2, bayer2rgb), /* PREVIOUS: even: BG g0 , odd: GR b0 */
LINE (tmp, j * 2 - 1, bayer2rgb), /* PREVIOUS: even: BG r0 , odd: GR g0 */
--
2.44.1