Use RGB24 format instead of BGR32
BGR32 mode is in RPi3's camera has a RB color swapping issue. This CL
makes to use stable RGB24 mode instead to avoid the problem without
causing any quality regression.
Bug: 69075512
Test: RB color swapping problem is gone on preview, recording and stil.
Exempt-From-Owner-Approval: HAL is owned by Things team.
Change-Id: I109363c0f68cec45f92e739a978f554e70032151
diff --git a/modules/camera/3_4/README.md b/modules/camera/3_4/README.md
index 73d0c13..30f36d7 100644
--- a/modules/camera/3_4/README.md
+++ b/modules/camera/3_4/README.md
@@ -28,7 +28,7 @@
Devices and cameras wishing to use this HAL must meet
the following requirements:
-* The camera must support BGR32, YUV420, and JPEG formats.
+* The camera must support RGB24, YUV420, and JPEG formats.
* The gralloc and other graphics modules used by the device must use
`HAL_PIXEL_FORMAT_RGBA_8888` as the `HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED`
@@ -146,6 +146,3 @@
* A variety of features are unimplemented: High speed capture,
flash torch mode, hotplugging/unplugging.
-* The HAL uses BGR for RGBA. Again, the HAL was designed for the Raspberry Pi
-camera, which doesn't support RGB, but RGB is a common default format for
-graphics stacks.
diff --git a/modules/camera/3_4/stream_format.cpp b/modules/camera/3_4/stream_format.cpp
index c85c26b..70900ab 100644
--- a/modules/camera/3_4/stream_format.cpp
+++ b/modules/camera/3_4/stream_format.cpp
@@ -57,7 +57,7 @@
case V4L2_PIX_FMT_JPEG:
return kFormatCategoryStalling;
case V4L2_PIX_FMT_YUV420: // Fall through.
- case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_RGB24:
return kFormatCategoryNonStalling;
default:
// Note: currently no supported RAW formats.
@@ -87,7 +87,7 @@
case V4L2_PIX_FMT_YUV420:
hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
break;
- case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_RGB24:
hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888;
break;
default:
@@ -106,7 +106,7 @@
case HAL_PIXEL_FORMAT_RGBA_8888:
// Should be RGB32, but RPi doesn't support that.
// For now we accept that the colors will be off.
- v4l2_pixel_format = V4L2_PIX_FMT_BGR32;
+ v4l2_pixel_format = V4L2_PIX_FMT_RGB24;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_888:
v4l2_pixel_format = V4L2_PIX_FMT_YUV420;
diff --git a/modules/camera/3_4/v4l2_gralloc.cpp b/modules/camera/3_4/v4l2_gralloc.cpp
index 7da3c4e..2fcef35 100644
--- a/modules/camera/3_4/v4l2_gralloc.cpp
+++ b/modules/camera/3_4/v4l2_gralloc.cpp
@@ -146,6 +146,7 @@
return ret;
}
break;
+ case V4L2_PIX_FMT_RGB24: // Fall-through.
case V4L2_PIX_FMT_BGR32: // Fall-through.
case V4L2_PIX_FMT_RGB32:
// RGB formats have nice agreed upon representation. Unless using android
@@ -204,6 +205,19 @@
const camera3_stream_buffer_t* camera_buffer = buffer_data->camera_buffer;
const buffer_handle_t buffer = *camera_buffer->buffer;
+ if (StreamFormat::HalToV4L2PixelFormat(camera_buffer->stream->format) == V4L2_PIX_FMT_RGB24) {
+ // Convert RGB24 to RGB32.
+ size_t rgb_size = camera_buffer->stream->width * camera_buffer->stream->height;
+ uint8_t* tail_rgb24 = (uint8_t*)data + 3 * rgb_size - 1;
+ uint8_t* tail_rgb32 = (uint8_t*)data + 4 * rgb_size - 1;
+ for (int i = 0; i < rgb_size; i++) {
+ *(tail_rgb32--) = 0xff;
+ *(tail_rgb32--) = *(tail_rgb24--);
+ *(tail_rgb32--) = *(tail_rgb24--);
+ *(tail_rgb32--) = *(tail_rgb24--);
+ }
+ }
+
// Check for transform.
if (buffer_data->transform_dest) {
HAL_LOGV("Transforming V4L2 YUV to gralloc YUV.");