| Message ID | 20260218213030.479743-1-dev@fredfunk.tech |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
On Wed, Feb 18, 2026 at 09:30:49PM +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. 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 handler where > dual-stream (ViewFinder + Raw) capture requires the Raw stream 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 the same GStreamer Bayer format names > as their unpacked counterparts (e.g., SRGGB10_CSI2P -> "rggb10le"), > since GStreamer's video/x-bayer caps describe the Bayer pattern and > bit depth, not the byte packing. > > 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..fb3a1411 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, "bggr10le" }, > + { formats::SGBRG10_CSI2P, "gbrg10le" }, > + { formats::SGRBG10_CSI2P, "grbg10le" }, > + { formats::SRGGB10_CSI2P, "rggb10le" }, > + { formats::SBGGR12_CSI2P, "bggr12le" }, > + { formats::SGBRG12_CSI2P, "gbrg12le" }, > + { formats::SGRBG12_CSI2P, "grbg12le" }, > + { formats::SRGGB12_CSI2P, "rggb12le" }, > + { formats::SBGGR14_CSI2P, "bggr14le" }, > + { formats::SGBRG14_CSI2P, "gbrg14le" }, > + { formats::SGRBG14_CSI2P, "grbg14le" }, > + { formats::SRGGB14_CSI2P, "rggb14le" }, These don't seem right. formats::SBGGR10_CSI2P and formats::SBGGR10 would both map to GST_VIDEO_FORMAT_ENCODED + "bggr10le", while they are different formats. How would GStreamer know they're different ? Given that GStreamer's V4L2 support maps e.g. "bggr10le" to V4L2_PIX_FMT_SBGGR10 and does not implement V4L2_PIX_FMT_SBGGR10P, I believe that GStreamer may be missing support for CSI-2 packet raw data. You may need to implement that in GStreamer first. > }; > > static const gchar *
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index bfb094c9..fb3a1411 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, "bggr10le" }, + { formats::SGBRG10_CSI2P, "gbrg10le" }, + { formats::SGRBG10_CSI2P, "grbg10le" }, + { formats::SRGGB10_CSI2P, "rggb10le" }, + { formats::SBGGR12_CSI2P, "bggr12le" }, + { formats::SGBRG12_CSI2P, "gbrg12le" }, + { formats::SGRBG12_CSI2P, "grbg12le" }, + { formats::SRGGB12_CSI2P, "rggb12le" }, + { formats::SBGGR14_CSI2P, "bggr14le" }, + { formats::SGBRG14_CSI2P, "gbrg14le" }, + { formats::SGRBG14_CSI2P, "grbg14le" }, + { formats::SRGGB14_CSI2P, "rggb14le" }, }; 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 handler where dual-stream (ViewFinder + Raw) capture requires the Raw stream 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 the same GStreamer Bayer format names as their unpacked counterparts (e.g., SRGGB10_CSI2P -> "rggb10le"), since GStreamer's video/x-bayer caps describe the Bayer pattern and bit depth, not the byte packing. 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(-)