gstreamer: Map 10-bit monochrome frames
diff mbox series

Message ID 20261015194317.287913-1-halfline@gmail.com
State Accepted
Headers show
Series
  • gstreamer: Map 10-bit monochrome frames
Related show

Commit Message

Ray Strode Oct. 15, 2026, 7:43 p.m. UTC
From: Ray Strode <rstrode@redhat.com>

The GStreamer format map covers 8-bit and 16-bit monochrome frames,
while libcamera also represents 10-bit monochrome as R10.

GStreamer pipelines cannot negotiate that 10-bit format through the
camera source.

This commit maps the GStreamer 10-bit little-endian monochrome format to
R10 when the installed GStreamer version provides it.

Signed-off-by: Ray Strode <rstrode@redhat.com>
---
 src/gstreamer/gstlibcamera-utils.cpp | 3 +++
 1 file changed, 3 insertions(+)

Comments

Kieran Bingham Oct. 18, 2026, 9:27 p.m. UTC | #1
Quoting Ray Strode (2026-10-15 20:43:17)
> From: Ray Strode <rstrode@redhat.com>
> 
> The GStreamer format map covers 8-bit and 16-bit monochrome frames,
> while libcamera also represents 10-bit monochrome as R10.
> 
> GStreamer pipelines cannot negotiate that 10-bit format through the
> camera source.
> 
> This commit maps the GStreamer 10-bit little-endian monochrome format to
> R10 when the installed GStreamer version provides it.
> 
> Signed-off-by: Ray Strode <rstrode@redhat.com>
> ---
>  src/gstreamer/gstlibcamera-utils.cpp | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
> index 7dd8b550..d7c842f5 100644
> --- a/src/gstreamer/gstlibcamera-utils.cpp
> +++ b/src/gstreamer/gstlibcamera-utils.cpp
>  
>         /* Monochrome */
>         { GST_VIDEO_FORMAT_GRAY8, formats::R8 },
> +#if GST_CHECK_VERSION(1, 26, 0)
> +       { GST_VIDEO_FORMAT_GRAY10_LE16, formats::R10 },

Ok so lets dig:

https://gstreamer.freedesktop.org/documentation/video/video-format.html?gi-language=c

 GST_VIDEO_FORMAT_GRAY10_LE16 (138) – 10-bit grayscale, packed into 16bit words (6 bits left padding) (Since: 1.26) 


https://lists.freedesktop.org/archives/dri-devel/2021-October/329308.html

+#define DRM_FORMAT_R10		fourcc_code('R', '1', '0', ' ') /* [15:0] x:R 6:10 little endian */
+
+/* 12 bpp Red */
+#define DRM_FORMAT_R12		fourcc_code('R', '1', '2', ' ') /* [15:0] x:R 4:12 little endian */

I wonder where gstreamers' GRAY12_LE16 (and then by extenstion
GRAY14_LE16) is. But the mapping for GRAY10_LE16 appears to match there
for my understanding so :

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> +#endif
>         { GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 },
>
Laurent Pinchart Oct. 18, 2026, 9:35 p.m. UTC | #2
On Sun, Oct 18, 2026 at 10:27:45PM +0100, Kieran Bingham wrote:
> Quoting Ray Strode (2026-10-15 20:43:17)
> > From: Ray Strode <rstrode@redhat.com>
> > 
> > The GStreamer format map covers 8-bit and 16-bit monochrome frames,
> > while libcamera also represents 10-bit monochrome as R10.
> > 
> > GStreamer pipelines cannot negotiate that 10-bit format through the
> > camera source.
> > 
> > This commit maps the GStreamer 10-bit little-endian monochrome format to
> > R10 when the installed GStreamer version provides it.
> > 
> > Signed-off-by: Ray Strode <rstrode@redhat.com>
> > ---
> >  src/gstreamer/gstlibcamera-utils.cpp | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
> > index 7dd8b550..d7c842f5 100644
> > --- a/src/gstreamer/gstlibcamera-utils.cpp
> > +++ b/src/gstreamer/gstlibcamera-utils.cpp
> >  
> >         /* Monochrome */
> >         { GST_VIDEO_FORMAT_GRAY8, formats::R8 },
> > +#if GST_CHECK_VERSION(1, 26, 0)
> > +       { GST_VIDEO_FORMAT_GRAY10_LE16, formats::R10 },
> 
> Ok so lets dig:
> 
> https://gstreamer.freedesktop.org/documentation/video/video-format.html?gi-language=c
> 
>  GST_VIDEO_FORMAT_GRAY10_LE16 (138) – 10-bit grayscale, packed into 16bit words (6 bits left padding) (Since: 1.26) 
> 
> 
> https://lists.freedesktop.org/archives/dri-devel/2021-October/329308.html
> 
> +#define DRM_FORMAT_R10		fourcc_code('R', '1', '0', ' ') /* [15:0] x:R 6:10 little endian */
> +
> +/* 12 bpp Red */
> +#define DRM_FORMAT_R12		fourcc_code('R', '1', '2', ' ') /* [15:0] x:R 4:12 little endian */
> 
> I wonder where gstreamers' GRAY12_LE16 (and then by extenstion
> GRAY14_LE16) is. But the mapping for GRAY10_LE16 appears to match there
> for my understanding so :
> 
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

