diff --git a/src/libs/capture.c b/src/libs/capture.c index 6f3cf4b..f4375d4 100644 --- a/src/libs/capture.c +++ b/src/libs/capture.c @@ -747,6 +747,21 @@ static int _capture_open_format(us_capture_s *cap, bool first) { run->format = FMT(pixelformat); _D_LOG_INFO("Using format: %s", _format_to_string_supported(run->format)); + if (cap->format_swap_rgb) { + // Userspace workaround for TC358743 RGB/BGR bug: + // - https://github.com/raspberrypi/linux/issues/6068 + uint swapped = 0; + switch (run->format) { + case V4L2_PIX_FMT_RGB24: swapped = V4L2_PIX_FMT_BGR24; break; + case V4L2_PIX_FMT_BGR24: swapped = V4L2_PIX_FMT_RGB24; break; + } + if (swapped > 0) { + _D_LOG_INFO("Using format swap: %s -> %s", + _format_to_string_supported(run->format), + _format_to_string_supported(swapped)); + run->format = swapped; + } + } run->stride = FMTS(bytesperline); run->raw_size = FMTS(sizeimage); // Only for userptr diff --git a/src/libs/capture.h b/src/libs/capture.h index 594bc02..9137f19 100644 --- a/src/libs/capture.h +++ b/src/libs/capture.h @@ -104,6 +104,8 @@ typedef struct { uint width; uint height; uint format; + + bool format_swap_rgb; uint jpeg_quality; v4l2_std_id standard; enum v4l2_memory io_method; diff --git a/src/ustreamer/options.c b/src/ustreamer/options.c index bd12134..a9f25e9 100644 --- a/src/ustreamer/options.c +++ b/src/ustreamer/options.c @@ -61,6 +61,7 @@ enum _US_OPT_VALUES { _O_DEVICE_TIMEOUT = 10000, _O_DEVICE_ERROR_DELAY, + _O_FORMAT_SWAP_RGB, _O_M2M_DEVICE, _O_IMAGE_DEFAULT, @@ -136,6 +137,7 @@ static const struct option _LONG_OPTS[] = { {"input", required_argument, NULL, _O_INPUT}, {"resolution", required_argument, NULL, _O_RESOLUTION}, {"format", required_argument, NULL, _O_FORMAT}, + {"format-swap-rgb", required_argument, NULL, _O_FORMAT_SWAP_RGB}, {"tv-standard", required_argument, NULL, _O_TV_STANDARD}, {"io-method", required_argument, NULL, _O_IO_METHOD}, {"desired-fps", required_argument, NULL, _O_DESIRED_FPS}, @@ -374,6 +376,7 @@ int options_parse(us_options_s *options, us_capture_s *cap, us_encoder_s *enc, u # pragma GCC diagnostic push case _O_FORMAT: OPT_PARSE_ENUM("pixel format", cap->format, us_capture_parse_format, US_FORMATS_STR); # pragma GCC diagnostic pop + case _O_FORMAT_SWAP_RGB: OPT_SET(cap->format_swap_rgb, true); case _O_TV_STANDARD: OPT_PARSE_ENUM("TV standard", cap->standard, us_capture_parse_standard, US_STANDARDS_STR); case _O_IO_METHOD: OPT_PARSE_ENUM("IO method", cap->io_method, us_capture_parse_io_method, US_IO_METHODS_STR); case _O_DESIRED_FPS: OPT_NUMBER("--desired-fps", cap->desired_fps, 0, US_VIDEO_MAX_FPS, 0); @@ -613,6 +616,8 @@ static void _help(FILE *fp, const us_capture_s *cap, const us_encoder_s *enc, co SAY(" -r|--resolution ─────────────── Initial image resolution. Default: %ux%u.\n", cap->width, cap->height); SAY(" -m|--format ─────────────────── Image format."); SAY(" Available: %s; default: YUYV.\n", US_FORMATS_STR); + SAY(" --format-swap-rgb ──────────────── Enable R-G-B order swapping: RGB to BGR and vice versa."); + SAY(" Default: disabled.\n"); SAY(" -a|--tv-standard ────────────── Force TV standard."); SAY(" Available: %s; default: disabled.\n", US_STANDARDS_STR); SAY(" -I|--io-method ───────────── Set V4L2 IO method (see kernel documentation)."); diff --git a/src/v4p/main.c b/src/v4p/main.c index edbc132..bbd0755 100644 --- a/src/v4p/main.c +++ b/src/v4p/main.c @@ -165,6 +165,7 @@ static void _main_loop(void) { cap->path = "/dev/kvmd-video"; cap->n_bufs = 6; cap->format = V4L2_PIX_FMT_RGB24; + cap->format_swap_rgb = true; cap->dv_timings = true; cap->persistent = true; cap->dma_export = true;