192 lines
8.5 KiB
Markdown
192 lines
8.5 KiB
Markdown
# 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
|