# HDMI Viewer Ein schlanker Qt6/C++ HDMI-Viewer für Arch Linux mit V4L2 (Video) und ALSA (Audio). Gedacht als Companion zu OBS Studio: **Anzeigen ohne Aufnehmen**. ## Features - Live-Vorschau vom HDMI-Grabber via V4L2, mit automatischer Formatpriorität MJPEG → YUYV → NV12 (MJPEG braucht deutlich weniger USB-Bandbreite und erlaubt so höhere Auflösungen/Framerates) - ALSA-Audio direkt vom Grabber-Gerät (Capture → Wiedergabe, per Thread) - Gerät-Auswahl beim Start (Video, Audio, Ziel-Framerate), alle Einstellungen werden gespeichert und beim nächsten Start vorausgewählt - **F** → Vollbild / **F** oder **Esc** im Vollbild → Fenstermodus - **Esc** im Fenstermodus → zurück zur Gerät-Auswahl (Device wird sauber freigegeben) - Seitenverhältnis immer bewahrt (Letterbox/Pillarbox) - Titelleiste und Statusleiste zeigen tatsächliche Auflösung, FPS und Pixelformat - GPU-Rendering per OpenGL 3.3 (kein Ruckeln durch CPU-seitiges Skalieren) - **Bildglättung** (standardmäßig an, Taste **S**): GPU-Shader trennt Luma/Chroma und behandelt sie getrennt – Chroma wird stärker weichgezeichnet (killt Dot-Crawl/Farbrauschen billiger Composite→HDMI-Scaler), Luma wird leicht geglättet und dezent gegengeschärft (nimmt harte Scaler-Kanten raus, ohne matschig zu wirken). Keine Optik-Spielerei, sondern eine echte Bildverbesserung. - **Retro-Optik** (standardmäßig aus, Taste **C**): separater Nostalgie-Look – Scanlines, Phosphor-/Aperture-Grille-Maske, leichte Wölbung wie bei einem alten Röhrenfernseher. Lässt sich mit der Bildglättung kombinieren. - **Nachschärfen** (Unsharp Mask, Taste **X** zum Umschalten, **+**/**-** zum Fein-Justieren): unabhängig von der Bildglättung, live einstellbar und persistiert. - **Hardware-Helligkeit/-Kontrast/-Sättigung** (Tasten **,**/**.**, **1**/**2**, **3**/**4**): steuert die entsprechenden V4L2-Regler *direkt am Grabber-Chip*, also VOR der JPEG-Kompression – das rettet tatsächlich Schattendetails, statt nur nachträglich am fertig komprimierten Bild zu strecken (was sichtbare Artefakte/Banding erzeugt). Beim Start wird der jeweilige Ausgangswert des Chips ausgelesen und gemerkt; beim Beenden wird er exakt wiederhergestellt, sodass der Grabber für andere Programme unverändert bleibt. Im Startdialog lassen sich für alle drei Regler feste Zielwerte vorgeben (`unverändert` = Regler beim Start gar nicht anfassen). - **Studio-/Full-Range-Korrektur**: Das fertig dekodierte Bild wird von einem komprimierten Kontrastumfang (Schwarzpunkt niedrig angesetzt, Weißpunkt ≈235/255) auf den vollen 0–255-Kontrastumfang gedehnt. Ohne diese Korrektur wirkt das Bild dumpf, kontrastarm und zu dunkel – viele billige HDMI-Grabber liefern (oder kodieren, auch bei MJPEG) genau in diesem komprimierten Bereich. Greift direkt im GPU-Shader auf dem fertigen RGB-Bild, also unabhängig vom Pixelformat. - **Roh-Modus** (Taste **R**): Diagnose-Umschalter, der sämtliche Verarbeitung (Bildglättung, Retro-Optik, Studio-Range-Korrektur, Kontrast-/ Sättigungs-Punch, Gamma) umgeht und das Bild 1:1 anzeigt. Zusätzlich werden die Hardware-Regler am Grabber-Chip auf ihren beim Start gemerkten Ausgangswert zurückgesetzt; beim Ausschalten gelten wieder die gespeicherten Werte bzw. das aktive Profil. - **Live-Vergleich** (Taste **V**): zeigt links das rohe und rechts das bearbeitete Bild nebeneinander – praktisch zum Fein-Tunen der Hardware-Regler. - **Profile** (Menü „Profile“, Tasten **F1**–**F9**): speichert die aktuelle Kombination aus Bildglättung, Retro-Optik, Nachschärfen und den drei Hardware-Reglern unter einem Namen (z. B. „PlayStation“, „PS3“). Beim Umschalten werden Filter und Grabber-Regler sofort gesetzt; „unverändert“ bei einem Hardware-Regler setzt ihn auf den Ausgangswert des Chips zurück. Speichern/Löschen geht im Menü „Profile“ und im Startdialog, dort lädt die Auswahl die Werte in die Felder. Ein Häkchen markiert das Profil, das zu den aktuellen Einstellungen passt. F1–F9 folgen der alphabetischen Reihenfolge im Menü. - **Screenshot** (Taste **P**): speichert das aktuell angezeigte (bearbeitete) Frame als PNG im Home-Verzeichnis. - **Frame-Dump** (Taste **D**, nur bei MJPEG): speichert das nächste rohe, unveränderte MJPEG-Frame direkt vom Chip als JPEG – nützlich, um zu prüfen, ob Abweichungen schon in den Rohdaten liegen oder erst bei der eigenen Verarbeitung entstehen. - **Programm-Icon und Startmenü-Eintrag**: Icon als SVG (`assets/hdmi-viewer.svg`), dazu eine `.desktop`-Datei. Beides wird bei `cmake --install` bzw. über das Paket installiert; das Fenster-Icon ist zusätzlich ins Programm eingebettet. ## Abhängigkeiten (Arch Linux) ```bash sudo pacman -S qt6-base qt6-svg cmake alsa-lib base-devel ``` `qt6-base` bringt auf Arch bereits die benötigten `Qt6OpenGL`- und `Qt6OpenGLWidgets`-Module mit. `qt6-svg` wird für das SVG-Programm-Icon benötigt. `linux/videodev2.h` ist Teil von `linux-api-headers`, das über die `base`-Gruppe ohnehin installiert ist. ## Installation über AUR ```bash yay -S hdmi-viewer # oder mit einem anderen AUR-Helper, bzw. manuell: git clone https://aur.archlinux.org/hdmi-viewer.git cd hdmi-viewer makepkg -si ``` ## Quellcode ```bash git clone https://git.projekt-hirnfrei.de/diabolus/hdmiviewer.git ``` ## Manuell bauen ```bash mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc) ``` Optional systemweit installieren (inkl. Startmenü-Eintrag und Icon): ```bash sudo cmake --install . --prefix /usr/local ``` ## Starten ```bash ./hdmi-viewer ``` ## Tastenkürzel | Taste | Funktion | |---------|--------------------------------------------------------| | F | Vollbild ein/aus | | S | Bildglättung ein/aus | | C | Retro-Optik (Scanlines/Maske) ein/aus | | X | Nachschärfen ein/aus (letzter Wert ↔ aus) | | + / - | Nachschärfen stärker / schwächer | | , / . | Hardware-Helligkeit dunkler / heller | | 1 / 2 | Hardware-Kontrast runter / hoch | | 3 / 4 | Hardware-Sättigung runter / hoch | | R | Roh-Modus (Diagnose, alle Filter + HW-Regler aus) ein/aus | | F1–F9 | Profil 1–9 laden (alphabetisch, siehe Menü „Profile“) | | V | Live-Vergleich (links roh, rechts bearbeitet) ein/aus | | P | Screenshot speichern (PNG) | | D | Rohes MJPEG-Frame dumpen (Diagnose) | | Esc | Vollbild verlassen ODER zurück zum Gerätedialog | ## Hilfsprogramme `tools/colormatch.py` vergleicht zwei Screenshots (z. B. dasselbe Bild in einem Referenzprogramm und in HDMI Viewer) und ermittelt pro Farbkanal Gain, Offset und Gamma, die das Testbild an die Referenz angleichen – inklusive fertiger GLSL-Zeile. Mit `--palette` werden zusätzlich die häufigsten Flächenfarben beider Bilder ausgegeben. Benötigt `python-numpy` und `python-pillow`. ```bash python3 tools/colormatch.py referenz.png test.png --palette ``` Beide Bilder müssen auf demselben Weg entstanden sein (z. B. beide als Desktop-Screenshot des laufenden Programms). ## Einstellungen Werden gespeichert in: `~/.config/hdmi-viewer/HDMIViewer.conf` (Standard XDG-Pfad, kein manuelles Anlegen nötig). Profile liegen in derselben Datei im Abschnitt `[profiles]`. ## Audio-Gerät finden ```bash # Alle ALSA-Capture-Geräte auflisten arecord -l # Testen (hw:X,Y aus arecord -l, z.B. hw:2,0) arecord -D hw:2,0 -f S16_LE -r 48000 -c 2 /tmp/test.wav aplay /tmp/test.wav ``` Das Gerät dann im Dialog so eingeben: z.B. `hw:2,0` oder `plughw:2,0` (plughw macht automatische Sample-Rate-Konvertierung, falls nötig) ## Änderungen ### 1.1.0 - Profile: Kombinationen aus Bildglättung, Retro-Optik, Nachschärfen und Hardware-Reglern speichern, laden und per **F1**–**F9** umschalten (Menü und Startdialog) - Fix: Das Bild wurde in der Anzeige auf etwa die Hälfte der Helligkeit abgedunkelt (Weiß 255 → 128), auch im Roh-Modus. Ursache war OpenGL-Zustand (u. a. Blending), den der `QPainter` der „Kein Signal“-Anzeige zurückließ. Der Zustand wird jetzt vor dem Zeichnen des Videobilds zurückgesetzt. - Roh-Modus (**R**) setzt zusätzlich die Hardware-Regler auf den Ausgangswert - Neues Programm-Icon, Startmenü-Eintrag, neue Abhängigkeit `qt6-svg` - Neues Hilfsprogramm `tools/colormatch.py` ### 1.0.0 - Erste Version