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
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
- Automatic tone mapping (#998), HyperHDR v21
- Add Ubuntu 24.10 and Fedora 41 (#1001), HyperHDR v21
- Add support for "unicam image" RPi HDMI capture card and UYVY format (#889), HyperHDR v21
- Breaking change: remove LUT from installer and create it dynamically (#994), HyperHDR v21
- Fix macOS 15 dark theme menu icons (#988), HyperHDR v21
- Add P010 HDR10 video format support (2024-11-24) (#968), HyperHDR v21
- DirectX multi-monitor support (#966), HyperHDR v21
- macOS 15 sequoia: migrate to ScreenCaptureKit (#984), HyperHDR v21
- Add Skydimo "support" (#985), HyperHDR v21
- New LUT calibration based on mp4 test videos (part I) (#896), HyperHDR v21
- feat: updated rpi_ws281x submodule, thanks @andreasvikke (#974), HyperHDR v21
- DX grabber: stick to user specified device selection (#961), HyperHDR v21
- Fix LED colors adjustments by configuration name (#956), HyperHDR v21
- Add autoresume feature for the macOS software grabber (#879), HyperHDR v21
- Add NV12 image format support for flatbuffers (#920), HyperHDR v21
- Update language file's Thanks @AstaRom (#883, #923, #998), HyperHDR v21
- Update flatbuffers to v24.3.25 (#875), HyperHDR v21
- Add cache_cleaner for Github Action (#910), HyperHDR v21
- New build.sh script for the HyperHDR build process (#904), HyperHDR v21
- Remove Alsa libs from CMake recipe, HyperHDR v21
- Remove more unnecessary libraries from installers, HyperHDR v21
- Remove libasound from installers, HyperHDR v21
- Fix restoring calibration settings (#874), HyperHDR v21
- Reorganize HyperHDR libs (#887), HyperHDR v21
- Fix macOS image alignment (#838), HyperHDR v21
- Remove hyperhdr-remote app. Reason: #856, HyperHDR v21
- Refactoring of the FlatBuffers client and server (#880), HyperHDR v21
- Remove mbedtls. Use OpenSSL (#877), HyperHDR v21
- Removal of QT SQL. Migrate to the SQLite library. (#872), HyperHDR v21
- New smoothing option for sound effects, fix ArchLinux installer, refactoring of the smoothing module and music effects (#871), HyperHDR v21
- Removal of QT D-Bus, switch to sdbus-cpp (#864), HyperHDR v21
- Dependency reductions: removal of heavy QT Gui lib (#861), HyperHDR v21
- Fix DirectX capturing after new Systray changes, HyperHDR v21
- New independed systray. Dependency reductions thanks to removal of QWidget (#852), HyperHDR v21
- Fix: lut calibration for grabberless builds (#840), HyperHDR v21
- Fix: close LED device on correct Thread (#803), HyperHDR v21
- Fedora uses xz as the package name, not xz-utils #771 Thanks @hsmalley (v20 beta2 🆕)
- Fix LUT loading bug to reduce memory usage by 96MB #766 (v20 beta2 🆕)
- Fix background music effect #761 (v20 beta2 🆕)
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ Open source ambient lighting implementation for television and music sets based
* Support for USB grabbers under Linux, Windows 10, macOS
* Pipewire/Portal hardware-accelerated screen capturer for Linux/Wayland
* DirectX screen grabber with pixel and vertex shader processing acceleration for Windows 10/11
* DirectX screen grabber supports native Windows HDR modes like DXGI_FORMAT_R16G16B16A16_FLOAT
* DirectX screen grabber supports native Windows HDR modes like DXGI_FORMAT_R16G16B16A16_FLOAT and multi-monitor ( :new: HyperHDR v21)
* Dynamic video cache buffers. Now Rpi can process even 1080p120 NV12 stream without any size decimation
* Built-in audio visualization effects using **spectrum analysis**
* MQTT support for IoT
* Entertainment API v2: per-channel support for Philips Gradient Strip and others
* Automatic LUT calibration detects grabber model specific properties for the best quality of HDR/SDR
* Automatic LUT calibration detects grabber model specific properties for the best quality of HDR/SDR using MP4 test files ( :new: HyperHDR v21)
* Optimized multi-instances. You can use for example your TV LED strip and multiple WLED or Philips Hue light sources.
* Built-in latency benchmark for USB grabbers
* support for high-quality P010 video format ( :new: HyperHDR v21)
* easy LED strip geometry editing process, automatic or manual with mouse and context menu per single LED
* Automatic signal detection with smart learning capability for USB grabbers
* SK6812 RGBW: advanced calibration of the white color channel for [HyperSerialEsp8266](https://github.com/awawa-dev/HyperSerialEsp8266), [HyperSerialESP32](https://github.com/awawa-dev/HyperSerialESP32), [HyperSPI](https://github.com/awawa-dev/HyperSPI), [HyperSerialPico](https://github.com/awawa-dev/HyperSerialPico)
Expand Down
2 changes: 1 addition & 1 deletion cmake/packages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ endif()
# OSX dmg generator
if ( APPLE )
SET ( CPACK_GENERATOR "DragNDrop")
SET ( CPACK_DMG_FORMAT "UDBZ" )
SET ( CPACK_DMG_FORMAT "ULMO" )

unset(CPACK_PACKAGE_ICON)
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/osx/Hyperhdr.icns")
Expand Down
83 changes: 83 additions & 0 deletions include/base/AutomaticToneMapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* AutomaticToneMapping.h
*
* MIT License
*
* Copyright (c) 2020-2024 awawa-dev
*
* Project homesite: https://github.com/awawa-dev/HyperHDR
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#pragma once

#ifndef PCH_ENABLED
#endif

#include <utils/Logger.h>

class AutomaticToneMapping
{
public:
struct ToneMappingThresholds;

AutomaticToneMapping();

AutomaticToneMapping* prepare();
void finilize();
void setConfig(bool enabled, const ToneMappingThresholds& newConfig, int timeInSec, int timeToDisableInMSec);
void setToneMapping(bool enabled);

constexpr uint8_t checkY(uint8_t y)
{
if (y > _running.y) _running.y = y;
return y;
}

constexpr uint8_t checkU(uint8_t u)
{
if (u > _running.u) _running.u = u;
return u;
}

constexpr uint8_t checkV(uint8_t v)
{
if (v > _running.v) _running.v = v;
return v;
}

struct ToneMappingThresholds {
uint8_t y;
uint8_t u;
uint8_t v;
};

private:
bool _enabled;
int _timeInSec;
int _timeToDisableInMSec;

ToneMappingThresholds _config, _running;

bool _modeSDR;
long _startedTime;
long _endingTime;
Logger* _log;

};
5 changes: 5 additions & 0 deletions include/base/Grabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <utils/LutLoader.h>
#include <base/DetectionManual.h>
#include <base/DetectionAutomatic.h>
#include <base/AutomaticToneMapping.h>
#include <performance-counters/PerformanceCounters.h>

#if defined(_WIN32) || defined(WIN32)
Expand Down Expand Up @@ -125,6 +126,9 @@ class Grabber : public DetectionAutomatic, public DetectionManual, protected Lut

QString getConfigurationPath();

void setAutomaticToneMappingConfig(bool enabled, const AutomaticToneMapping::ToneMappingThresholds& newConfig, int timeInSec, int timeToDisableInMSec);
void setAutoToneMappingCurrentStateEnabled(bool enabled);

struct DevicePropertiesItem
{
int x, y, fps, fps_a, fps_b, input;
Expand Down Expand Up @@ -272,6 +276,7 @@ public slots:
bool _signalDetectionEnabled;
bool _signalAutoDetectionEnabled;
QSemaphore _synchro;
AutomaticToneMapping _automaticToneMapping;
};

bool sortDevicePropertiesItem(const Grabber::DevicePropertiesItem& v1, const Grabber::DevicePropertiesItem& v2);
4 changes: 3 additions & 1 deletion include/grabber/linux/v4l2/V4L2Worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <utils/PixelFormat.h>
#include <base/Grabber.h>
#include <utils/Components.h>
#include <base/AutomaticToneMapping.h>

#include <turbojpeg.h>

Expand All @@ -32,7 +33,7 @@ class V4L2Worker : public QThread
unsigned __cropBottom, unsigned __cropRight,
quint64 __currentFrame, qint64 __frameBegin,
int __hdrToneMappingEnabled, uint8_t* __lutBuffer,
bool __qframe, bool __directAccess, QString __deviceName);
bool __qframe, bool __directAccess, QString __deviceName, AutomaticToneMapping* __automaticToneMapping);

void startOnThisThread();
void run() override;
Expand Down Expand Up @@ -76,6 +77,7 @@ class V4L2Worker : public QThread
bool _qframe;
bool _directAccess;
QString _deviceName;
AutomaticToneMapping* _automaticToneMapping;
};

class V4L2WorkerManager : public QObject
Expand Down
4 changes: 3 additions & 1 deletion include/grabber/osx/AVF/AVFWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <utils/PixelFormat.h>
#include <base/Grabber.h>
#include <utils/Components.h>
#include <base/AutomaticToneMapping.h>



Expand All @@ -38,7 +39,7 @@ class AVFWorker : public QThread
unsigned __cropBottom, unsigned __cropRight,
quint64 __currentFrame, qint64 __frameBegin,
int __hdrToneMappingEnabled, uint8_t* __lutBuffer, bool __qframe,
bool __directAccess, QString __deviceName);
bool __directAccess, QString __deviceName, AutomaticToneMapping* __automaticToneMapping);

void startOnThisThread();
void run() override;
Expand Down Expand Up @@ -78,6 +79,7 @@ class AVFWorker : public QThread
bool _qframe;
bool _directAccess;
QString _deviceName;
AutomaticToneMapping* _automaticToneMapping;
};

class AVFWorkerManager : public QObject
Expand Down
4 changes: 3 additions & 1 deletion include/grabber/windows/MF/MFWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <utils/PixelFormat.h>
#include <base/Grabber.h>
#include <utils/Components.h>
#include <base/AutomaticToneMapping.h>

#include <turbojpeg.h>

Expand All @@ -27,7 +28,7 @@ class MFWorker : public QThread
unsigned __cropBottom, unsigned __cropRight,
quint64 __currentFrame, qint64 __frameBegin,
int __hdrToneMappingEnabled, uint8_t* __lutBuffer, bool __qframe,
bool __directAccess, QString __deviceName);
bool __directAccess, QString __deviceName, AutomaticToneMapping* __automaticToneMapping);

void startOnThisThread();
void run() override;
Expand Down Expand Up @@ -69,6 +70,7 @@ class MFWorker : public QThread
bool _qframe;
bool _directAccess;
QString _deviceName;
AutomaticToneMapping* _automaticToneMapping;
};

class MFWorkerManager : public QObject
Expand Down
2 changes: 2 additions & 0 deletions include/lut-calibrator/BestResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct BestResult
double upYLimit = 0;
double downYLimit = 0;
double yShift = 0;
byte3 yuvRange = {};
bool isSourceP010 = false;
} signal;

Expand Down Expand Up @@ -124,6 +125,7 @@ struct BestResult
out << "bestResult.signal.yShift = " << std::to_string(signal.yShift) << ";" << std::endl;
out << "bestResult.signal.isSourceP010 = " << std::to_string(signal.isSourceP010) << ";" << std::endl;
out << "bestResult.minError = " << std::to_string(std::round(minError * 100.0) / 30000.0) << ";" << std::endl;
out << "bestResult.signal.yuvRange = byte3{ " << std::to_string(signal.yuvRange[0]) << ", " << std::to_string(signal.yuvRange[1]) << ", " << std::to_string(signal.yuvRange[2]) << "};" << std::endl;
out << "*/" << std::endl;
}
};
3 changes: 2 additions & 1 deletion include/lut-calibrator/BoardUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ namespace BoardUtils
double _yShift = 0;
double _downYLimit = 0;
double _upYLimit = 0;
byte3 _rangeYUV = {};

public:
CapturedColors() = default;
Expand All @@ -96,7 +97,7 @@ namespace BoardUtils
bool areAllCaptured();
void finilizeBoard();
static void correctYRange(double3& yuv, double yRange, double upYLimit, double downYLimit, double yShift);
void getSignalParams(double& yRange, double& upYLimit, double& downYLimit, double& yShift);
void getSignalParams(double& yRange, double& upYLimit, double& downYLimit, double& yShift, byte3& rangeYUV);
void setCaptured(int index);
void setRange(YuvConverter::COLOR_RANGE range);
YuvConverter::COLOR_RANGE getRange() const;
Expand Down
3 changes: 2 additions & 1 deletion include/utils/FrameDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <image/ColorRgb.h>
#include <image/Image.h>
#include <utils/PixelFormat.h>
#include <base/AutomaticToneMapping.h>

// some stuff for HDR tone mapping
#define LUT_INDEX(y,u,v) ((y + (u<<8) + (v<<16))*3)
Expand All @@ -24,7 +25,7 @@ class FrameDecoder

static void processQImage(
const uint8_t* data, const uint8_t* dataUV, int width, int height, int lineLength,
const PixelFormat pixelFormat, const uint8_t* lutBuffer, Image<ColorRgb>& outputImage, bool toneMapping = true);
const PixelFormat pixelFormat, const uint8_t* lutBuffer, Image<ColorRgb>& outputImage, bool toneMapping = true, AutomaticToneMapping* automaticToneMapping = nullptr);

static void processSystemImageBGRA(Image<ColorRgb>& image, int targetSizeX, int targetSizeY,
int startX, int startY,
Expand Down
3 changes: 3 additions & 0 deletions include/utils/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace settings {
RAWUDPSERVER,
PROTOSERVER,
MQTT,
AUTOTONEMAPPING,
INVALID
};

Expand Down Expand Up @@ -65,6 +66,7 @@ namespace settings {
case type::RAWUDPSERVER: return "rawUdpServer";
case type::PROTOSERVER: return "protoServer";
case type::MQTT: return "mqtt";
case type::AUTOTONEMAPPING: return "automaticToneMapping";
default: return "invalid";
}
}
Expand Down Expand Up @@ -96,6 +98,7 @@ namespace settings {
else if (type == "rawUdpServer") return type::RAWUDPSERVER;
else if (type == "protoServer") return type::PROTOSERVER;
else if (type == "mqtt") return type::MQTT;
else if (type == "automaticToneMapping") return type::AUTOTONEMAPPING;
else return type::INVALID;
}
}
Loading