From: Pavan Bobba <opensource206@gmail.com>
To: skhan@linuxfoundation.org, kieran.bingham@ideasonboard.com,
mchehab@kernel.org
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
Pavan Bobba <opensource206@gmail.com>
Subject: [PATCH] media: vimc: debayer: add support for multiple RGB formats
Date: Mon, 3 Nov 2025 11:27:16 +0530 [thread overview]
Message-ID: <20251103055716.29537-1-opensource206@gmail.com> (raw)
Enhance the vimc debayer subdevice to support multiple RGB output
formats and improve its format negotiation behavior.
This patch introduces the following changes:
- Adds ARGB8888_1X32 to the list of supported source pad mbus codes.
- Allows userspace to select any valid RGB code on the source pad
through set_fmt().
- Propagates width, height, and field settings from sink to source
while preserving the selected RGB code.
- Sets appropriate default colorimetry for RGB output (sRGB, full-range).
- Updates vimc_debayer_process_rgb_frame() to handle RGB24, BGR24,
and ARGB32 pixel formats with proper channel ordering and alpha fill.
- Adds debug and warning logs for invalid or unsupported formats.
These changes make the virtual debayer pipeline more flexible and
realistic for testing RGB/ARGB camera capture paths.
Signed-off-by: Pavan Bobba <opensource206@gmail.com>
---
.../media/test-drivers/vimc/vimc-debayer.c | 113 ++++++++++++++----
1 file changed, 90 insertions(+), 23 deletions(-)
diff --git a/drivers/media/test-drivers/vimc/vimc-debayer.c b/drivers/media/test-drivers/vimc/vimc-debayer.c
index bbb7c7a86df0..0fa1cb8d3be1 100644
--- a/drivers/media/test-drivers/vimc/vimc-debayer.c
+++ b/drivers/media/test-drivers/vimc/vimc-debayer.c
@@ -15,9 +15,6 @@
#include "vimc-common.h"
-/* TODO: Add support for more output formats, we only support RGB888 for now. */
-#define VIMC_DEBAYER_SOURCE_MBUS_FMT MEDIA_BUS_FMT_RGB888_1X24
-
enum vimc_debayer_rgb_colors {
VIMC_DEBAYER_RED = 0,
VIMC_DEBAYER_GREEN = 1,
@@ -73,6 +70,7 @@ static const u32 vimc_debayer_src_mbus_codes[] = {
MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
MEDIA_BUS_FMT_RGB888_1X32_PADHI,
+ MEDIA_BUS_FMT_ARGB8888_1X32,
};
static const struct vimc_debayer_pix_map vimc_debayer_pix_map_list[] = {
@@ -170,7 +168,7 @@ static int vimc_debayer_init_state(struct v4l2_subdev *sd,
mf = v4l2_subdev_state_get_format(sd_state, 1);
*mf = sink_fmt_default;
- mf->code = VIMC_DEBAYER_SOURCE_MBUS_FMT;
+ mf->code = vimc_debayer_src_mbus_codes[0];
return 0;
}
@@ -239,6 +237,14 @@ static void vimc_debayer_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
vimc_colorimetry_clamp(fmt);
}
+static void vimc_debayer_set_rgb_mbus_fmt_default(struct v4l2_mbus_framefmt *fmt)
+{
+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
+ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
+ fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+}
+
static int vimc_debayer_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
@@ -250,12 +256,30 @@ static int vimc_debayer_set_fmt(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && vdebayer->src_frame)
return -EBUSY;
- /*
- * Do not change the format of the source pad, it is propagated from
- * the sink.
- */
- if (VIMC_IS_SRC(fmt->pad))
- return v4l2_subdev_get_fmt(sd, sd_state, fmt);
+ if (VIMC_IS_SRC(fmt->pad)) {
+ struct v4l2_mbus_framefmt *source_fmt;
+ struct v4l2_mbus_framefmt *sink_fmt;
+
+ /* Validate the requested source format */
+ if (!vimc_debayer_src_code_is_valid(fmt->format.code))
+ return -EINVAL;
+
+ /* Get current formats */
+ source_fmt = v4l2_subdev_state_get_format(sd_state, 1);
+ sink_fmt = v4l2_subdev_state_get_format(sd_state, 0);
+
+ /* Update source format with appropriate properties for RGB output */
+ source_fmt->code = fmt->format.code;
+ source_fmt->width = sink_fmt->width; /* Size should match */
+ source_fmt->height = sink_fmt->height; /* Size should match */
+ source_fmt->field = sink_fmt->field; /* Field handling should match */
+
+ /* Set appropriate colorimetry for RGB output */
+ vimc_debayer_set_rgb_mbus_fmt_default(source_fmt);
+
+ fmt->format = *source_fmt;
+ return 0;
+ }
/* Set the new format in the sink pad. */
vimc_debayer_adjust_sink_fmt(&fmt->format);
@@ -278,8 +302,25 @@ static int vimc_debayer_set_fmt(struct v4l2_subdev *sd,
/* Propagate the format to the source pad. */
format = v4l2_subdev_state_get_format(sd_state, 1);
- *format = fmt->format;
- format->code = VIMC_DEBAYER_SOURCE_MBUS_FMT;
+
+ /* Propagate size and field from sink, but maintain source code */
+ format->width = fmt->format.width;
+ format->height = fmt->format.height;
+ format->field = fmt->format.field;
+
+ /*
+ * Source code should always be valid (set during init or via set_fmt).
+ * If somehow it's not, this is a bug - log warning and fix it.
+ */
+ if (!vimc_debayer_src_code_is_valid(format->code)) {
+ dev_warn(vdebayer->ved.dev,
+ "%s: Invalid source code 0x%x, resetting to default\n",
+ vdebayer->sd.name, format->code);
+ format->code = vimc_debayer_src_mbus_codes[0];
+ }
+
+ /* Set appropriate colorimetry for RGB output */
+ vimc_debayer_set_rgb_mbus_fmt_default(format);
return 0;
}
@@ -297,19 +338,45 @@ static void vimc_debayer_process_rgb_frame(struct vimc_debayer_device *vdebayer,
unsigned int rgb[3])
{
const struct vimc_pix_map *vpix;
- unsigned int i, index;
+ unsigned int index;
vpix = vimc_pix_map_by_code(vdebayer->hw.src_code);
- index = VIMC_FRAME_INDEX(lin, col, vdebayer->hw.size.width, 3);
- for (i = 0; i < 3; i++) {
- switch (vpix->pixelformat) {
- case V4L2_PIX_FMT_RGB24:
- vdebayer->src_frame[index + i] = rgb[i];
- break;
- case V4L2_PIX_FMT_BGR24:
- vdebayer->src_frame[index + i] = rgb[2 - i];
- break;
- }
+ if (!vpix) {
+ dev_dbg(vdebayer->ved.dev, "Invalid source code: 0x%x\n",
+ vdebayer->hw.src_code);
+ return;
+ }
+
+ index = VIMC_FRAME_INDEX(lin, col, vdebayer->hw.size.width, vpix->bpp);
+
+ switch (vpix->pixelformat) {
+ case V4L2_PIX_FMT_RGB24:
+ /* RGB24: R-G-B */
+ vdebayer->src_frame[index + 0] = rgb[0]; /* Red */
+ vdebayer->src_frame[index + 1] = rgb[1]; /* Green */
+ vdebayer->src_frame[index + 2] = rgb[2]; /* Blue */
+ break;
+
+ case V4L2_PIX_FMT_BGR24:
+ /* BGR24: B-G-R */
+ vdebayer->src_frame[index + 0] = rgb[2]; /* Blue */
+ vdebayer->src_frame[index + 1] = rgb[1]; /* Green */
+ vdebayer->src_frame[index + 2] = rgb[0]; /* Red */
+ break;
+
+ case V4L2_PIX_FMT_ARGB32:
+ /* ARGB32: A-R-G-B (set alpha to 255) */
+ vdebayer->src_frame[index + 0] = 255; /* Alpha */
+ vdebayer->src_frame[index + 1] = rgb[0]; /* Red */
+ vdebayer->src_frame[index + 2] = rgb[1]; /* Green */
+ vdebayer->src_frame[index + 3] = rgb[2]; /* Blue */
+ break;
+
+ default:
+ dev_dbg(vdebayer->ved.dev,
+ "Unsupported pixel format for debayer: 0x%x\n",
+ vpix->pixelformat);
+ break;
}
}
--
2.43.0
reply other threads:[~2025-11-03 5:57 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251103055716.29537-1-opensource206@gmail.com \
--to=opensource206@gmail.com \
--cc=kieran.bingham@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).