Add YuvSnapshot support
Stream with YCbCr_420_888 format may be treated as different
usage type on different platforms.
Add YuvSnapshot support. Then pipeline handler can decide
the detail pipe to run.
Treat YCbCr_420_888 as STILL for usage GRALLOC_USAGE_PRIVATE_1.
Signed-off-by: Qingwu Zhang <qingwu.zhang@intel.corp-partner.google.com>
Merged-In: Iadc7aad854242a0879f9be14475b96e026828a33
Change-Id: Iadc7aad854242a0879f9be14475b96e026828a33
diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
index 2bb3cd9..7927e46 100644
--- a/include/libcamera/stream.h
+++ b/include/libcamera/stream.h
@@ -69,6 +69,7 @@
StillCapture,
VideoRecording,
Viewfinder,
+ YuvSnapshot,
};
std::ostream &operator<<(std::ostream &out, StreamRole role);
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 8111d53..d4697db 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -214,6 +214,13 @@
return (GRALLOC_USAGE_HW_VIDEO_ENCODER & stream->usage);
}
+// Vendor extended buffer usage bit for the HAL to identify the still capture YUV stream
+#define IS_STILL_USAGE(usage) (((usage)&GRALLOC_USAGE_PRIVATE_1) == GRALLOC_USAGE_PRIVATE_1)
+bool hasStillCaptureFlag(camera3_stream_t *stream)
+{
+ return (IS_STILL_USAGE(stream->usage));
+}
+
bool isYuvSnapshotStream(camera3_stream_t *stream)
{
return (!isVideoStream(stream) && !isPreviewStream(stream) &&
@@ -374,9 +381,12 @@
if (isJpegStream(stream)) {
continue;
- } else if (isYuvSnapshotStream(stream)) {
+ } else if (hasStillCaptureFlag(stream)) {
streamConfig.streams = { { stream, CameraStream::Type::Direct } };
streamConfig.config.role = StreamRole::StillCapture;
+ } else if (isYuvSnapshotStream(stream)) {
+ streamConfig.streams = { { stream, CameraStream::Type::Direct } };
+ streamConfig.config.role = StreamRole::YuvSnapshot;
} else if (isPreviewStream(stream)) {
streamConfig.streams = { { stream, CameraStream::Type::Direct } };
streamConfig.config.role = StreamRole::Viewfinder;
diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
index 9bdfff0..f6e87f8 100644
--- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
+++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
@@ -765,6 +765,7 @@
switch (role) {
case StreamRole::StillCapture:
+ case StreamRole::YuvSnapshot:
case StreamRole::Viewfinder:
case StreamRole::VideoRecording: {
Size size = role == StreamRole::StillCapture
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index a81c817..3ed3be0 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -407,6 +407,7 @@
Size size;
switch (role) {
+ case StreamRole::YuvSnapshot:
case StreamRole::StillCapture:
/*
* Use as default full-frame configuration a value
diff --git a/src/libcamera/pipeline/mtkisp7/mtkisp7.cpp b/src/libcamera/pipeline/mtkisp7/mtkisp7.cpp
index 6f25d8f..720affa 100644
--- a/src/libcamera/pipeline/mtkisp7/mtkisp7.cpp
+++ b/src/libcamera/pipeline/mtkisp7/mtkisp7.cpp
@@ -484,6 +484,7 @@
}
cfg.setStream(const_cast<Stream *>(vidStreams[videoCnt++]));
break;
+ case StreamRole::YuvSnapshot:
case StreamRole::StillCapture:
if (stillCnt >= 2) {
LOG(MtkISP7, Error)
@@ -562,6 +563,7 @@
switch (role) {
case StreamRole::StillCapture:
+ case StreamRole::YuvSnapshot:
cfg.setStream(&data->still1Stream_);
cfg.role = StreamRole::StillCapture;
break;
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 6efa79f..89b3b6f 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -638,6 +638,7 @@
Size size;
switch (role) {
+ case StreamRole::YuvSnapshot:
case StreamRole::StillCapture:
/* JPEG encoders typically expect sYCC. */
if (!colorSpace)
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
index fad710a..a6bfce2 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
@@ -398,6 +398,7 @@
bufferCount = 2;
break;
+ case StreamRole::YuvSnapshot:
case StreamRole::StillCapture:
fmts = data->ispFormats();
pixelFormat = formats::YUV420;
diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp
index 33d8ce4..087af60 100644
--- a/src/libcamera/pipeline/virtual/virtual.cpp
+++ b/src/libcamera/pipeline/virtual/virtual.cpp
@@ -221,6 +221,7 @@
for (const StreamRole role : roles) {
switch (role) {
case StreamRole::StillCapture:
+ case StreamRole::YuvSnapshot:
case StreamRole::VideoRecording:
case StreamRole::Viewfinder:
break;
diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp
index 1981655..c415813 100644
--- a/src/libcamera/stream.cpp
+++ b/src/libcamera/stream.cpp
@@ -416,6 +416,9 @@
* The stream is intended to capture video for the purpose of display on the
* local screen. Trade-offs between quality and usage of system resources are
* acceptable.
+ * \var YuvSnapshot
+ * The stream is intended to capture high-resolution, high-quality YUV images
+ * with low frame rate.
*/
/**
@@ -426,11 +429,12 @@
*/
std::ostream &operator<<(std::ostream &out, StreamRole role)
{
- static constexpr std::array<const char *, 4> names{
+ static constexpr std::array<const char *, 5> names{
"Raw",
"StillCapture",
"VideoRecording",
"Viewfinder",
+ "YuvSnapshot",
};
out << names[static_cast<std::underlying_type_t<StreamRole>>(role)];