From b1ebcfbfd6afb57f314b6689ca001aca1b13a5b4 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 8 Jul 2024 09:45:03 +0200 Subject: [PATCH] PipeWire camera: support additional formats and fix RGB/BGR mapping Similar to BGRA/RGBA we added recently, formats from PipeWire are in big-endian, while WebRTC (using libyuv) is little-endian, therefore we have to map BGR to RGB and not RGB to RGB as colors would be off. Also add some additional formats supported by libyuv. Bug: webrtc:42225999 Change-Id: Iee8303f0922fe434069b2b3f88994abecf7d2cc5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/355860 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Jan Grulich Cr-Commit-Position: refs/heads/main@{#42609} --- modules/video_capture/linux/pipewire_session.cc | 6 ++++++ .../video_capture/linux/video_capture_pipewire.cc | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc index d52d6aacc8..107ea3dfbd 100644 --- a/modules/video_capture/linux/pipewire_session.cc +++ b/modules/video_capture/linux/pipewire_session.cc @@ -35,12 +35,18 @@ VideoType PipeWireRawFormatToVideoType(uint32_t id) { return VideoType::kYUY2; case SPA_VIDEO_FORMAT_UYVY: return VideoType::kUYVY; + case SPA_VIDEO_FORMAT_RGB16: + return VideoType::kRGB565; case SPA_VIDEO_FORMAT_RGB: + return VideoType::kBGR24; + case SPA_VIDEO_FORMAT_BGR: return VideoType::kRGB24; case SPA_VIDEO_FORMAT_BGRA: return VideoType::kARGB; case SPA_VIDEO_FORMAT_RGBA: return VideoType::kABGR; + case SPA_VIDEO_FORMAT_ARGB: + return VideoType::kBGRA; default: return VideoType::kUnknown; } diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc index 9ff4fdb9b1..1672b7583f 100644 --- a/modules/video_capture/linux/video_capture_pipewire.cc +++ b/modules/video_capture/linux/video_capture_pipewire.cc @@ -34,10 +34,15 @@ struct { {SPA_VIDEO_FORMAT_YUY2, VideoType::kYUY2}, {SPA_VIDEO_FORMAT_UYVY, VideoType::kUYVY}, // PipeWire is big-endian for the formats, while libyuv is little-endian - // This means that BGRA == ARGB and RGBA == ABGR + // This means that BGRA == ARGB, RGBA == ABGR and similar + // This follows mapping in libcamera PipeWire plugin: + // https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/libcamera/libcamera-utils.cpp {SPA_VIDEO_FORMAT_BGRA, VideoType::kARGB}, {SPA_VIDEO_FORMAT_RGBA, VideoType::kABGR}, - {SPA_VIDEO_FORMAT_RGB, VideoType::kRGB24}, + {SPA_VIDEO_FORMAT_ARGB, VideoType::kBGRA}, + {SPA_VIDEO_FORMAT_RGB, VideoType::kBGR24}, + {SPA_VIDEO_FORMAT_BGR, VideoType::kRGB24}, + {SPA_VIDEO_FORMAT_RGB16, VideoType::kRGB565}, }; VideoType VideoCaptureModulePipeWire::PipeWireRawFormatToVideoType( @@ -302,13 +307,16 @@ void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) { break; case VideoType::kYUY2: case VideoType::kUYVY: + case VideoType::kRGB565: stride = configured_capability_.width * 2; break; case VideoType::kRGB24: + case VideoType::kBGR24: stride = configured_capability_.width * 3; break; case VideoType::kARGB: case VideoType::kABGR: + case VideoType::kBGRA: stride = configured_capability_.width * 4; break; default: