Skip to content
Open
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
105 changes: 91 additions & 14 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,95 @@
Makefile
# Qt Creator user files
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.qmlproject.user
*.qmlproject.user.*
.qmake.stash
YUView.pro.user
# Exclude files that will be created by visual studio
.qmake.cache

# Visual Studio files
.vs/
*.sln
*.vcxproj
*.vcxproj.*
*.filters
*.user
*.VC.opendb
*.VC.db
*.sln
*.vcxproj*
/.vs
/build
/buildRelease
/GeneratedFiles
/x64
/deploy
/decoders
.vscode
issues

# Build directories
build/
build_*/
buildRelease/
debug/
release/
bin/
obj/
x64/
GeneratedFiles/
deploy/
decoders/

# Compiled object files
*.o
*.obj

# Compiled executable and library files
*.exe
*.dll
*.so
*.so.*
*.dylib
*.a
*.lib

# Qt generated files
moc_*.cpp
qrc_*.cpp
ui_*.h
Makefile*
*.qrc.depends

# Core dump
core

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~

# OS generated files
Thumbs.db
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Desktop.ini

# Temporary and log files
*.log
*.tmp
*.temp

# Issue tracking (local)
issues/

# Local development artifacts (not for upstream PR)
temp_docs/
_upstream_ref/
HDR_DEBUG_VERIFICATION.md
docs/HDR_*.md
docs/hdr_*.md
docs/Buffer_Pipeline_Investigation_Report.md
docs/PR_HDR_Debug_Plan_Verification.md

# Compiled shader binaries
# These should be generated during build, not committed
*.qsb
_diff_list.txt
_substantive_diff.txt
10 changes: 9 additions & 1 deletion YUViewApp/YUViewApp.pro
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Qt module configuration with version compatibility
QT += core gui widgets opengl xml concurrent network

# openglwidgets module only exists in Qt6, not in Qt5
greaterThan(QT_MAJOR_VERSION, 5) {
QT += openglwidgets
}

TARGET = YUView
TEMPLATE = app
CONFIG += c++20
CONFIG += c++17
CONFIG -= debug_and_release

SOURCES += $$files(src/*.cpp, false)
Expand Down Expand Up @@ -78,6 +84,8 @@ win32 {
RC_FILE += images/WindowsAppIcon.rc
SVNN = $$system("git describe --tags")
DEFINES += NOMINMAX
# Windows-specific libraries needed for HDR functionality
LIBS += -ldxgi -luser32 -lole32
}

LASTHASH = $$system("git rev-parse HEAD")
Expand Down
77 changes: 71 additions & 6 deletions YUViewApp/src/yuviewapp.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* This file is part of YUView - The YUV player with advanced analytics toolset
/* This file is part of YUView - The YUV player with advanced analytics toolset
* <https://github.com/IENT/YUView>
* Copyright (C) 2015 Institut für Nachrichtentechnik, RWTH Aachen University, GERMANY
*
Expand Down Expand Up @@ -31,22 +31,87 @@
*/

#include <QCoreApplication>
#include <QSurfaceFormat>
#include <QColorSpace>
#include <QDebug>
#include <QSettings>
#include <QMessageBox>

#include <common/Typedef.h>
#include <ui/YUViewApplication.h>


int main(int argc, char *argv[])
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); // DPI support
#endif
// ========================================
// BASIC OPENGL SETUP - MUST BE FIRST
// ========================================

// Set basic OpenGL attributes before any application creation
// Qt6 enables high-DPI scaling by default.
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents,false);
QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents,false);

// ========================================
// STARTUP-BASED HDR DECISION LOGIC (PRD Requirement 5.1-5.5)
// Simplified branch structure: HDR vs SDR path determined once at startup
// ========================================

qRegisterMetaType<recacheIndicator>("recacheIndicator");

YUViewApplication app(argc, argv);
// Set application identity before using QSettings
QCoreApplication::setApplicationName("YUView");
QCoreApplication::setOrganizationName("Institut für Nachrichtentechnik, RWTH Aachen University");
QCoreApplication::setOrganizationDomain("ient.rwth-aachen.de");

// Read HDR preference from configuration (PRD Requirement 5.2)
QSettings settings;
const bool userWantsHDR = settings.value("Enable10BitDisplay", false).toBool();

bool hdrModeEnabled = false;
bool hardwareFallbackOccurred = false;
QString fallbackMessage;


