Skip to content

Commit

Permalink
Fix for "unicam image" RPi HDMI capture card and others
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev committed Jun 29, 2024
1 parent 12ed1c3 commit ae364ae
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 7 deletions.
9 changes: 9 additions & 0 deletions include/utils/PixelFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

enum class PixelFormat {
YUYV,
UYVY,
RGB24,
XRGB,
I420,
Expand All @@ -22,6 +23,10 @@ inline PixelFormat parsePixelFormat(const QString& pixelFormat)
{
return PixelFormat::YUYV;
}
else if (format.compare("uyvy") == 0)
{
return PixelFormat::UYVY;
}
else if (format.compare("rgb24") == 0)
{
return PixelFormat::RGB24;
Expand Down Expand Up @@ -53,6 +58,10 @@ inline QString pixelFormatToString(const PixelFormat& pixelFormat)
{
return "yuyv";
}
else if (pixelFormat == PixelFormat::UYVY)
{
return "uyvy";
}
else if (pixelFormat == PixelFormat::RGB24)
{
return "rgb24";
Expand Down
45 changes: 42 additions & 3 deletions sources/grabber/v4l2/V4L2Grabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
static const V4L2Grabber::HyperHdrFormat supportedFormats[] =
{
{ V4L2_PIX_FMT_YUYV, PixelFormat::YUYV },
{ V4L2_PIX_FMT_UYVY, PixelFormat::UYVY },
{ V4L2_PIX_FMT_XRGB32, PixelFormat::XRGB },
{ V4L2_PIX_FMT_RGB24, PixelFormat::RGB24 },
{ V4L2_PIX_FMT_YUV420, PixelFormat::I420 },
Expand Down Expand Up @@ -129,7 +130,7 @@ void V4L2Grabber::setHdrToneMappingEnabled(int mode)
{
Debug(_log, "setHdrToneMappingMode replacing LUT and restarting");
_V4L2WorkerManager.Stop();
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::NV12) || (_actualVideoFormat == PixelFormat::MJPEG))
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::UYVY) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::NV12) || (_actualVideoFormat == PixelFormat::MJPEG))
loadLutFile(PixelFormat::YUYV);
else
loadLutFile(PixelFormat::RGB24);
Expand Down Expand Up @@ -558,6 +559,28 @@ void V4L2Grabber::enumerateV4L2devices(bool silent)
}
}

if (properties.valid.size() == 0)
{
DevicePropertiesItem di;
di.x = fmt.fmt.pix.width;
di.y = fmt.fmt.pix.height;
di.fps = 0;
di.pf = identifyFormat(fmt.fmt.pix.pixelformat);
di.v4l2PixelFormat = fmt.fmt.pix.pixelformat;
di.input = inputIndex;

QString pixelFormat = pixelFormatToString(di.pf);
if (di.pf == PixelFormat::NO_CHANGE)
{
Debug(_log, "%s %d x %d @ %d fps %s (unsupported)", QSTRING_CSTR(properties.name), di.x, di.y, di.fps, QSTRING_CSTR(pixelFormat));
}
else
{
Debug(_log, "%s %d x %d @ %d fps %s, input = %i (seems supported, device not fully compatible with v4l2 grabber model, frame rate is unknown)", QSTRING_CSTR(properties.name), di.x, di.y, di.fps, QSTRING_CSTR(pixelFormat), di.input);
properties.valid.append(di);
}
}

_deviceProperties.insert(realName, properties);

