Skip to content

Commit a0c3ee6

Browse files
committed
autoselect pixel format
1 parent af6cfe5 commit a0c3ee6

1 file changed

Lines changed: 43 additions & 32 deletions

File tree

src/libcameracamera.cpp

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@
33
#include <QThread>
44
#include <QTimer>
55
#include <cerrno>
6-
#include <chrono>
76
#include <cstring>
8-
#include <iomanip>
9-
#include <iostream>
107
#include <libcamera/formats.h>
118
#include <libcamera/framebuffer_allocator.h>
129
#include <qvideoframe.h>
1310
#include <sys/mman.h>
14-
#include <thread>
1511

1612
using namespace libcamera;
1713

@@ -540,48 +536,33 @@ QImage LibCameraWorker::convertBufferToImage(
540536
}
541537
}
542538
} else if (cfg.pixelFormat == libcamera::formats::YUV420) {
543-
// YUV420 planar format
539+
// YUV420 planar format (I420)
544540
unsigned int width = cfg.size.width;
545541
unsigned int height = cfg.size.height;
546-
unsigned int stride = cfg.stride;
547-
548-
// Use Format_RGB888 - byte order is R, G, B
549542
image = QImage(width, height, QImage::Format_RGB888);
550543

551544
const uint8_t *src = static_cast<const uint8_t *>(memory);
552545
const uint8_t *yPlane = src;
553-
554-
// Try standard I420 order first: Y, U, V
555-
const uint8_t *uPlane = src + stride * height;
556-
const uint8_t *vPlane = uPlane + (stride / 2) * (height / 2);
557-
558-
qDebug() << "[DEBUG] YUV420 conversion: width=" << width << "height=" << height << "stride=" << stride;
546+
const uint8_t *uPlane = src + width * height;
547+
const uint8_t *vPlane = uPlane + (width * height / 4);
559548

560549
for (unsigned int y = 0; y < height; y++) {
561-
uint8_t *destRow = image.scanLine(y);
562550
for (unsigned int x = 0; x < width; x++) {
563-
int yVal = yPlane[y * stride + x];
564-
int uVal = uPlane[(y / 2) * (stride / 2) + (x / 2)];
565-
int vVal = vPlane[(y / 2) * (stride / 2) + (x / 2)];
551+
int yVal = yPlane[y * width + x];
552+
int uVal = uPlane[(y / 2) * (width / 2) + (x / 2)];
553+
int vVal = vPlane[(y / 2) * (width / 2) + (x / 2)];
554+
555+
auto clamp = [](int val) { return std::max(0, std::min(255, val)); };
566556

567-
// YUV to RGB conversion (BT.601)
568557
int c = yVal - 16;
569558
int d = uVal - 128;
570559
int e = vVal - 128;
571560

572-
int r = (298 * c + 409 * e + 128) >> 8;
573-
int g = (298 * c - 100 * d - 208 * e + 128) >> 8;
574-
int b = (298 * c + 516 * d + 128) >> 8;
575-
576-
// Clamp values
577-
r = r < 0 ? 0 : (r > 255 ? 255 : r);
578-
g = g < 0 ? 0 : (g > 255 ? 255 : g);
579-
b = b < 0 ? 0 : (b > 255 ? 255 : b);
561+
int r = clamp((298 * c + 409 * e + 128) >> 8);
562+
int g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
563+
int b = clamp((298 * c + 516 * d + 128) >> 8);
580564

581-
// RGB888 format: B at offset 0, G at offset 1, R at offset 2
582-
destRow[x * 3 + 0] = static_cast<uint8_t>(b);
583-
destRow[x * 3 + 1] = static_cast<uint8_t>(g);
584-
destRow[x * 3 + 2] = static_cast<uint8_t>(r);
565+
image.setPixel(x, y, qRgb(r, g, b));
585566
}
586567
}
587568

@@ -612,7 +593,37 @@ bool LibCameraWorker::configureCamera(libcamera::StreamRole role) {
612593
unsigned int defaultHeight = cfg.size.height;
613594
float aspectRatio = static_cast<float>(defaultWidth) / defaultHeight;
614595

615-
cfg.pixelFormat = formats::RGB888;
596+
std::vector<PixelFormat> pixelFormats = cfg.formats().pixelformats();
597+
// Search for the best available pixel format in order of preference
598+
PixelFormat selectedFormat = formats::RGB888; // fallback
599+
bool formatFound = false;
600+
601+
// Priority order: BGR888, RGB888, YUYV, MJPEG, YUV420
602+
std::vector<PixelFormat> preferredFormats = {
603+
formats::BGR888,
604+
formats::RGB888,
605+
formats::YUYV,
606+
formats::MJPEG,
607+
formats::YUV420
608+
};
609+
610+
for (const auto &preferred : preferredFormats) {
611+
for (const auto &available : pixelFormats) {
612+
if (available == preferred) {
613+
selectedFormat = preferred;
614+
formatFound = true;
615+
qDebug() << "[INFO] Selected pixel format:" << QString::fromStdString(selectedFormat.toString());
616+
break;
617+
}
618+
}
619+
if (formatFound) break;
620+
}
621+
622+
if (!formatFound) {
623+
qDebug() << "[WARNING] None of the preferred formats available, using default";
624+
}
625+
626+
cfg.pixelFormat = selectedFormat;
616627
cfg.size.width = 640;
617628
cfg.size.height = static_cast<unsigned int>(640.0f / aspectRatio);
618629
cfg.bufferCount = 4;

0 commit comments

Comments
 (0)