Please check with Nicolas for GStreamer patches.

> > +#endif
> >         { GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 },
> >
Kieran Bingham Oct. 18, 2026, 9:58 p.m. UTC | #3
+Cc Nicolas,

Quoting Laurent Pinchart (2026-10-18 22:35:02)
> On Sun, Oct 18, 2026 at 10:27:45PM +0100, Kieran Bingham wrote:
> > Quoting Ray Strode (2026-10-15 20:43:17)
> > > From: Ray Strode <rstrode@redhat.com>
> > > 
> > > The GStreamer format map covers 8-bit and 16-bit monochrome frames,
> > > while libcamera also represents 10-bit monochrome as R10.
> > > 
> > > GStreamer pipelines cannot negotiate that 10-bit format through the
> > > camera source.
> > > 
> > > This commit maps the GStreamer 10-bit little-endian monochrome format to
> > > R10 when the installed GStreamer version provides it.
> > > 
> > > Signed-off-by: Ray Strode <rstrode@redhat.com>
> > > ---
> > >  src/gstreamer/gstlibcamera-utils.cpp | 3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
> > > index 7dd8b550..d7c842f5 100644
> > > --- a/src/gstreamer/gstlibcamera-utils.cpp
> > > +++ b/src/gstreamer/gstlibcamera-utils.cpp
> > >  
> > >         /* Monochrome */
> > >         { GST_VIDEO_FORMAT_GRAY8, formats::R8 },
> > > +#if GST_CHECK_VERSION(1, 26, 0)
> > > +       { GST_VIDEO_FORMAT_GRAY10_LE16, formats::R10 },
> > 
> > Ok so lets dig:
> > 
> > https://gstreamer.freedesktop.org/documentation/video/video-format.html?gi-language=c
> > 
> >  GST_VIDEO_FORMAT_GRAY10_LE16 (138) – 10-bit grayscale, packed into 16bit words (6 bits left padding) (Since: 1.26) 
> > 
> > 
> > https://lists.freedesktop.org/archives/dri-devel/2021-October/329308.html
> > 
> > +#define DRM_FORMAT_R10               fourcc_code('R', '1', '0', ' ') /* [15:0] x:R 6:10 little endian */
> > +
> > +/* 12 bpp Red */
> > +#define DRM_FORMAT_R12               fourcc_code('R', '1', '2', ' ') /* [15:0] x:R 4:12 little endian */
> > 
> > I wonder where gstreamers' GRAY12_LE16 (and then by extenstion
> > GRAY14_LE16) is. But the mapping for GRAY10_LE16 appears to match there
> > for my understanding so :
> > 
> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> Please check with Nicolas for GStreamer patches.

I guess we really do need a get_maintainers.pl ;-)
--
Kieran


> 
> > > +#endif
> > >         { GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 },
> > >
> 
> -- 
> Regards,
> 
> Laurent Pinchart
Nicolas Dufresne Oct. 20, 2026, 8:27 p.m. UTC | #4
Hi,

