From b380beba6d74efa1c3747065fb1091f60c230d6b Mon Sep 17 00:00:00 2001 From: gudvinr Date: Sat, 8 Mar 2025 21:01:49 +0300 Subject: [PATCH] Add GREY pixelformat (#171) Fixes #170 Monochrome cameras send only Y component of YUV image --- src/libs/capture.c | 1 + src/libs/frame.c | 1 + src/ustreamer/encoders/cpu/encoder.c | 33 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/libs/capture.c b/src/libs/capture.c index 139b589..ef12d76 100644 --- a/src/libs/capture.c +++ b/src/libs/capture.c @@ -69,6 +69,7 @@ static const struct { {"UYVY", V4L2_PIX_FMT_UYVY}, {"YUV420", V4L2_PIX_FMT_YUV420}, {"YVU420", V4L2_PIX_FMT_YVU420}, + {"GREY", V4L2_PIX_FMT_GREY}, {"RGB565", V4L2_PIX_FMT_RGB565}, {"RGB24", V4L2_PIX_FMT_RGB24}, {"BGR24", V4L2_PIX_FMT_BGR24}, diff --git a/src/libs/frame.c b/src/libs/frame.c index b24735c..0636d0c 100644 --- a/src/libs/frame.c +++ b/src/libs/frame.c @@ -84,6 +84,7 @@ uint us_frame_get_padding(const us_frame_s *frame) { switch (frame->format) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_GREY: bytes_per_pixel = 1; break; diff --git a/src/ustreamer/encoders/cpu/encoder.c b/src/ustreamer/encoders/cpu/encoder.c index f116b27..1ea6229 100644 --- a/src/ustreamer/encoders/cpu/encoder.c +++ b/src/ustreamer/encoders/cpu/encoder.c @@ -39,6 +39,7 @@ static void _jpeg_set_dest_frame(j_compress_ptr jpeg, us_frame_s *frame); static void _jpeg_write_scanlines_yuv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); static void _jpeg_write_scanlines_yuv_planar(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); +static void _jpeg_write_scanlines_grey(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); #ifndef JCS_EXTENSIONS @@ -75,6 +76,10 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, uint quali case V4L2_PIX_FMT_YVU420: jpeg.in_color_space = JCS_YCbCr; break; + case V4L2_PIX_FMT_GREY: + jpeg.input_components = 1; + jpeg.in_color_space = JCS_GRAYSCALE; + break; # ifdef JCS_EXTENSIONS case V4L2_PIX_FMT_BGR24: jpeg.in_color_space = JCS_EXT_BGR; @@ -102,6 +107,10 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, uint quali case V4L2_PIX_FMT_YVU420: _jpeg_write_scanlines_yuv_planar(&jpeg, src); break; + + case V4L2_PIX_FMT_GREY: + _jpeg_write_scanlines_grey(&jpeg, src); + break; case V4L2_PIX_FMT_RGB565: _jpeg_write_scanlines_rgb565(&jpeg, src); @@ -249,6 +258,30 @@ static void _jpeg_write_scanlines_yuv_planar(struct jpeg_compress_struct *jpeg, free(line_buf); } +static void _jpeg_write_scanlines_grey(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { + u8 *line_buf; + US_CALLOC(line_buf, frame->width); + + const uint padding = us_frame_get_padding(frame); + const u8 *data = frame->data; + + while (jpeg->next_scanline < frame->height) { + u8 *ptr = line_buf; + + for (uint x = 0; x < frame->width; ++x) { + ptr[0] = data[x]; + ptr += 1; + } + + data += frame->width + padding; + + JSAMPROW scanlines[1] = {line_buf}; + jpeg_write_scanlines(jpeg, scanlines, 1); + } + + free(line_buf); +} + static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { u8 *line_buf; US_CALLOC(line_buf, frame->width * 3);