| Message ID | 20260219173423.1028522-1-dev@fredfunk.tech |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Hi Frederic, Thank you for the patch. On Thu, Feb 19, 2026 at 05:34:34PM +0000, Frederic Laing wrote: > Add SRGGB/SBGGR/SGBRG/SGRBG 10/12/14-bit CSI-2 packed (CSI2P) format > entries to both format_map and bayer_map in gstlibcamera-utils.cpp. > > Many camera sensors (e.g., IMX371, IMX376) natively output > CSI-2 packed Bayer formats like SRGGB10_CSI2P. It's not a property of the sensor, but of the CSI-2 receiver (or more precisely the DMA engine on the output of the CSI-2 receievr). Same CSI-2 receivers will write the packed data to memory, some will unpack the data, and others will even repack them in a different format. I'd write Many CSI-2 receivers write raw data in the packed format defined in the CSI-2 specification, like SRGGB10_CSI2P. > Without mappings for > these formats, GStreamer's libcamerasrc cannot negotiate raw Bayer > output (video/x-bayer caps) when the sensor only supports CSI2P > variants, causing caps negotiation to fail with empty caps. > > This is particularly important for dual-stream (ViewFinder + Raw) > capture where the Raw stream needs to use the sensor's native CSI2P s/sensor's native // > format. The Software ISP processes only the ViewFinder stream while > the Raw stream bypasses it entirely, but GStreamer needs to be able > to represent the Raw stream's format in caps. > > The CSI2P formats are mapped to distinct GStreamer Bayer format names > using a "p" suffix (e.g., SRGGB10_CSI2P -> "rggb10p") to distinguish > them from their unpacked counterparts (e.g., SRGGB10 -> "rggb10le"). > > This patch depends on the corresponding GStreamer merge request that > adds CSI-2 packed Bayer format support to the V4L2 plugin: > https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10852 The code looks fine. Once the merge request gets appreoved, we can merge this in libcamera. > > Tested on OnePlus 6T (Qualcomm SDM845) with IMX371 front camera: > - Single raw stream: 4656x3496 SRGGB10_CSI2P > - Dual stream: 640x480 ABGR8888 (ViewFinder) + 4656x3496 SRGGB10_CSI2P > > Signed-off-by: Frederic Laing <dev@fredfunk.tech> > --- > src/gstreamer/gstlibcamera-utils.cpp | 31 +++++++++++++++++++++++++++- > 1 file changed, 30 insertions(+), 1 deletion(-) > > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp > index bfb094c9..467e4f71 100644 > --- a/src/gstreamer/gstlibcamera-utils.cpp > +++ b/src/gstreamer/gstlibcamera-utils.cpp > @@ -22,7 +22,7 @@ static const struct { > /* Compressed */ > { GST_VIDEO_FORMAT_ENCODED, formats::MJPEG }, > > - /* Bayer formats */ > + /* Bayer formats - unpacked */ > { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR8 }, > { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG8 }, > { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG8 }, > @@ -44,6 +44,20 @@ static const struct { > { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG16 }, > { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB16 }, > > + /* Bayer formats - CSI-2 packed */ > + { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR10_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG10_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG10_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB10_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR12_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG12_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG12_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB12_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR14_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG14_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG14_CSI2P }, > + { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB14_CSI2P }, > + > /* Monochrome */ > { GST_VIDEO_FORMAT_GRAY8, formats::R8 }, > { GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 }, > @@ -265,6 +279,7 @@ static const struct { > PixelFormat format; > const gchar *name; > } bayer_map[]{ > + /* Unpacked */ > { formats::SBGGR8, "bggr" }, > { formats::SGBRG8, "gbrg" }, > { formats::SGRBG8, "grbg" }, > @@ -285,6 +300,20 @@ static const struct { > { formats::SGBRG16, "gbrg16le" }, > { formats::SGRBG16, "grbg16le" }, > { formats::SRGGB16, "rggb16le" }, > + > + /* CSI-2 packed */ > + { formats::SBGGR10_CSI2P, "bggr10p" }, > + { formats::SGBRG10_CSI2P, "gbrg10p" }, > + { formats::SGRBG10_CSI2P, "grbg10p" }, > + { formats::SRGGB10_CSI2P, "rggb10p" }, > + { formats::SBGGR12_CSI2P, "bggr12p" }, > + { formats::SGBRG12_CSI2P, "gbrg12p" }, > + { formats::SGRBG12_CSI2P, "grbg12p" }, > + { formats::SRGGB12_CSI2P, "rggb12p" }, > + { formats::SBGGR14_CSI2P, "bggr14p" }, > + { formats::SGBRG14_CSI2P, "gbrg14p" }, > + { formats::SGRBG14_CSI2P, "grbg14p" }, > + { formats::SRGGB14_CSI2P, "rggb14p" }, > }; > > static const gchar *
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index bfb094c9..467e4f71 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -22,7 +22,7 @@ static const struct { /* Compressed */ { GST_VIDEO_FORMAT_ENCODED, formats::MJPEG }, - /* Bayer formats */ + /* Bayer formats - unpacked */ { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR8 }, { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG8 }, { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG8 }, @@ -44,6 +44,20 @@ static const struct { { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG16 }, { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB16 }, + /* Bayer formats - CSI-2 packed */ + { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR10_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG10_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG10_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB10_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR12_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG12_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG12_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB12_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SBGGR14_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SGBRG14_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SGRBG14_CSI2P }, + { GST_VIDEO_FORMAT_ENCODED, formats::SRGGB14_CSI2P }, + /* Monochrome */ { GST_VIDEO_FORMAT_GRAY8, formats::R8 }, { GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 }, @@ -265,6 +279,7 @@ static const struct { PixelFormat format; const gchar *name; } bayer_map[]{ + /* Unpacked */ { formats::SBGGR8, "bggr" }, { formats::SGBRG8, "gbrg" }, { formats::SGRBG8, "grbg" }, @@ -285,6 +300,20 @@ static const struct { { formats::SGBRG16, "gbrg16le" }, { formats::SGRBG16, "grbg16le" }, { formats::SRGGB16, "rggb16le" }, + + /* CSI-2 packed */ + { formats::SBGGR10_CSI2P, "bggr10p" }, + { formats::SGBRG10_CSI2P, "gbrg10p" }, + { formats::SGRBG10_CSI2P, "grbg10p" }, + { formats::SRGGB10_CSI2P, "rggb10p" }, + { formats::SBGGR12_CSI2P, "bggr12p" }, + { formats::SGBRG12_CSI2P, "gbrg12p" }, + { formats::SGRBG12_CSI2P, "grbg12p" }, + { formats::SRGGB12_CSI2P, "rggb12p" }, + { formats::SBGGR14_CSI2P, "bggr14p" }, + { formats::SGBRG14_CSI2P, "gbrg14p" }, + { formats::SGRBG14_CSI2P, "grbg14p" }, + { formats::SRGGB14_CSI2P, "rggb14p" }, }; static const gchar *
Add SRGGB/SBGGR/SGBRG/SGRBG 10/12/14-bit CSI-2 packed (CSI2P) format entries to both format_map and bayer_map in gstlibcamera-utils.cpp. Many camera sensors (e.g., IMX371, IMX376) natively output CSI-2 packed Bayer formats like SRGGB10_CSI2P. Without mappings for these formats, GStreamer's libcamerasrc cannot negotiate raw Bayer output (video/x-bayer caps) when the sensor only supports CSI2P variants, causing caps negotiation to fail with empty caps. This is particularly important for dual-stream (ViewFinder + Raw) capture where the Raw stream needs to use the sensor's native CSI2P format. The Software ISP processes only the ViewFinder stream while the Raw stream bypasses it entirely, but GStreamer needs to be able to represent the Raw stream's format in caps. The CSI2P formats are mapped to distinct GStreamer Bayer format names using a "p" suffix (e.g., SRGGB10_CSI2P -> "rggb10p") to distinguish them from their unpacked counterparts (e.g., SRGGB10 -> "rggb10le"). This patch depends on the corresponding GStreamer merge request that adds CSI-2 packed Bayer format support to the V4L2 plugin: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10852 Tested on OnePlus 6T (Qualcomm SDM845) with IMX371 front camera: - Single raw stream: 4656x3496 SRGGB10_CSI2P - Dual stream: 640x480 ABGR8888 (ViewFinder) + 4656x3496 SRGGB10_CSI2P Signed-off-by: Frederic Laing <dev@fredfunk.tech> --- src/gstreamer/gstlibcamera-utils.cpp | 31 +++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)