Le dimanche 18 octobre 2026 à 23:35 +0200, Laurent Pinchart a écrit :
> On Sun, Oct 18, 2026 at 10:27:45PM +0100, Kieran Bingham wrote:
> > Quoting Ray Strode (2026-10-15 20:43:17)
> > > From: Ray Strode <rstrode@redhat.com>
> > > 
> > > The GStreamer format map covers 8-bit and 16-bit monochrome frames,
> > > while libcamera also represents 10-bit monochrome as R10.
> > > 
> > > GStreamer pipelines cannot negotiate that 10-bit format through the
> > > camera source.
> > > 
> > > This commit maps the GStreamer 10-bit little-endian monochrome format to
> > > R10 when the installed GStreamer version provides it.
> > > 
> > > Signed-off-by: Ray Strode <rstrode@redhat.com>
> > > ---
> > >  src/gstreamer/gstlibcamera-utils.cpp | 3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
> > > index 7dd8b550..d7c842f5 100644
> > > --- a/src/gstreamer/gstlibcamera-utils.cpp
> > > +++ b/src/gstreamer/gstlibcamera-utils.cpp
> > >  
> > >         /* Monochrome */
> > >         { GST_VIDEO_FORMAT_GRAY8, formats::R8 },
> > > +#if GST_CHECK_VERSION(1, 26, 0)
> > > +       { GST_VIDEO_FORMAT_GRAY10_LE16, formats::R10 },
> > 
> > Ok so lets dig:
> > 
> > https://gstreamer.freedesktop.org/documentation/video/video-format.html?gi-language=c
> > 
> >  GST_VIDEO_FORMAT_GRAY10_LE16 (138) – 10-bit grayscale, packed into 16bit words (6 bits left padding) (Since: 1.26) 
> > 
> > 
> > https://lists.freedesktop.org/archives/dri-devel/2021-October/329308.html
> > 
> > +#define DRM_FORMAT_R10		fourcc_code('R', '1', '0', ' ') /* [15:0] x:R 6:10 little endian */
> > +
> > +/* 12 bpp Red */
> > +#define DRM_FORMAT_R12		fourcc_code('R', '1', '2', ' ') /* [15:0] x:R 4:12 little endian */
> > 
> > I wonder where gstreamers' GRAY12_LE16 (and then by extenstion
> > GRAY14_LE16) is. But the mapping for GRAY10_LE16 appears to match there
> > for my understanding so :

Formats are added by people that needs them, patches welcome (cc me for review).

> > 
> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> Please check with Nicolas for GStreamer patches.

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>

> 
> > > +#endif
> > >         { GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 },
> > >

Patch
diff mbox series

diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
index 7dd8b550..d7c842f5 100644
--- a/src/gstreamer/gstlibcamera-utils.cpp
+++ b/src/gstreamer/gstlibcamera-utils.cpp
@@ -19,60 +19,63 @@  static const struct {
 	GstVideoFormat gst_format;
 	PixelFormat format;
 } format_map[] = {
 	/* Compressed */
 	{ GST_VIDEO_FORMAT_ENCODED, formats::MJPEG },
 
 	/* Bayer formats */
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SBGGR8 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGBRG8 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGRBG8 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SRGGB8 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SBGGR10 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGBRG10 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGRBG10 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SRGGB10 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SBGGR12 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGBRG12 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGRBG12 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SRGGB12 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SBGGR14 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGBRG14 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGRBG14 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SRGGB14 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SBGGR16 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGBRG16 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SGRBG16 },
 	{ GST_VIDEO_FORMAT_ENCODED, formats::SRGGB16 },
 
 	/* Monochrome */
 	{ GST_VIDEO_FORMAT_GRAY8, formats::R8 },
+#if GST_CHECK_VERSION(1, 26, 0)
+	{ GST_VIDEO_FORMAT_GRAY10_LE16, formats::R10 },
+#endif
 	{ GST_VIDEO_FORMAT_GRAY16_LE, formats::R16 },
 
 	/* RGB16 */
 	{ GST_VIDEO_FORMAT_RGB16, formats::RGB565 },
 
 	/* RGB24 */
 	{ GST_VIDEO_FORMAT_RGB, formats::BGR888 },
 	{ GST_VIDEO_FORMAT_BGR, formats::RGB888 },
 
 	/* RGB32 */
 	{ GST_VIDEO_FORMAT_BGRx, formats::XRGB8888 },
 	{ GST_VIDEO_FORMAT_RGBx, formats::XBGR8888 },
 	{ GST_VIDEO_FORMAT_xBGR, formats::RGBX8888 },
 	{ GST_VIDEO_FORMAT_xRGB, formats::BGRX8888 },
 	{ GST_VIDEO_FORMAT_BGRA, formats::ARGB8888 },
 	{ GST_VIDEO_FORMAT_RGBA, formats::ABGR8888 },
 	{ GST_VIDEO_FORMAT_ABGR, formats::RGBA8888 },
 	{ GST_VIDEO_FORMAT_ARGB, formats::BGRA8888 },
 
 	/* YUV Semiplanar */
 	{ GST_VIDEO_FORMAT_NV12, formats::NV12 },
 	{ GST_VIDEO_FORMAT_NV21, formats::NV21 },
 	{ GST_VIDEO_FORMAT_NV16, formats::NV16 },
 	{ GST_VIDEO_FORMAT_NV61, formats::NV61 },
 	{ GST_VIDEO_FORMAT_NV24, formats::NV24 },
 
 	/* YUV Planar */
 	{ GST_VIDEO_FORMAT_I420, formats::YUV420 },
 	{ GST_VIDEO_FORMAT_YV12, formats::YVU420 },
 	{ GST_VIDEO_FORMAT_Y42B, formats::YUV422 },