Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -23,6 +24,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 @@ -58,6 +63,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
50 changes: 45 additions & 5 deletions sources/grabber/linux/v4l2/V4L2Grabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,13 @@ namespace
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 },
{ V4L2_PIX_FMT_NV12, PixelFormat::NV12 },
{ V4L2_PIX_FMT_MJPEG, PixelFormat::MJPEG },
{ V4L2_PIX_FMT_P010, PixelFormat::P010 }
{ V4L2_PIX_FMT_P010, PixelFormat::P010 }
};


Expand Down Expand Up @@ -147,7 +148,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)
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::UYVY) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::NV12)
|| (_actualVideoFormat == PixelFormat::P010) || (_actualVideoFormat == PixelFormat::MJPEG))
loadLutFile(PixelFormat::YUYV);
else
Expand Down Expand Up @@ -577,6 +578,28 @@ void V4L2Grabber::enumerateV4L2devices(bool silent)
}
}

if (properties.valid.size() == 0 && devName == "/dev/video0")
{
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 @@ -904,7 +927,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 @@ -918,6 +941,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 @@ -974,6 +1004,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 @@ -1209,10 +1248,11 @@ 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 || _hdrToneMappingEnabled) && !_lutBufferInit)
{
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, true);
}
Expand Down
53 changes: 49 additions & 4 deletions sources/utils/FrameDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,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::P010 && pixelFormat != PixelFormat::MJPEG)
{
Expand All @@ -200,7 +200,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 || pixelFormat == PixelFormat::P010) && lutBuffer == NULL)
{
Error(Logger::getInstance("FrameDecoder"), "Missing LUT table for YUV colorspace");
Expand Down Expand Up @@ -248,6 +248,30 @@ 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 @@ -474,7 +498,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 && pixelFormat != PixelFormat::P010)
{
Expand All @@ -483,7 +507,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 || pixelFormat == PixelFormat::P010) && lutBuffer == NULL)
{
Error(Logger::getInstance("FrameDecoder"), "Missing LUT table for YUV colorspace");
Expand Down Expand Up @@ -522,6 +546,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
6 changes: 3 additions & 3 deletions www/i18n/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1246,10 +1246,10 @@
"option_calibration_intro": "Vyberte typ kalibrace",
"option_calibration_video": "Kalibrace pomocí testovacího videa přehrávaného vaším oblíbeným přehrávačem videa.<br/>Kalibrujeme LUT s ohledem na grabber, přehrávač a váš televizor.",
"option_calibration_classic": "Kalibrace pomocí systému Windows s povoleným režimem HDR a webovým prohlížečem.<br/>Kalibrujeme LUT s ohledem na grabber a váš televizor.",
"video_calibration_overview": "<b>1</b> Musíte nastavit formát videa svého grabberu na MJPEG/YUV/NV12. Jiné formáty nejsou podporovány.<br/><br/><b>2</b> Pokud provádíte kalibraci pomocí Flatbufferů, musíte v jeho nastavení povolit mapování tónů. Podporován je pouze formát videa NV12.</br><br/><b>3</b> Testovací soubory si můžete stáhnout zde: <a href='https://github.com/awawa-dev/awawa- dev.github.io/tree/master/calibration'>odkaz</a>. V přehrávači spusťte přehrávání testovacího souboru. Měli byste to vidět v náhledu videa HyperHDR. Testovací obrazovka musí zabírat celou obrazovku a nesmí být viditelné žádné nadbytečné prvky, jako je nabídka přehrávače.</br><br/><b>4</b> Pro kalibraci byste měli vybrat soubor s ' hdr' v názvu, pokud váš systém nebo přehrávač automaticky nepoužívá mapování tónů SDR na HDR nebo pokud neplánujete kalibrovat signál SDR. V takovém případě, abyste se přizpůsobili takovému scénáři, vyberte soubor s 'sdr' v názvu.</br><br/><b>5</b> Formát YUV420 s omezeným rozsahem poskytuje největší kompatibilitu s průměrem až velmi dobrá kvalita a je nejoblíbenější. Formát YUV444 poskytuje nejlepší kvalitu, ale je vzácné najít materiály zakódované v této podobě.</br><br/><b>6</b> <b>Pokud se kalibrují pomocí Windows 11 (pomocí webového prohlížeče nebo přehrávače videa jako zdroje videa), vypněte funkce, jako je „Noční světlo“, „Automatická správa barev pro aplikace“ a „Auto-HDR“. Neměňte vyvážení barev v ovladači grafiky. Výstup GFX by měl podporovat např. 10 nebo 12 bit RGB v plném rozsahu PC.</b></br><br/><b>7</b> <b>Výpočty jsou velmi intenzivní a zatěžují vaše zařízení! <svg data-src='svg/performance_undervoltage.svg' class='svg4hyperhdr ms-1'></svg></b>Můžete deaktivovat korekci barev LCH, abyste trochu snížili zátěž.",
"video_calibration_overview": "<b>1</b> Musíte nastavit formát videa svého grabberu na MJPEG/YUV/NV12/P010. Jiné formáty nejsou podporovány.<br/><br/><b>2</b> Pokud provádíte kalibraci pomocí Flatbufferů, musíte v jeho nastavení povolit mapování tónů. Podporován je pouze formát videa NV12.</br><br/><b>3</b> Testovací soubory si můžete stáhnout zde: <a href='https://github.com/awawa-dev/awawa- dev.github.io/tree/master/calibration'>odkaz</a>. V přehrávači spusťte přehrávání testovacího souboru. Měli byste to vidět v náhledu videa HyperHDR. Testovací obrazovka musí zabírat celou obrazovku a nesmí být viditelné žádné nadbytečné prvky, jako je nabídka přehrávače.</br><br/><b>4</b> Pro kalibraci byste měli vybrat soubor s ' hdr' v názvu, pokud váš systém nebo přehrávač automaticky nepoužívá mapování tónů SDR na HDR nebo pokud neplánujete kalibrovat signál SDR. V takovém případě, abyste se přizpůsobili takovému scénáři, vyberte soubor s 'sdr' v názvu.</br><br/><b>5</b> Formát YUV420 s omezeným rozsahem poskytuje největší kompatibilitu s průměrem až velmi dobrá kvalita a je nejoblíbenější. Formát YUV444 poskytuje nejlepší kvalitu, ale je vzácné najít materiály zakódované v této podobě.</br><br/><b>6</b> <b>Pokud se kalibrují pomocí Windows 11 (pomocí webového prohlížeče nebo přehrávače videa jako zdroje videa), vypněte funkce, jako je „Noční světlo“, „Automatická správa barev pro aplikace“ a „Auto-HDR“. Neměňte vyvážení barev v ovladači grafiky. Výstup GFX by měl podporovat např. 10 nebo 12 bit RGB v plném rozsahu PC.</b></br><br/><b>7</b> <b>Výpočty jsou velmi intenzivní a zatěžují vaše zařízení! <svg data-src='svg/performance_undervoltage.svg' class='svg4hyperhdr ms-1'></svg></b>Můžete deaktivovat korekci barev LCH, abyste trochu snížili zátěž.",
"chk_calibration_debug": "Ladit",
"flatbuffers_nv12_quarter_of_frame_title": "Čtvrtina rámu pro NV12",
"flatbuffers_nv12_quarter_of_frame_expl": "Kodek NV12 obsahuje čtyřikrát více informací o jasu než o barvě. Tato možnost umožňuje snížit zatížení procesoru snížením výšky a šířky snímku videa o 2, aniž by došlo ke ztrátě informací o barvách.",
"chk_lchCorrection": "Korekce barev LCH",
"grabber_calibration_expl": "Tento nástroj vám umožňuje vytvořit novou kalibrovanou HDR LUT pro váš grabber (nebo externí zdroj flatbufferů) co nejblíže skutečným vstupním barvám.<br/>Potřebujete zdroj videa HDR10, který dokáže zobrazit tuto webovou stránku, například: Windows 10 s povoleným HDR ve vlastnostech grafického ovladače.<br/>Během kalibrace může obrazovka blikat. Tento proces obvykle trvá přibližně několik minut na počítači Intel 7 Windows (v závislosti na zdrojích hostitelského procesoru a snímkové rychlosti zachycování videa).<br/><b>Výpočty jsou velmi intenzivní a zatěžují vaše zařízení <svg data- src='svg/performance_undervoltage.svg' class='svg4hyperhdr ms-1'></svg></b>Můžete deaktivovat korekci barev LCH, abyste trochu snížili zátěž<br/>Postup můžete sledovat v protokolech HyperHDR pomocí prohlížeče z jiného zařízení.<br/><br/><br/><b>1</b> Pokud je vše správně připojeno, měla by se tato stránka zobrazit na televizní obrazovce (jako obsah HDR) a živý náhled v HyperHDR (snímáno grabberem).</br><b>2</b> Absolutní minimální rozlišení snímání je 1280x720 (toto ověříme). Doporučeno je 1920x1080 YUV/NV12. Poměr stran 1920/1080 musí být zachován.<br/><b>3</b> Pokud je povolen, musíte ve vlastnostech grabberu deaktivovat 'Režim čtvrtiny snímku'.<br/><b>4</b> Vy musí nastavit formát videa grabberu na MJPEG/YUV/NV12.<br/><b>5</b> Před spuštěním procesu přepněte svůj WWW prohlížeč do režimu celé obrazovky (klávesa F11, ověříme to) .</br><b>6</b> <b>Pokud provádíte kalibraci pomocí Windows 11, vypněte funkce, jako je „Noční světlo“, „Automatická správa barev pro aplikace“ a „Automatické HDR“. Neměňte vyvážení barev v ovladači grafiky. Výstup GFX by měl podporovat např. 10 nebo 12 bit RGB v plném rozsahu PC.</b><br/><br/>Po dokončení kalibrace bude v domovském adresáři uživatele HyperHDR vytvořen nový soubor tabulky LUT (lut_lin_tables.3d) a je okamžitě připraven použít, když pouze povolíte mapování tónů HDR. Podrobnosti naleznete v protokolech HyperHDR."
}
"grabber_calibration_expl": "Tento nástroj vám umožňuje vytvořit novou kalibrovanou HDR LUT pro váš grabber (nebo externí zdroj flatbufferů) co nejblíže skutečným vstupním barvám.<br/>Potřebujete zdroj videa HDR10, který dokáže zobrazit tuto webovou stránku, například: Windows 10 s povoleným HDR ve vlastnostech grafického ovladače.<br/>Během kalibrace může obrazovka blikat. Tento proces obvykle trvá přibližně několik minut na počítači Intel 7 Windows (v závislosti na zdrojích hostitelského procesoru a snímkové rychlosti zachycování videa).<br/><b>Výpočty jsou velmi intenzivní a zatěžují vaše zařízení <svg data- src='svg/performance_undervoltage.svg' class='svg4hyperhdr ms-1'></svg></b>Můžete deaktivovat korekci barev LCH, abyste trochu snížili zátěž<br/>Postup můžete sledovat v protokolech HyperHDR pomocí prohlížeče z jiného zařízení.<br/><br/><br/><b>1</b> Pokud je vše správně připojeno, měla by se tato stránka zobrazit na televizní obrazovce (jako obsah HDR) a živý náhled v HyperHDR (snímáno grabberem).</br><b>2</b> Absolutní minimální rozlišení snímání je 1280x720 (toto ověříme). Doporučeno je 1920x1080 YUV/NV12. Poměr stran 1920/1080 musí být zachován.<br/><b>3</b> Pokud je povolen, musíte ve vlastnostech grabberu deaktivovat 'Režim čtvrtiny snímku'.<br/><b>4</b> Vy musí nastavit formát videa grabberu na MJPEG/YUV/NV12/P010.<br/><b>5</b> Před spuštěním procesu přepněte svůj WWW prohlížeč do režimu celé obrazovky (klávesa F11, ověříme to) .</br><b>6</b> <b>Pokud provádíte kalibraci pomocí Windows 11, vypněte funkce, jako je „Noční světlo“, „Automatická správa barev pro aplikace“ a „Automatické HDR“. Neměňte vyvážení barev v ovladači grafiky. Výstup GFX by měl podporovat např. 10 nebo 12 bit RGB v plném rozsahu PC.</b><br/><br/>Po dokončení kalibrace bude v domovském adresáři uživatele HyperHDR vytvořen nový soubor tabulky LUT (lut_lin_tables.3d) a je okamžitě připraven použít, když pouze povolíte mapování tónů HDR. Podrobnosti naleznete v protokolech HyperHDR."
}
Loading
Loading