// Simplified pure branch structure for HDR/SDR decision
// When userWantsHDR is true: configure 10-bit OpenGL surface format for HDR rendering
// When userWantsHDR is false: use Qt default format, rely on standard QPainter path
// This eliminates the redundant 8-bit -> 10-bit reconfiguration pattern
if (userWantsHDR) {
// HDR PATH: Configure 10-bit OpenGL surface format with Qt 6.8+ native HDR color space
// This format is required for HDR_VideoWindow to render 10-bit content correctly
QSurfaceFormat hdrFormat;
hdrFormat.setProfile(QSurfaceFormat::CoreProfile);
hdrFormat.setVersion(3, 3);
hdrFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
hdrFormat.setSwapInterval(1);
// HDR RGBA16F requires 16-bit per channel for linear light rendering
hdrFormat.setRedBufferSize(16);
hdrFormat.setGreenBufferSize(16);
hdrFormat.setBlueBufferSize(16);
hdrFormat.setAlphaBufferSize(16);

// Qt 6.8+ Native HDR: Use extended sRGB linear color space for RGBA16F
// The QRhi swap chain will be configured with HDRExtendedSrgbLinear format
// which uses scRGB linear light (values > 1.0 represent HDR content)
// PQ/HLG/Linear OETF will be applied in fragment shader (homework assignment)
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
hdrFormat.setColorSpace(QColorSpace(QColorSpace::SRgbLinear));
#else
#endif

QSurfaceFormat::setDefaultFormat(hdrFormat);

hdrModeEnabled = true;
} else {
// SDR PATH: Use Qt default format, no explicit QSurfaceFormat configuration needed
// Standard QPainter rendering path handles 8-bit display automatically
hdrModeEnabled = false;
}

// Create the main YUView application with HDR decision made

YUViewApplication app(argc, argv, hdrModeEnabled, hardwareFallbackOccurred, fallbackMessage);

return app.returnCode;
}
46 changes: 44 additions & 2 deletions YUViewLib/YUViewLib.pro
Original file line number Diff line number Diff line change
@@ -1,21 +1,56 @@
# Qt module configuration with version compatibility
QT += core gui widgets opengl xml concurrent network

# openglwidgets module only exists in Qt6, not in Qt5
greaterThan(QT_MAJOR_VERSION, 5) {
QT += openglwidgets
# gui-private required for QRhi (Qt Rendering Hardware Interface) HDR support
QT += gui-private
# shadertools module for runtime shader compilation (optional, for RHI HDR support)
# If not available, pre-compiled .qsb files are needed
qtHaveModule(shadertools): QT += shadertools
}

TEMPLATE = lib
CONFIG += staticlib
CONFIG += c++20
CONFIG += c++17
CONFIG -= debug_and_release
CONFIG += object_parallel_to_source

unix {
CONFIG += link_pkgconfig
PKGCONFIG += libpng
}

