Skip to content

Commit 460b36b

Browse files
committed
add support for YUV420 pixel format conversion in LibCameraWorker
1 parent 334b749 commit 460b36b

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

src/libcameracamera.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,36 @@ QImage LibCameraWorker::convertBufferToImage(
533533
image.setPixel(x + 1, y, qRgb(r1, g1, b1));
534534
}
535535
}
536+
} else if (cfg.pixelFormat == libcamera::formats::YUV420) {
537+
// YUV420 planar format (I420)
538+
unsigned int width = cfg.size.width;
539+
unsigned int height = cfg.size.height;
540+
image = QImage(width, height, QImage::Format_RGB888);
541+
542+
const uint8_t *src = static_cast<const uint8_t *>(memory);
543+
const uint8_t *yPlane = src;
544+
const uint8_t *uPlane = src + width * height;
545+
const uint8_t *vPlane = uPlane + (width * height / 4);
546+
547+
for (unsigned int y = 0; y < height; y++) {
548+
for (unsigned int x = 0; x < width; x++) {
549+
int yVal = yPlane[y * width + x];
550+
int uVal = uPlane[(y / 2) * (width / 2) + (x / 2)];
551+
int vVal = vPlane[(y / 2) * (width / 2) + (x / 2)];
552+
553+
auto clamp = [](int val) { return std::max(0, std::min(255, val)); };
554+
555+
int c = yVal - 16;
556+
int d = uVal - 128;
557+
int e = vVal - 128;
558+
559+
int r = clamp((298 * c + 409 * e + 128) >> 8);
560+
int g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
561+
int b = clamp((298 * c + 516 * d + 128) >> 8);
562+
563+
image.setPixel(x, y, qRgb(r, g, b));
564+
}
565+
}
536566
} else {
537567
qDebug() << "[ERROR] Unsupported pixel format:"
538568
<< QString::fromStdString(cfg.pixelFormat.toString());
@@ -566,10 +596,14 @@ bool LibCameraWorker::configureCamera(libcamera::StreamRole role) {
566596
mCurrentWidth = cfg.size.width;
567597
mCurrentHeight = cfg.size.height;
568598
} else if (role == StreamRole::StillCapture) {
569-
cfg.pixelFormat = formats::MJPEG;
599+
// Don't force MJPEG - use the camera's default format for still capture
600+
// Pi cameras typically use YUV420 which we'll convert
601+
// Only set buffer count, keep default format and resolution
570602
cfg.bufferCount = 1;
571603
mCurrentWidth = cfg.size.width;
572604
mCurrentHeight = cfg.size.height;
605+
qDebug() << "[INFO] Still capture default format:" << QString::fromStdString(cfg.pixelFormat.toString());
606+
qDebug() << "[INFO] Still capture default size:" << cfg.size.width << "x" << cfg.size.height;
573607
}
574608

575609
CameraConfiguration::Status status = mConfig->validate();

0 commit comments

Comments
 (0)