if (!silent)
Expand Down Expand Up @@ -885,7 +908,7 @@ bool V4L2Grabber::init_device(QString selectedDeviceName, DevicePropertiesItem p

streamparms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
// Check that the driver knows about framerate get/set
if (xioctl(VIDIOC_G_PARM, &streamparms) >= 0)
if (props.fps > 0 && xioctl(VIDIOC_G_PARM, &streamparms) >= 0)
{
// Check if the device is able to accept a capture framerate set.
if (streamparms.parm.capture.capability == V4L2_CAP_TIMEPERFRAME)
Expand All @@ -899,6 +922,13 @@ bool V4L2Grabber::init_device(QString selectedDeviceName, DevicePropertiesItem p
Info(_log, "Set framerate to %d FPS", streamparms.parm.capture.timeperframe.denominator);
}
}
else
{
if (props.fps == 0)
Warning(_log, "The device doesnt report frame rate settings");
else
Error(_log, "The device doesnt support VIDIOC_G_PARM for frame rate settings");
}

// set the line length
_lineLength = fmt.fmt.pix.bytesperline;
Expand Down Expand Up @@ -955,6 +985,15 @@ bool V4L2Grabber::init_device(QString selectedDeviceName, DevicePropertiesItem p
}
break;

case V4L2_PIX_FMT_UYVY:
{
loadLutFile(PixelFormat::YUYV);
_actualVideoFormat = PixelFormat::UYVY;
_frameByteSize = props.x * props.y * 2;
Info(_log, "Video pixel format is set to: UYVY");
}
break;

case V4L2_PIX_FMT_XRGB32:
{
loadLutFile(PixelFormat::RGB24);
Expand Down Expand Up @@ -1180,7 +1219,7 @@ bool V4L2Grabber::process_image(v4l2_buffer* buf, const void* frameImageBuffer,
{
V4L2Worker* _workerThread = _V4L2WorkerManager.workers[i];

if ((_actualVideoFormat == PixelFormat::YUYV || _actualVideoFormat == PixelFormat::I420 ||
if ((_actualVideoFormat == PixelFormat::YUYV || _actualVideoFormat == PixelFormat::UYVY || _actualVideoFormat == PixelFormat::I420 ||
_actualVideoFormat == PixelFormat::NV12) && !_lutBufferInit)
{
loadLutFile();
Expand Down
54 changes: 50 additions & 4 deletions sources/utils/FrameDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void FrameDecoder::processImage(
uint8_t buffer[8];

// validate format
if (pixelFormat != PixelFormat::YUYV &&
if (pixelFormat != PixelFormat::YUYV && pixelFormat != PixelFormat::UYVY &&
pixelFormat != PixelFormat::XRGB && pixelFormat != PixelFormat::RGB24 &&
pixelFormat != PixelFormat::I420 && pixelFormat != PixelFormat::NV12 && pixelFormat != PixelFormat::MJPEG)
{
Expand All @@ -56,7 +56,7 @@ void FrameDecoder::processImage(
}

// validate format LUT
if ((pixelFormat == PixelFormat::YUYV || pixelFormat == PixelFormat::I420 || pixelFormat == PixelFormat::MJPEG ||
if ((pixelFormat == PixelFormat::YUYV || pixelFormat == PixelFormat::UYVY || pixelFormat == PixelFormat::I420 || pixelFormat == PixelFormat::MJPEG ||
pixelFormat == PixelFormat::NV12) && lutBuffer == NULL)
{
Error(Logger::getInstance("FrameDecoder"), "Missing LUT table for YUV colorspace");
Expand Down Expand Up @@ -111,6 +111,31 @@ void FrameDecoder::processImage(
return;
}

if (pixelFormat == PixelFormat::UYVY)
{
for (int yDest = 0, ySource = _cropTop; yDest < outputHeight; ++ySource, ++yDest)
{
uint8_t* currentDest = destMemory + ((uint64_t)destLineSize) * yDest;
uint8_t* endDest = currentDest + destLineSize;
uint8_t* currentSource = (uint8_t*)data + (((uint64_t)lineLength * ySource) + (((uint64_t)_cropLeft) << 1));

while (currentDest < endDest)
{
*((uint32_t*)&buffer) = *((uint32_t*)currentSource);

ind_lutd = LUT_INDEX(buffer[1], buffer[0], buffer[2]);
ind_lutd2 = LUT_INDEX(buffer[3], buffer[0], buffer[2]);

*((uint32_t*)currentDest) = *((uint32_t*)(&lutBuffer[ind_lutd]));
currentDest += 3;
*((uint32_t*)currentDest) = *((uint32_t*)(&lutBuffer[ind_lutd2]));
currentDest += 3;
currentSource += 4;
}
}
return;
}


if (pixelFormat == PixelFormat::RGB24)
{
Expand Down Expand Up @@ -285,7 +310,7 @@ void FrameDecoder::processQImage(
uint8_t buffer[8];

// validate format
if (pixelFormat != PixelFormat::YUYV &&
if (pixelFormat != PixelFormat::YUYV && pixelFormat != PixelFormat::UYVY &&
pixelFormat != PixelFormat::XRGB && pixelFormat != PixelFormat::RGB24 &&
pixelFormat != PixelFormat::I420 && pixelFormat != PixelFormat::NV12)
{
Expand All @@ -294,7 +319,7 @@ void FrameDecoder::processQImage(
}

// validate format LUT
if ((pixelFormat == PixelFormat::YUYV || pixelFormat == PixelFormat::I420 ||
if ((pixelFormat == PixelFormat::YUYV || pixelFormat == PixelFormat::UYVY || pixelFormat == PixelFormat::I420 ||
pixelFormat == PixelFormat::NV12) && lutBuffer == NULL)
{
Error(Logger::getInstance("FrameDecoder"), "Missing LUT table for YUV colorspace");
Expand Down Expand Up @@ -333,6 +358,27 @@ void FrameDecoder::processQImage(
return;
}

if (pixelFormat == PixelFormat::UYVY)
{
for (int yDest = 0, ySource = 0; yDest < outputHeight; ySource += 2, ++yDest)
{
uint8_t* currentDest = destMemory + ((uint64_t)destLineSize) * yDest;
uint8_t* endDest = currentDest + destLineSize;
uint8_t* currentSource = (uint8_t*)data + (((uint64_t)lineLength * ySource));

while (currentDest < endDest)
{
*((uint32_t*)&buffer) = *((uint32_t*)currentSource);

ind_lutd = LUT_INDEX(buffer[1], buffer[0], buffer[2]);

*((uint32_t*)currentDest) = *((uint32_t*)(&lutBuffer[ind_lutd]));
currentDest += 3;
currentSource += 4;
}
}
return;
}

if (pixelFormat == PixelFormat::RGB24)
{
Expand Down

0 comments on commit ae364ae

Please sign in to comment.