SOURCES += $$files(src/*.cpp, true)
HEADERS += $$files(src/*.h, true)

# HDR files are automatically included by the recursive $$files() above

FORMS += $$files(ui/*.ui, false)

INCLUDEPATH += src/

RESOURCES += \
images/images.qrc \
docs/docs.qrc
docs/docs.qrc \
resources/shaders/shaders.qrc

greaterThan(QT_MAJOR_VERSION, 5) {
win32:QSB_BIN = $$shell_path($$[QT_HOST_BINS]/qsb.exe)
else:QSB_BIN = $$shell_path($$[QT_HOST_BINS]/qsb)

HDR_SHADER_SOURCES = \
$$files($$PWD/resources/shaders/*.vert, false) \
$$files($$PWD/resources/shaders/*.frag, false)

shader_compiler.name = qsb ${QMAKE_FILE_IN}
shader_compiler.input = HDR_SHADER_SOURCES
shader_compiler.output = ${QMAKE_FILE_IN}.qsb
shader_compiler.commands = $$QSB_BIN --glsl \"440,310 es\" --hlsl 50 --msl 12 -o \"${QMAKE_FILE_OUT}\" \"${QMAKE_FILE_IN}\"
shader_compiler.CONFIG += no_link target_predeps
QMAKE_EXTRA_COMPILERS += shader_compiler
}

contains(QT_ARCH, x86_32|i386) {
warning("You are building for a 32 bit system. This is untested and not supported.")
Expand All @@ -32,11 +67,18 @@ isEmpty(SVNN) {

win32 {
DEFINES += NOMINMAX
# Windows-specific libraries for HDR detection
LIBS += -ldxgi -luser32 -lole32
# Note: WinRT support (-lwindowsapp) temporarily disabled for MinGW compatibility
}

win32-msvc* {
HASHSTRING = '\\"$${LASTHASH}\\"'
DEFINES += YUVIEW_HASH=$${HASHSTRING}
CONFIG(release, debug|release) {
QMAKE_CXXFLAGS_RELEASE += -GL -arch:AVX2 -fp:fast -Ob3
QMAKE_LFLAGS_RELEASE += /LTCG /OPT:REF /OPT:ICF
}
}
win32-g++ | linux | macx {
HASHSTRING = '\\"$${LASTHASH}\\"'
Expand Down
19 changes: 19 additions & 0 deletions YUViewLib/resources/shaders/compile_shaders.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
echo Compiling HDR RHI shaders...

REM RGB vertex shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 -o hdr_rhi_vertex.vert.qsb hdr_rhi_vertex.vert
echo hdr_rhi_vertex.vert -^> hdr_rhi_vertex.vert.qsb

REM RGB fragment shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 -o hdr_rhi_fragment.frag.qsb hdr_rhi_fragment.frag
echo hdr_rhi_fragment.frag -^> hdr_rhi_fragment.frag.qsb

REM YUV vertex shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 -o hdr_rhi_yuv_vertex.vert.qsb hdr_rhi_yuv_vertex.vert
echo hdr_rhi_yuv_vertex.vert -^> hdr_rhi_yuv_vertex.vert.qsb

REM YUV fragment shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 -o hdr_rhi_yuv_fragment.frag.qsb hdr_rhi_yuv_fragment.frag
echo hdr_rhi_yuv_fragment.frag -^> hdr_rhi_yuv_fragment.frag.qsb

echo Done! All shaders compiled successfully.
38 changes: 38 additions & 0 deletions YUViewLib/resources/shaders/compile_shaders.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
# Compile GLSL shaders to QSB format for QRhi
# Usage: ./compile_shaders.sh
# Requires: qsb tool from Qt 6.6+ installation

# Check if qsb is available
if ! command -v qsb &> /dev/null; then
echo "Error: qsb tool not found. Please add Qt bin directory to PATH."
echo "Example: export PATH=\$PATH:/path/to/Qt/6.x.x/gcc_64/bin"
exit 1
fi

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

echo "Compiling HDR RHI shaders..."

# RGB vertex shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 \
-o hdr_rhi_vertex.vert.qsb hdr_rhi_vertex.vert
echo " hdr_rhi_vertex.vert -> hdr_rhi_vertex.vert.qsb"

# RGB fragment shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 \
-o hdr_rhi_fragment.frag.qsb hdr_rhi_fragment.frag
echo " hdr_rhi_fragment.frag -> hdr_rhi_fragment.frag.qsb"

# YUV vertex shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 \
-o hdr_rhi_yuv_vertex.vert.qsb hdr_rhi_yuv_vertex.vert
echo " hdr_rhi_yuv_vertex.vert -> hdr_rhi_yuv_vertex.vert.qsb"

# YUV fragment shader
qsb --glsl "440,310 es" --hlsl 50 --msl 12 \
-o hdr_rhi_yuv_fragment.frag.qsb hdr_rhi_yuv_fragment.frag
echo " hdr_rhi_yuv_fragment.frag -> hdr_rhi_yuv_fragment.frag.qsb"

echo "Done! All shaders compiled successfully."
20 changes: 20 additions & 0 deletions YUViewLib/resources/shaders/hdr_rhi_fragment.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#version 440

// HDR RGB Fragment Shader
//
// This shader samples from a pre-converted RGB texture.
// Used as fallback for SDR content or when RGB texture path is needed.
// For HDR10, the texture should already contain PQ-encoded values.

layout(location = 0) in vec2 TexCoord;
layout(location = 0) out vec4 FragColor;

// Texture sampler for RGB video texture
layout(binding = 1) uniform sampler2D videoTexture;

void main() {
// Sample the texture and output directly
// For HDR10 swap chain, values are PQ-encoded
// For SDR, values are in sRGB color space
FragColor = texture(videoTexture, TexCoord);
}
Loading