13 Commits
Author SHA1 Message Date
AZiZ cf91edcf1e Update README with VP9 and BD-J menu status 2026-10-18 06:39:57 +01:00
AZiZ 36d8450e37 Add files via upload 2026-10-18 06:38:38 +01:00
AZiZ f109ef6410 hardware encoding fixes 2026-10-18 06:36:28 +01:00
AZiZ 71306c9256 v0.4.5 update 2026-10-18 06:35:33 +01:00
AZiZ d46be6a68f Update v0.4 2026-10-10 23:45:02 +01:00
AZiZ 86bb7d474a opus audio/video bug patch 2026-10-10 23:44:10 +01:00
AZiZ a4d877b24d Update version badge to 0.4 in README.md 2026-10-10 23:42:08 +01:00
AZiZ d8050026b6 Enhance features in README with Opus and remote access
Updated features section to include Opus support and clarify phone/PC page functionality.
2026-10-10 23:41:13 +01:00
AZiZ 6b11ce8147 Update hardware decoding and add upscaling feature 2026-10-10 23:37:53 +01:00
AZiZ ebe77db666 Update hardware decoding and HDR features status 2026-10-10 23:34:05 +01:00
AZiZ 7b4e2d2ffe Readme 2026-10-10 18:21:44 +01:00
AZiZ 9aaeb373e9 Update v0.3.1 2026-10-10 16:41:16 +01:00
AZiZ c72b75db4f fixes Dolby TrueHD 7.1 2026-10-10 16:39:40 +01:00
62 changed files with 6450 additions and 491 deletions

No files matched your search

+12 -8
View File
@@ -10,7 +10,7 @@
</p>
<p align="center">
<img alt="Version" src="https://img.shields.io/badge/version-0.3-f37a2b">
<img alt="Version" src="https://img.shields.io/badge/version-0.4-f37a2b">
<img alt="Platform" src="https://img.shields.io/badge/platform-PS5-1f1f1f">
<img alt="VLC" src="https://img.shields.io/badge/libvlc-3.0.24-ff8800">
<img alt="Renderer" src="https://img.shields.io/badge/renderer-Vulkan%20(RADV)-c0561b">
@@ -21,13 +21,15 @@
## Features
- Plays nearly anything VLC plays: H.264, HEVC (8 and 10-bit), AV1, VP9, VC-1, MPEG-2 and more, up to 4K, with every common audio format, including TrueHD and DTS-HD.
- **Library** with Home, Videos, Music and Browse: thumbnails, Continue watching, Favourites and search.
- Plays nearly anything VLC plays: H.264, HEVC (8 and 10-bit), AV1, VP9, VC-1, MPEG-2 and more, up to 4K, with every common audio format, including TrueHD, DTS-HD and Opus.
- **Hardware decoding** on the PS5's video chip for H.264 and HEVC up to 4K, 10-bit HDR included.
- **HDR**: HDR10 and HLG go to an HDR TV as HDR, and are tone mapped with natural colours on an SDR one. Dolby Vision files play as their HDR10 base.
- **Library** with Home, Videos, Music, Playlists and Browse: thumbnails, Continue watching, Favourites and search.
- **Playlists**: make your own, add any video or song from anywhere with Options, reorder them; covers made from their videos; `.m3u` files on your drives play too.
- **Subtitles** in every script, styled ASS/SSA, size and colour, delay, plus **OpenSubtitles** downloads.
- **5.1 / 7.1 surround**, equalizer, night mode and audio delay.
- **Network**: SMB shares, DLNA servers, network links (HTTP, HLS, DASH…), free TV channels and internet radio.
- **PC/Phone page**: open `http://<ps5-ip>:8080` to send files to the PS5, use your pc or phone as a remote.
- **Phone & PC page**: open `http://<ps5-ip>:8080` in any browser to send files to the PS5, download them back to your phone or PC, or add your OpenSubtitles key.
- Music mode with covers and a visualizer, a photo viewer, DVD / Blu-ray folders, and ZIP / RAR / 7z archives.
- Two looks (**Classic** and **Modern**) and **16 languages**.
@@ -102,9 +104,11 @@ Optional full access. With etaHEN, OnionHEN or the Helper, VLC can lift its sand
| 360° videos (look around with the right stick) | ✅ |
| Frame-by-frame step | ✅ |
| Screenshots to PNG | ✅ |
| Hardware decoding (H.264 / HEVC / VP9 up to 4K) | Not yet |
| HDR → SDR tone mapping | Not yet |
| HDR10 output to the TV | Not yet |
| Hardware decoding (H.264 / HEVC) | ✅ |
| HDR → SDR tone mapping | ✅ |
| HDR10 output to the TV | ✅ |
| Hardware decoding (VP9 up to 4K) | ✅ |
| Upscaling up to 4K (FSR 1, Lanczos, Anime4K etc) | Not yet |
### 🔊 Audio
@@ -188,7 +192,7 @@ Optional full access. With etaHEN, OnionHEN or the Helper, VLC can lift its sand
|---|---|
| DVD folders and ISOs with menus | ✅ |
| Blu-ray folders and ISOs (unprotected) | ✅ |
| Blu-ray Java (BD-J) menus | ❌ needs Java, which the PS5 hasn't got: those discs play without menus |
| Blu-ray Java (BD-J) menus | ❌ Java Blu-ray menus not supported |
| ZIP, RAR and 7z archives open like folders | ✅ |
## Building
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = تسجيل الدخول إلى المشاركة
A Windows PC takes its own account; a NAS, the user you made on it. = كمبيوتر ويندوز يقبل حسابه نفسه، وجهاز NAS يقبل المستخدم الذي أنشأته عليه.
Track %d = المسار %d
Track = مسار
Disc menu = قائمة القرص
Pop-up menu = القائمة المنبثقة
Blu-ray region = منطقة Blu-ray
Region %s = المنطقة %s
Blu-ray region: from the next disc you open = منطقة Blu-ray: من القرص التالي الذي تفتحه
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: الأمريكتان وشرق آسيا. B: أوروبا وأفريقيا وأوقيانوسيا. C: الصين وروسيا والهند
Add a subtitle file = إضافة ملف ترجمة
Pick a subtitle file = اختر ملف ترجمة
Subtitles: %s = الترجمة: %s
Couldn't load that subtitle file = تعذّر تحميل ملف الترجمة هذا
That isn't a subtitle file (.srt, .ass, .vtt...) = هذا ليس ملف ترجمة (.srt و.ass و.vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = أقراص Blu-ray التي تعمل بـ Java (BD-J) غير مدعومة على PS5
Hardware decoding = فك الترميز بالعتاد
The console's video chip. Off: the processor decodes, slower for 4K = شريحة الفيديو في الجهاز. عند الإيقاف: يفك المعالج الترميز، وهو أبطأ مع 4K
Looking for channels and stations… = جارٍ البحث عن القنوات والمحطات…
Hardware decoding: from the next video = فك الترميز بالعتاد: من الفيديو التالي
Match frame rate = مطابقة معدل الإطارات
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = تُعرض الأفلام بترددها الأصلي 24 أو 25 أو 50 هرتز: حركة أنعم. بعض أجهزة التلفاز تسودّ لحظة
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Bei der Freigabe anmelden
A Windows PC takes its own account; a NAS, the user you made on it. = Ein Windows-PC nimmt sein eigenes Konto, ein NAS den Benutzer, den du darauf angelegt hast.
Track %d = Spur %d
Track = Spur
Disc menu = Disc-Menü
Pop-up menu = Pop-up-Menü
Blu-ray region = Blu-ray-Region
Region %s = Region %s
Blu-ray region: from the next disc you open = Blu-ray-Region: ab der nächsten Disc, die du öffnest
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Amerika und Ostasien. B: Europa, Afrika und Ozeanien. C: China, Russland und Indien
Add a subtitle file = Untertiteldatei hinzufügen
Pick a subtitle file = Untertiteldatei wählen
Subtitles: %s = Untertitel: %s
Couldn't load that subtitle file = Diese Untertiteldatei ließ sich nicht laden
That isn't a subtitle file (.srt, .ass, .vtt...) = Das ist keine Untertiteldatei (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Java-Blu-rays (BD-J) werden auf der PS5 nicht unterstützt
Hardware decoding = Hardware-Dekodierung
The console's video chip. Off: the processor decodes, slower for 4K = Der Videochip der Konsole. Aus: Der Prozessor dekodiert, langsamer bei 4K
Looking for channels and stations… = Sender und Radiosender werden gesucht…
Hardware decoding: from the next video = Hardware-Dekodierung: ab dem nächsten Video
Match frame rate = Bildrate anpassen
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Filme laufen mit ihren eigenen 24, 25 oder 50 Hz: ruhigere Schwenks. Manche Fernseher werden kurz schwarz
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Iniciar sesión en la carpeta compartida
A Windows PC takes its own account; a NAS, the user you made on it. = Un PC con Windows usa su propia cuenta; un NAS, el usuario que creaste en él.
Track %d = Pista %d
Track = Pista
Disc menu = Menú del disco
Pop-up menu = Menú emergente
Blu-ray region = Región Blu-ray
Region %s = Región %s
Blu-ray region: from the next disc you open = Región Blu-ray: desde el próximo disco que abras
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: América y Asia oriental. B: Europa, África y Oceanía. C: China, Rusia e India
Add a subtitle file = Añadir un archivo de subtítulos
Pick a subtitle file = Elige un archivo de subtítulos
Subtitles: %s = Subtítulos: %s
Couldn't load that subtitle file = No se pudo cargar ese archivo de subtítulos
That isn't a subtitle file (.srt, .ass, .vtt...) = Eso no es un archivo de subtítulos (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Los Blu-ray con Java (BD-J) no son compatibles con la PS5
Hardware decoding = Decodificación por hardware
The console's video chip. Off: the processor decodes, slower for 4K = El chip de vídeo de la consola. Desactivado: decodifica el procesador, más lento en 4K
Looking for channels and stations… = Buscando canales y emisoras…
Hardware decoding: from the next video = Decodificación por hardware: desde el próximo vídeo
Match frame rate = Igualar la frecuencia de imagen
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Las películas se ven a sus propios 24, 25 o 50 Hz: paneos más suaves. Algunas TV se ponen en negro un momento
+18
View File
@@ -552,3 +552,21 @@ Sign in to the share = Se connecter au partage
A Windows PC takes its own account; a NAS, the user you made on it. = Un PC Windows prend son propre compte ; un NAS, l'utilisateur que vous y avez créé.
Track %d = Piste %d
Track = Piste
Disc menu = Menu du disque
Pop-up menu = Menu contextuel
Blu-ray region = Zone Blu-ray
Region %s = Zone %s
Blu-ray region: from the next disc you open = Zone Blu-ray : à partir du prochain disque ouvert
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A : Amériques et Asie de l'Est. B : Europe, Afrique et Océanie. C : Chine, Russie et Inde
Add a subtitle file = Ajouter un fichier de sous-titres
Pick a subtitle file = Choisissez un fichier de sous-titres
Subtitles: %s = Sous-titres : %s
Couldn't load that subtitle file = Impossible de charger ce fichier de sous-titres
That isn't a subtitle file (.srt, .ass, .vtt...) = Ce n'est pas un fichier de sous-titres (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Les Blu-ray Java (BD-J) ne sont pas pris en charge sur PS5
Hardware decoding = Décodage matériel
The console's video chip. Off: the processor decodes, slower for 4K = La puce vidéo de la console. Désactivé : le processeur décode, plus lent en 4K
Looking for channels and stations… = Recherche de chaînes et de stations…
Hardware decoding: from the next video = Décodage matériel : à partir de la prochaine vidéo
Match frame rate = Adapter la fréquence d'images
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Les films passent à leurs propres 24, 25 ou 50 Hz : panoramiques plus fluides. Certaines TV deviennent noires un instant
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Masuk ke folder berbagi
A Windows PC takes its own account; a NAS, the user you made on it. = PC Windows memakai akunnya sendiri; NAS memakai pengguna yang Anda buat di sana.
Track %d = Trek %d
Track = Trek
Disc menu = Menu disk
Pop-up menu = Menu pop-up
Blu-ray region = Region Blu-ray
Region %s = Region %s
Blu-ray region: from the next disc you open = Region Blu-ray: mulai dari disk berikutnya yang kamu buka
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Amerika dan Asia Timur. B: Eropa, Afrika, dan Oseania. C: Tiongkok, Rusia, dan India
Add a subtitle file = Tambahkan file subtitle
Pick a subtitle file = Pilih file subtitle
Subtitles: %s = Subtitle: %s
Couldn't load that subtitle file = File subtitle itu tidak bisa dimuat
That isn't a subtitle file (.srt, .ass, .vtt...) = Itu bukan file subtitle (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Blu-ray Java (BD-J) tidak didukung di PS5
Hardware decoding = Dekode perangkat keras
The console's video chip. Off: the processor decodes, slower for 4K = Cip video konsol. Mati: prosesor yang mendekode, lebih lambat untuk 4K
Looking for channels and stations… = Mencari saluran dan stasiun…
Hardware decoding: from the next video = Dekode perangkat keras: mulai video berikutnya
Match frame rate = Samakan laju bingkai
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Film diputar pada 24, 25 atau 50 Hz aslinya: gerakan lebih halus. Beberapa TV gelap sesaat
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Accedi alla condivisione
A Windows PC takes its own account; a NAS, the user you made on it. = Un PC Windows usa il proprio account; un NAS, l'utente che hai creato su di esso.
Track %d = Traccia %d
Track = Traccia
Disc menu = Menu del disco
Pop-up menu = Menu pop-up
Blu-ray region = Area Blu-ray
Region %s = Area %s
Blu-ray region: from the next disc you open = Area Blu-ray: dal prossimo disco che apri
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Americhe e Asia orientale. B: Europa, Africa e Oceania. C: Cina, Russia e India
Add a subtitle file = Aggiungi un file di sottotitoli
Pick a subtitle file = Scegli un file di sottotitoli
Subtitles: %s = Sottotitoli: %s
Couldn't load that subtitle file = Impossibile caricare quel file di sottotitoli
That isn't a subtitle file (.srt, .ass, .vtt...) = Non è un file di sottotitoli (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = I Blu-ray Java (BD-J) non sono supportati su PS5
Hardware decoding = Decodifica hardware
The console's video chip. Off: the processor decodes, slower for 4K = Il chip video della console. Disattivato: decodifica il processore, più lento in 4K
Looking for channels and stations… = Ricerca di canali e stazioni…
Hardware decoding: from the next video = Decodifica hardware: dal prossimo video
Match frame rate = Adatta frequenza fotogrammi
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = I film vanno ai loro 24, 25 o 50 Hz: panoramiche più fluide. Alcune TV diventano nere per un attimo
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = 共有フォルダーにサインイン
A Windows PC takes its own account; a NAS, the user you made on it. = Windows PC ならその PC のアカウント、NAS なら NAS で作ったユーザーを使います。
Track %d = トラック %d
Track = トラック
Disc menu = ディスクメニュー
Pop-up menu = ポップアップメニュー
Blu-ray region = Blu-ray リージョン
Region %s = リージョン %s
Blu-ray region: from the next disc you open = Blu-ray リージョン: 次に開くディスクから
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: 南北アメリカと東アジア。B: ヨーロッパ、アフリカ、オセアニア。C: 中国、ロシア、インド
Add a subtitle file = 字幕ファイルを追加
Pick a subtitle file = 字幕ファイルを選択
Subtitles: %s = 字幕: %s
Couldn't load that subtitle file = その字幕ファイルを読み込めませんでした
That isn't a subtitle file (.srt, .ass, .vtt...) = 字幕ファイルではありません (.srt、.ass、.vtt など)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Java の Blu-ray (BD-J) は PS5 では再生できません
Hardware decoding = ハードウェアデコード
The console's video chip. Off: the processor decodes, slower for 4K = 本体のビデオチップ。オフ:プロセッサーでデコード(4Kでは遅くなります)
Looking for channels and stations… = チャンネルと局を検索中…
Hardware decoding: from the next video = ハードウェアデコード:次のビデオから
Match frame rate = フレームレートを合わせる
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = 映画を本来の24・25・50Hzで再生し、パンが滑らかになります。一部のテレビは一瞬暗くなります
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = 공유 폴더에 로그인
A Windows PC takes its own account; a NAS, the user you made on it. = Windows PC는 그 PC의 계정을, NAS는 NAS에서 만든 사용자를 사용합니다.
Track %d = 트랙 %d
Track = 트랙
Disc menu = 디스크 메뉴
Pop-up menu = 팝업 메뉴
Blu-ray region = Blu-ray 지역
Region %s = 지역 %s
Blu-ray region: from the next disc you open = Blu-ray 지역: 다음에 여는 디스크부터
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: 아메리카와 동아시아. B: 유럽, 아프리카, 오세아니아. C: 중국, 러시아, 인도
Add a subtitle file = 자막 파일 추가
Pick a subtitle file = 자막 파일 선택
Subtitles: %s = 자막: %s
Couldn't load that subtitle file = 그 자막 파일을 불러올 수 없습니다
That isn't a subtitle file (.srt, .ass, .vtt...) = 자막 파일이 아닙니다 (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Java 블루레이(BD-J)는 PS5에서 지원되지 않습니다
Hardware decoding = 하드웨어 디코딩
The console's video chip. Off: the processor decodes, slower for 4K = 본체의 비디오 칩. 끄면 프로세서가 디코딩하며 4K에서는 느립니다
Looking for channels and stations… = 채널과 방송국을 찾는 중…
Hardware decoding: from the next video = 하드웨어 디코딩: 다음 동영상부터
Match frame rate = 프레임 속도 맞추기
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = 영화를 원래의 24, 25, 50Hz로 재생해 화면 이동이 부드럽습니다. 일부 TV는 잠시 검게 됩니다
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Aanmelden bij de share
A Windows PC takes its own account; a NAS, the user you made on it. = Een Windows-pc gebruikt zijn eigen account; een NAS de gebruiker die je erop hebt gemaakt.
Track %d = Track %d
Track = Track
Disc menu = Schijfmenu
Pop-up menu = Pop-upmenu
Blu-ray region = Blu-ray-regio
Region %s = Regio %s
Blu-ray region: from the next disc you open = Blu-ray-regio: vanaf de volgende schijf die je opent
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Amerika en Oost-Azië. B: Europa, Afrika en Oceanië. C: China, Rusland en India
Add a subtitle file = Ondertitelbestand toevoegen
Pick a subtitle file = Kies een ondertitelbestand
Subtitles: %s = Ondertitels: %s
Couldn't load that subtitle file = Dat ondertitelbestand kon niet worden geladen
That isn't a subtitle file (.srt, .ass, .vtt...) = Dat is geen ondertitelbestand (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Java-Blu-rays (BD-J) worden niet ondersteund op de PS5
Hardware decoding = Hardwaredecodering
The console's video chip. Off: the processor decodes, slower for 4K = De videochip van de console. Uit: de processor decodeert, trager bij 4K
Looking for channels and stations… = Zenders en stations zoeken…
Hardware decoding: from the next video = Hardwaredecodering: vanaf de volgende video
Match frame rate = Beeldfrequentie aanpassen
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Films spelen op hun eigen 24, 25 of 50 Hz: vloeiendere pans. Sommige tv's worden even zwart
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Zaloguj się do udziału
A Windows PC takes its own account; a NAS, the user you made on it. = Komputer z Windows przyjmuje własne konto, a NAS użytkownika, którego na nim utworzono.
Track %d = Ścieżka %d
Track = Ścieżka
Disc menu = Menu płyty
Pop-up menu = Menu podręczne
Blu-ray region = Region Blu-ray
Region %s = Region %s
Blu-ray region: from the next disc you open = Region Blu-ray: od następnej otwartej płyty
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Ameryki i Azja Wschodnia. B: Europa, Afryka i Oceania. C: Chiny, Rosja i Indie
Add a subtitle file = Dodaj plik napisów
Pick a subtitle file = Wybierz plik napisów
Subtitles: %s = Napisy: %s
Couldn't load that subtitle file = Nie udało się wczytać tego pliku napisów
That isn't a subtitle file (.srt, .ass, .vtt...) = To nie jest plik napisów (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Płyty Blu-ray z Javą (BD-J) nie są obsługiwane na PS5
Hardware decoding = Dekodowanie sprzętowe
The console's video chip. Off: the processor decodes, slower for 4K = Układ wideo konsoli. Wył.: dekoduje procesor, wolniej przy 4K
Looking for channels and stations… = Szukanie kanałów i stacji…
Hardware decoding: from the next video = Dekodowanie sprzętowe: od następnego filmu
Match frame rate = Dopasuj liczbę klatek
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Filmy grają we własnych 24, 25 lub 50 Hz: płynniejsze panoramy. Niektóre telewizory na chwilę gasną
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Entrar no compartilhamento
A Windows PC takes its own account; a NAS, the user you made on it. = Um PC com Windows usa a própria conta; um NAS, o usuário que você criou nele.
Track %d = Faixa %d
Track = Faixa
Disc menu = Menu do disco
Pop-up menu = Menu pop-up
Blu-ray region = Região do Blu-ray
Region %s = Região %s
Blu-ray region: from the next disc you open = Região do Blu-ray: a partir do próximo disco que você abrir
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Américas e Leste Asiático. B: Europa, África e Oceania. C: China, Rússia e Índia
Add a subtitle file = Adicionar um arquivo de legenda
Pick a subtitle file = Escolha um arquivo de legenda
Subtitles: %s = Legendas: %s
Couldn't load that subtitle file = Não foi possível carregar esse arquivo de legenda
That isn't a subtitle file (.srt, .ass, .vtt...) = Isso não é um arquivo de legenda (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Blu-rays com Java (BD-J) não são compatíveis com o PS5
Hardware decoding = Decodificação por hardware
The console's video chip. Off: the processor decodes, slower for 4K = O chip de vídeo do console. Desligado: o processador decodifica, mais lento em 4K
Looking for channels and stations… = Procurando canais e estações…
Hardware decoding: from the next video = Decodificação por hardware: a partir do próximo vídeo
Match frame rate = Igualar taxa de quadros
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Filmes rodam nos seus próprios 24, 25 ou 50 Hz: movimentos mais suaves. Algumas TVs ficam pretas por um instante
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Вход в общую папку
A Windows PC takes its own account; a NAS, the user you made on it. = Компьютер с Windows принимает свою учётную запись, NAS — пользователя, которого вы на нём создали.
Track %d = Дорожка %d
Track = Дорожка
Disc menu = Меню диска
Pop-up menu = Всплывающее меню
Blu-ray region = Регион Blu-ray
Region %s = Регион %s
Blu-ray region: from the next disc you open = Регион Blu-ray: со следующего открытого диска
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Америка и Восточная Азия. B: Европа, Африка и Океания. C: Китай, Россия и Индия
Add a subtitle file = Добавить файл субтитров
Pick a subtitle file = Выберите файл субтитров
Subtitles: %s = Субтитры: %s
Couldn't load that subtitle file = Не удалось загрузить этот файл субтитров
That isn't a subtitle file (.srt, .ass, .vtt...) = Это не файл субтитров (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Blu-ray с Java (BD-J) не поддерживаются на PS5
Hardware decoding = Аппаратное декодирование
The console's video chip. Off: the processor decodes, slower for 4K = Видеочип консоли. Выкл.: декодирует процессор, медленнее для 4K
Looking for channels and stations… = Поиск каналов и станций…
Hardware decoding: from the next video = Аппаратное декодирование: со следующего видео
Match frame rate = Подстройка частоты кадров
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Фильмы идут со своей частотой 24, 25 или 50 Гц: плавнее панорамы. Некоторые ТВ на миг гаснут
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = Paylaşıma giriş yap
A Windows PC takes its own account; a NAS, the user you made on it. = Windows PC kendi hesabını, NAS ise üzerinde oluşturduğunuz kullanıcıyı kabul eder.
Track %d = Parça %d
Track = Parça
Disc menu = Disk menüsü
Pop-up menu = Açılır menü
Blu-ray region = Blu-ray bölgesi
Region %s = Bölge %s
Blu-ray region: from the next disc you open = Blu-ray bölgesi: açacağın bir sonraki diskten itibaren
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A: Amerika ve Doğu Asya. B: Avrupa, Afrika ve Okyanusya. C: Çin, Rusya ve Hindistan
Add a subtitle file = Altyazı dosyası ekle
Pick a subtitle file = Bir altyazı dosyası seç
Subtitles: %s = Altyazı: %s
Couldn't load that subtitle file = Bu altyazı dosyası yüklenemedi
That isn't a subtitle file (.srt, .ass, .vtt...) = Bu bir altyazı dosyası değil (.srt, .ass, .vtt...)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = Java Blu-ray diskleri (BD-J) PS5'te desteklenmiyor
Hardware decoding = Donanımla kod çözme
The console's video chip. Off: the processor decodes, slower for 4K = Konsolun video yongası. Kapalı: işlemci çözer, 4K'da daha yavaş
Looking for channels and stations… = Kanallar ve istasyonlar aranıyor…
Hardware decoding: from the next video = Donanımla kod çözme: sonraki videodan itibaren
Match frame rate = Kare hızını eşle
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = Filmler kendi 24, 25 veya 50 Hz'lerinde oynar: daha akıcı kaydırmalar. Bazı TV'ler bir an kararır
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = 登录共享文件夹
A Windows PC takes its own account; a NAS, the user you made on it. = Windows 电脑用它自己的账户;NAS 用你在上面创建的用户。
Track %d = 音轨 %d
Track = 音轨
Disc menu = 光盘菜单
Pop-up menu = 弹出菜单
Blu-ray region = 蓝光区域
Region %s = 区域 %s
Blu-ray region: from the next disc you open = 蓝光区域:从下一张打开的光盘起生效
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A:美洲和东亚。B:欧洲、非洲和大洋洲。C:中国、俄罗斯和印度
Add a subtitle file = 添加字幕文件
Pick a subtitle file = 选择字幕文件
Subtitles: %s = 字幕:%s
Couldn't load that subtitle file = 无法加载该字幕文件
That isn't a subtitle file (.srt, .ass, .vtt...) = 这不是字幕文件(.srt、.ass、.vtt…)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = PS5 不支持 Java 蓝光光盘 (BD-J)
Hardware decoding = 硬件解码
The console's video chip. Off: the processor decodes, slower for 4K = 主机的视频芯片。关闭:由处理器解码,4K 较慢
Looking for channels and stations… = 正在查找频道和电台…
Hardware decoding: from the next video = 硬件解码:从下一个视频开始
Match frame rate = 匹配帧率
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = 电影以其本身的 24、25 或 50 Hz 播放:平移更流畅。部分电视会黑屏片刻
+18
View File
@@ -551,3 +551,21 @@ Sign in to the share = 登入共用資料夾
A Windows PC takes its own account; a NAS, the user you made on it. = Windows 電腦用它自己的帳戶;NAS 用你在上面建立的使用者。
Track %d = 音軌 %d
Track = 音軌
Disc menu = 光碟選單
Pop-up menu = 彈出式選單
Blu-ray region = 藍光區碼
Region %s = 區碼 %s
Blu-ray region: from the next disc you open = 藍光區碼:從下一張開啟的光碟起生效
A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India = A:美洲與東亞。B:歐洲、非洲與大洋洲。C:中國、俄羅斯與印度
Add a subtitle file = 加入字幕檔
Pick a subtitle file = 選擇字幕檔
Subtitles: %s = 字幕:%s
Couldn't load that subtitle file = 無法載入該字幕檔
That isn't a subtitle file (.srt, .ass, .vtt...) = 這不是字幕檔(.srt、.ass、.vtt…)
Java Blu-ray discs (BD-J) aren't supported on the PS5 = PS5 不支援 Java 藍光光碟 (BD-J)
Hardware decoding = 硬體解碼
The console's video chip. Off: the processor decodes, slower for 4K = 主機的視訊晶片。關閉:由處理器解碼,4K 較慢
Looking for channels and stations… = 正在尋找頻道和電台…
Hardware decoding: from the next video = 硬體解碼:從下一個影片開始
Match frame rate = 配合影格率
Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment = 電影以其原本的 24、25 或 50 Hz 播放:平移更流暢。部分電視會黑屏片刻
+1 -1
View File
@@ -30,7 +30,7 @@ defs=(-DVK_NO_PROTOTYPES -DIMGUI_IMPL_VULKAN_USE_VOLK -DVLCPS5_HOST)
cflags=(-O2 -g -Wall -Wno-unused-function "${san[@]}" "${defs[@]}" "${inc[@]}")
# the newest of our headers: a file is built again when one changed (a struct
# that grew, a default argument) not only when the file itself did
newest_h=$(ls -t "$repo"/src/*.h | head -1)
newest_h=$(ls -t "$repo"/src/*.h "$repo"/src/gen/*.h | head -1)
objs=()
compile() { # source compiler [flags...]
@@ -0,0 +1,23 @@
--- a/modules/demux/adaptive/http/HTTPConnection.cpp 2026-10-10 04:56:06.924021837 +0000
+++ b/modules/demux/adaptive/http/HTTPConnection.cpp 2026-10-10 04:56:06.924582937 +0000
@@ -195,14 +195,18 @@
int create(const char *uri,const std::string &ua,
const std::string &ref, const BytesRange &range)
{
- struct restuple *tpl = new struct restuple;
+ /* VLC-PS5: malloc, as vlc_http_res_destroy() frees it with
+ * free(); `new` here was a new/free mismatch (ASan) */
+ struct restuple *tpl = (struct restuple *) malloc(sizeof(*tpl));
+ if (tpl == nullptr)
+ return -1;
tpl->source = this;
this->range = range;
if (vlc_http_res_init(&tpl->resource, &this->callbacks, http_mgr, uri,
ua.empty() ? nullptr : ua.c_str(),
ref.empty() ? nullptr : ref.c_str()))
{
- delete tpl;
+ free(tpl);
return -1;
}
http_res = &tpl->resource;
@@ -0,0 +1,35 @@
--- a/modules/codec/avcodec/audio.c
+++ b/modules/codec/avcodec/audio.c
@@ -37,6 +37,7 @@
#include <vlc_avcodec.h>
#include "avcodec.h"
+#include "../../demux/xiph.h"
#include <libavcodec/avcodec.h>
#include <libavutil/mem.h>
@@ -103,6 +104,24 @@
i_size = 0;
}
+ /* VLC-PS5: VLC's demuxers hand Opus over as packed Xiph headers
+ * (OpusHead, OpusTags) for its own opus module; FFmpeg's decoder
+ * wants the OpusHead alone, else it reads no channels and fails */
+ if( p_dec->fmt_in.i_codec == VLC_CODEC_OPUS &&
+ ( i_size < 8 || memcmp( p_src, "OpusHead", 8 ) ) )
+ {
+ unsigned sizes[XIPH_MAX_HEADER_COUNT];
+ const void *headers[XIPH_MAX_HEADER_COUNT];
+ unsigned count;
+ if( !xiph_SplitHeaders( sizes, headers, &count, i_size, p_src ) &&
+ count > 0 && sizes[0] >= 19 &&
+ !memcmp( headers[0], "OpusHead", 8 ) )
+ {
+ i_offset = (const uint8_t *)headers[0] - p_src;
+ i_size = sizes[0];
+ }
+ }
+
if( i_size > 0 )
{
p_context->extradata =
+16
View File
@@ -0,0 +1,16 @@
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -139,6 +139,13 @@
video_format_t fmt;
video_format_ApplyRotation(&fmt, &vd->fmt);
+ /* VLC-PS5: the picture's colours (HDR transfer, primaries, matrix,
+ * light levels), which the setup callback doesn't carry */
+ void (*colour)(void *, const video_format_t *) =
+ var_InheritAddress(vd, "vmem-colour");
+ if (colour != NULL)
+ colour(sys->opaque, &fmt);
+
if (setup != NULL) {
char chroma[5];
@@ -0,0 +1,34 @@
--- a/src/misc/picture.c
+++ b/src/misc/picture.c
@@ -62,9 +62,17 @@
/**
* Destroys a picture allocated with picture_NewFromFormat().
*/
+/* VLC-PS5: a 4K picture is 25 MiB and a video keeps 20 to 30 of them,
+ * more than the console's heap holds; the title puts big ones in its
+ * direct memory. Weak: without them, the heap as before. */
+extern void *vlc_ps5_big_alloc( size_t ) __attribute__((weak));
+extern int vlc_ps5_big_free( void * ) __attribute__((weak));
+#define VLC_PS5_BIG_PICTURE (4 << 20)
+
static void picture_Destroy( picture_t *p_picture )
{
- aligned_free( p_picture->p[0].p_pixels );
+ if( vlc_ps5_big_free == NULL || !vlc_ps5_big_free( p_picture->p[0].p_pixels ) )
+ aligned_free( p_picture->p[0].p_pixels );
free( p_picture );
}
@@ -274,7 +282,11 @@
goto error;
pic_size = (pic_size + 63) & ~63; /* must be a multiple of 64 */
- uint8_t *buf = aligned_alloc(64, pic_size);
+ uint8_t *buf = NULL;
+ if (vlc_ps5_big_alloc != NULL && pic_size >= VLC_PS5_BIG_PICTURE)
+ buf = vlc_ps5_big_alloc(pic_size);
+ if (buf == NULL)
+ buf = aligned_alloc(64, pic_size);
if (buf == NULL)
goto error;
+34
View File
@@ -0,0 +1,34 @@
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -249,6 +249,10 @@
return sys->pool;
}
+/* VLC-PS5: the app's picture copy, when it has one */
+extern void vlc_ps5_copy_plane(uint8_t *, size_t, const uint8_t *, size_t, size_t,
+ unsigned) __attribute__((weak));
+
static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic)
{
vout_display_sys_t *sys = vd->sys;
@@ -265,7 +269,19 @@
picture_t *locked = picture_NewFromResource(&vd->fmt, &rsc);
if (likely(locked != NULL)) {
- picture_CopyPixels(locked, pic);
+ if (vlc_ps5_copy_plane != NULL) {
+ /* VLC-PS5: split over a few threads (a 4K picture is 25 MiB) */
+ for (int i = 0; i < locked->i_planes && i < pic->i_planes; i++) {
+ const plane_t *d = &locked->p[i], *s = &pic->p[i];
+ int lines = __MIN(d->i_visible_lines, s->i_visible_lines);
+ int bytes = __MIN(d->i_visible_pitch, s->i_visible_pitch);
+ if (lines > 0 && bytes > 0)
+ vlc_ps5_copy_plane(d->p_pixels, d->i_pitch, s->p_pixels, s->i_pitch,
+ bytes, lines);
+ }
+ } else {
+ picture_CopyPixels(locked, pic);
+ }
picture_Release(locked);
}
+49
View File
@@ -0,0 +1,49 @@
--- a/modules/access/smb2.c
+++ b/modules/access/smb2.c
@@ -123,6 +123,7 @@
struct srvsvc_netshareenumall_rep *share_enum;
#endif
uint64_t smb2_size;
+ uint64_t pos; /* VLC-PS5: where the next read starts */
vlc_url_t encoded_url;
bool eof;
bool smb2_connected;
@@ -320,8 +321,20 @@
/* Limit the read size since smb2_read_async() will complete only after
* reading the whole requested data and not when whatever data is available
* (high read size means a faster I/O but a higher latency). */
- if (len > 262144)
- len = 262144;
+ /* VLC-PS5: 2 MiB, fewer requests each waiting a network round trip
+ * (a 4K film needs 9 MB/s; 256 KiB at a time over Wi-Fi didn't make it),
+ * and never past the end of the file: a read crossing it failed, and with
+ * it the last metadata of a 13 GB Blu-ray image (console run 14) */
+ if (len > 2097152)
+ len = 2097152;
+ if (sys->smb2_size > 0) {
+ if (sys->pos >= sys->smb2_size) {
+ sys->eof = true;
+ return 0;
+ }
+ if (len > sys->smb2_size - sys->pos)
+ len = sys->smb2_size - sys->pos;
+ }
struct vlc_smb2_op op = VLC_SMB2_OP(access, &sys->smb2);
op.res.read.len = 0;
@@ -339,6 +352,7 @@
if (op.res.read.len == 0)
sys->eof = true;
+ sys->pos += op.res.read.len;
return op.res.read.len;
}
@@ -366,6 +380,7 @@
VLC_SMB2_SET_ERROR(&op, "smb2_lseek", err);
return err;
}
+ sys->pos = i_pos;
sys->eof = false;
return VLC_SUCCESS;
+38
View File
@@ -0,0 +1,38 @@
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -145,6 +145,8 @@
var_InheritAddress(vd, "vmem-colour");
if (colour != NULL)
colour(sys->opaque, &fmt);
+ /* VLC-PS5: the decoder's own format, for its visible part below */
+ const video_format_t source = fmt;
if (setup != NULL) {
char chroma[5];
@@ -178,9 +180,23 @@
}
sys->cleanup = NULL;
}
- fmt.i_x_offset = fmt.i_y_offset = 0;
- fmt.i_visible_width = fmt.i_width;
- fmt.i_visible_height = fmt.i_height;
+ /* VLC-PS5: a buffer at the decoder's own size keeps the decoder's
+ * visible part (1280x720 in 1280x736; 3840x2160 in 3840x2176): called
+ * all visible, it made VLC scale every picture on the CPU to fill it
+ * (swscale, a whole 4K picture per frame in software decoding). The
+ * app crops it when drawing. */
+ if (fmt.i_width == source.i_width && fmt.i_height == source.i_height &&
+ source.i_x_offset == 0 && source.i_y_offset == 0 &&
+ source.i_visible_width > 0 && source.i_visible_height > 0 &&
+ source.i_visible_width <= fmt.i_width && source.i_visible_height <= fmt.i_height) {
+ fmt.i_x_offset = fmt.i_y_offset = 0;
+ fmt.i_visible_width = source.i_visible_width;
+ fmt.i_visible_height = source.i_visible_height;
+ } else {
+ fmt.i_x_offset = fmt.i_y_offset = 0;
+ fmt.i_visible_width = fmt.i_width;
+ fmt.i_visible_height = fmt.i_height;
+ }
if (!fmt.i_chroma) {
msg_Err(vd, "vmem-chroma should be 4 characters long");
@@ -0,0 +1,41 @@
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -84,6 +84,9 @@
/* Hack to force display of still pictures */
bool b_first_frame;
+ /* VLC-PS5: pictures refused in a row (see DecodeBlock) */
+ int ps5_refused;
+
bool b_draining;
/* */
@@ -1244,6 +1247,19 @@
}
ret = avcodec_send_packet(p_context, pkt);
+ if( ret == AVERROR(ENOMEM) && p_sys->ps5_refused < 200 )
+ {
+ /* VLC-PS5: no picture for a moment (the pictures are cancelled
+ * at a live stream's break, while the decoder's threads still
+ * ask for one): that packet is lost, and the video goes on
+ * from the next keyframe instead of ending (BBC America's
+ * picture stopped for good at a segment break, 2026-10-13) */
+ if (p_sys->ps5_refused++ == 0)
+ msg_Warn(p_dec, "avcodec_send_packet: no picture for now, going on from the next keyframe");
+ avcodec_flush_buffers(p_context);
+ av_packet_free( &pkt );
+ break;
+ }
if( ret != 0 && ret != AVERROR(EAGAIN) )
{
if (ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL))
@@ -1283,6 +1299,8 @@
break;
}
bool not_received_frame = ret;
+ if (!not_received_frame)
+ p_sys->ps5_refused = 0;
wait_mt( p_sys );
@@ -0,0 +1,18 @@
--- a/modules/demux/adaptive/PlaylistManager.cpp
+++ b/modules/demux/adaptive/PlaylistManager.cpp
@@ -685,8 +685,14 @@
}
case DEMUX_GET_PTS_DELAY:
- *va_arg (args, int64_t *) = 1000 * INT64_C(1000);
+ {
+ /* VLC-PS5: the player's network caching, not always 1 s: a
+ * channel whose server sends barely in real time stalled and
+ * rebuffered each time (BBC America, 2026-10-18) */
+ int64_t ms = var_InheritInteger(p_demux, "network-caching");
+ *va_arg (args, int64_t *) = (ms > 1000 ? ms : 1000) * INT64_C(1000);
break;
+ }
default:
return VLC_EGENERIC;
@@ -0,0 +1,58 @@
--- a/modules/demux/adaptive/http/HTTPConnection.cpp
+++ b/modules/demux/adaptive/http/HTTPConnection.cpp
@@ -42,6 +42,19 @@
using namespace adaptive::http;
+/* VLC-PS5: the player stopped this video (src/player.cc). Without this,
+ * after a stop the next segment was still fetched, by VLC's own http once
+ * the console's refused it, and leaving a slow channel took 10 s; the next
+ * video waited for it (2026-10-18). */
+extern "C" int vlc_ps5_stream_cancelled(long) __attribute__((weak));
+static bool ps5_cancelled(vlc_object_t *obj)
+{
+ if (vlc_ps5_stream_cancelled == nullptr)
+ return false;
+ long serial = (long)var_InheritInteger(obj, "ps5http-serial");
+ return serial > 0 && vlc_ps5_stream_cancelled(serial);
+}
+
AbstractConnection::AbstractConnection(vlc_object_t *p_object_)
{
p_object = p_object_;
@@ -295,7 +308,7 @@
RequestStatus LibVLCHTTPConnection::request(const std::string &path,
const BytesRange &range)
{
- if(source->http_mgr == nullptr)
+ if(source->http_mgr == nullptr || ps5_cancelled(p_object))
return RequestStatus::GenericError;
reset();
@@ -414,6 +427,8 @@
ssize_t LibVLCHTTPConnection::read(void *p_buffer, size_t len)
{
+ if (ps5_cancelled(p_object))
+ return 0;
ssize_t read = vlc_stream_Read(stream, p_buffer, len);
bytesRead = source->totalRead;
return read;
@@ -462,6 +477,8 @@
RequestStatus StreamUrlConnection::request(const std::string &path,
const BytesRange &range)
{
+ if (ps5_cancelled(p_object))
+ return RequestStatus::GenericError;
reset();
/* Set new path for this query */
@@ -509,6 +526,8 @@
{
if( !p_streamurl )
return VLC_EGENERIC;
+ if (ps5_cancelled(p_object))
+ return 0;
if(len == 0)
return VLC_SUCCESS;
+16
View File
@@ -0,0 +1,16 @@
--- a/src/input/clock.c
+++ b/src/input/clock.c
@@ -80,7 +80,12 @@
*****************************************************************************/
/* Maximum gap allowed between two CRs. */
-#define CR_MAX_GAP (60 * CLOCK_FREQ)
+/* VLC-PS5: 10 s, not 60. Between two clock references of one stream
+ * (sent every 100 ms or so) a jump over 10 s is a new start; at 60 s a free
+ * TV channel's ad break that moved its times by 35 s was taken as playing
+ * on, every picture and sound counted 35 s late and thrown away, and the
+ * picture froze (a Pluto channel, 2026-10-18). */
+#define CR_MAX_GAP (10 * CLOCK_FREQ)
/* Latency introduced on DVDs with CR == 0 on chapter change - this is from
* my dice --Meuuh */
@@ -0,0 +1,15 @@
--- a/modules/demux/adaptive/logic/BufferingLogic.cpp
+++ b/modules/demux/adaptive/logic/BufferingLogic.cpp
@@ -38,7 +38,11 @@
using namespace adaptive::logic;
const vlc_tick_t AbstractBufferingLogic::BUFFERING_LOWEST_LIMIT = CLOCK_FREQ * 2;
-const vlc_tick_t AbstractBufferingLogic::DEFAULT_MIN_BUFFERING = CLOCK_FREQ * 6;
+/* VLC-PS5: 3 s before a live channel starts, not 6: on the console's Wi-Fi
+ * (about 700 KiB/s to far servers) 6 s of an 8 Mbit/s channel took 4-5 s to
+ * come in, and channels were slow to show (2026-10-18). It still fills up
+ * to its live delay while it plays. */
+const vlc_tick_t AbstractBufferingLogic::DEFAULT_MIN_BUFFERING = CLOCK_FREQ * 3;
const vlc_tick_t AbstractBufferingLogic::DEFAULT_MAX_BUFFERING = CLOCK_FREQ * 30;
const vlc_tick_t AbstractBufferingLogic::DEFAULT_LIVE_BUFFERING = CLOCK_FREQ * 15;
+139
View File
@@ -0,0 +1,139 @@
--- a/src/vulkan/wsi/wsi_common_videoout.c
+++ b/src/vulkan/wsi/wsi_common_videoout.c
@@ -146,8 +146,46 @@
{
return -1;
}
+
+static int
+sceVideoOutSubmitChangeBufferAttribute2(int32_t handle, int32_t set, const void *attribute, const void *option)
+{
+ return 0;
+}
+
+struct ps5_video_out_output_status {
+ uint32_t resolution;
+ uint32_t dynamic_range;
+ uint64_t refresh_rate;
+ uint64_t flags;
+ uint64_t reserved[3];
+};
+
+static int
+sceVideoOutGetOutputStatus(int32_t handle, struct ps5_video_out_output_status *status)
+{
+ memset(status, 0, sizeof(*status));
+ status->dynamic_range = 1;
+ return 0;
+}
+#else
+/* VLC-PS5: VideoOut calls ps5platform/videoout.h doesn't declare. */
+struct ps5_video_out_output_status {
+ uint32_t resolution;
+ uint32_t dynamic_range; /* 0 unknown, 1 SDR, 2 HDR */
+ uint64_t refresh_rate;
+ uint64_t flags; /* bit 0: HDR output active */
+ uint64_t reserved[3];
+};
+int sceVideoOutSubmitChangeBufferAttribute2(int32_t handle, int32_t set, const void *attribute,
+ const void *option);
+int sceVideoOutGetOutputStatus(int32_t handle, struct ps5_video_out_output_status *status);
#endif
+/* VLC-PS5: HDR10 scanout, 10:10:10:2 in the framebuffers' B,G,R order with
+ * BT.2020 primaries and the PQ curve. */
+#define VLCPS5_VIDEO_OUT_PIXEL_FORMAT_HDR10 UINT64_C(0x8100070400000000)
+
/* The display and its modes: one each per process, as VideoOut is. */
struct wsi_videoout_mode {
uint32_t refresh_millihertz;
@@ -399,6 +437,89 @@
return VK_SUCCESS;
}
+/*
+ * VLC-PS5: HDR10 output. The framebuffers stay registered and are retyped in
+ * place (registering them again isn't possible while one is on screen); the
+ * new type applies from the next flip. The app waits for its GPU work to end
+ * first and from then on writes 10:10:10:2 PQ pixels into the same 32-bit
+ * buffers. 0 when VideoOut took it.
+ */
+int vlcps5_wsi_videoout_set_hdr(int enable);
+int vlcps5_wsi_videoout_dynamic_range(void);
+
+int
+vlcps5_wsi_videoout_set_hdr(int enable)
+{
+ struct wsi_videoout_output *out = &videoout_output;
+ mtx_lock(&out->lock);
+ int result = -1;
+ if (out->buffers) {
+ uint8_t attribute[PS5_VIDEO_OUT_ATTRIBUTE_BYTES] = {0};
+ sceVideoOutSetBufferAttribute2(attribute,
+ enable ? VLCPS5_VIDEO_OUT_PIXEL_FORMAT_HDR10
+ : PS5_VIDEO_OUT_PIXEL_FORMAT_B8G8R8A8_SDR,
+ PS5_VIDEO_OUT_TILING_64KB_R_X, VIDEOOUT_WIDTH, VIDEOOUT_HEIGHT, 0, 0, 0);
+ result = sceVideoOutSubmitChangeBufferAttribute2(out->handle, 0, attribute, NULL);
+ }
+ mtx_unlock(&out->lock);
+ fprintf(stderr, "wsi/videoout: framebuffers %s: 0x%08x\n", enable ? "HDR10" : "SDR", (unsigned)result);
+ return result;
+}
+
+/* VLC-PS5: what the output carries: 1 SDR, 2 HDR, 0 unknown, negative: no answer. */
+int
+vlcps5_wsi_videoout_dynamic_range(void)
+{
+ struct wsi_videoout_output *out = &videoout_output;
+ mtx_lock(&out->lock);
+ int result = -1;
+ if (videoout_open_locked()) {
+ struct ps5_video_out_output_status status;
+ memset(&status, 0, sizeof(status));
+ int rc = sceVideoOutGetOutputStatus(out->handle, &status);
+ result = rc == 0 ? (int)status.dynamic_range : -1;
+ fprintf(stderr, "wsi/videoout: output status 0x%08x: range %u, flags 0x%" PRIx64 "\n", (unsigned)rc,
+ status.dynamic_range, status.flags);
+ }
+ mtx_unlock(&out->lock);
+ return result;
+}
+
+/*
+ * VLC-PS5: the output's refresh for films, as VideoOut's output modes number
+ * it: 2 (23.976 Hz), 3 (24 Hz), 9 (50 Hz), 1 (back to the default). Asked
+ * first whether the output takes it; then the vblank period measured, in
+ * microseconds, into *period_us (0 if not changed). 0 when VideoOut took it.
+ */
+int vlcps5_wsi_videoout_set_refresh(int mode, int *period_us);
+
+int
+vlcps5_wsi_videoout_set_refresh(int mode, int *period_us)
+{
+ struct wsi_videoout_output *out = &videoout_output;
+ int result = -1;
+ if (period_us)
+ *period_us = 0;
+ mtx_lock(&out->lock);
+ if (videoout_open_locked()) {
+ const int supported = mode == (int)PS5_VIDEO_OUT_MODE_RESTORE
+ ? 1
+ : sceVideoOutIsOutputSupported(out->handle, (uint32_t)mode, NULL, NULL, NULL);
+ result = supported > 0 ? sceVideoOutConfigureOutput(out->handle, (uint32_t)mode, NULL, NULL, NULL)
+ : (supported < 0 ? supported : -2);
+ int measured = 0;
+ if (result == 0)
+ measured = (int)(videoout_vblank_period_ns(out->handle) / 1000);
+ if (period_us)
+ *period_us = measured;
+ fprintf(stderr, "wsi/videoout: output mode %d: %s (0x%08x), a vblank every %.3f ms\n", mode,
+ result == 0 ? "taken" : supported > 0 ? "refused" : "not supported", (unsigned)result,
+ measured / 1000.0);
+ }
+ mtx_unlock(&out->lock);
+ return result;
+}
+
static int64_t
videoout_shown_argument_locked(void)
{
@@ -0,0 +1,18 @@
--- a/lib/socket.c 2026-10-10 18:59:32.030473620 +0000
+++ b/lib/socket.c 2026-10-10 18:59:32.038975423 +0000
@@ -1072,6 +1072,15 @@
set_nonblocking(fd);
set_tcp_sockopt(fd, TCP_NODELAY, 1);
+ /* VLC-PS5: big buffers, set before connect so the TCP window is
+ * agreed on with them. The console's default (64 KiB) let one window
+ * through per round trip: ~33 Mbit/s over Wi-Fi, under a 4K film's
+ * 70 and a 16 MiB prefetch taking seconds to start a video. */
+ {
+ int rcv = 4 * 1024 * 1024, snd = 1024 * 1024;
+ setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *)&rcv, sizeof rcv);
+ setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *)&snd, sizeof snd);
+ }
#if 0 == CONFIGURE_OPTION_TCP_LINGER
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&yes, sizeof yes);
setsockopt(fd, SOL_SOCKET, SO_LINGER, (const void*)&lin, sizeof lin);
@@ -0,0 +1,55 @@
--- a/upnp/src/ssdp/ssdp_server.c 2026-10-09 20:35:17.057957885 +0000
+++ b/upnp/src/ssdp/ssdp_server.c 2026-10-09 20:35:17.058290985 +0000
@@ -981,6 +981,7 @@
INADDR_ANY,
SSDP_PORT,
errorBuffer);
+ fprintf(stderr, "upnp: bind UDP %d: %s\n", SSDP_PORT, errorBuffer);
ret = UPNP_E_SOCKET_BIND;
goto error_handler;
}
@@ -1509,10 +1510,23 @@
retVal = create_ssdp_sock_v4(&out->ssdpSock4);
if (retVal != UPNP_E_SUCCESS) {
#ifdef INCLUDE_CLIENT_APIS
- UpnpCloseSocket(out->ssdpReqSock4);
- UpnpCloseSocket(out->ssdpReqSock6);
- #endif /* INCLUDE_CLIENT_APIS */
+ /* VLC-PS5: port 1900 taken (the console's own SSDP,
+ * another user: no SO_REUSEPORT sharing when sandboxed).
+ * A control point searches without it. */
+ if (out->ssdpReqSock4 != INVALID_SOCKET) {
+ fprintf(stderr,
+ "upnp: no SSDP listener on port 1900 (%d): "
+ "searching only\n",
+ retVal);
+ out->ssdpSock4 = INVALID_SOCKET;
+ } else {
+ UpnpCloseSocket(out->ssdpReqSock4);
+ UpnpCloseSocket(out->ssdpReqSock6);
+ return retVal;
+ }
+ #else
return retVal;
+ #endif /* INCLUDE_CLIENT_APIS */
}
} else
out->ssdpSock4 = INVALID_SOCKET;
--- a/upnp/src/genlib/miniserver/miniserver.c 2026-10-09 20:35:17.061594185 +0000
+++ b/upnp/src/genlib/miniserver/miniserver.c 2026-10-09 20:35:17.061755185 +0000
@@ -1046,6 +1046,7 @@
"Error in IPv%d bind(): %s\n",
s->ip_version,
errorBuffer);
+ fprintf(stderr, "upnp: miniserver IPv%d bind: %s\n", s->ip_version, errorBuffer);
/* Bind failed. */
ret_val = UPNP_E_SOCKET_BIND;
goto error;
@@ -1298,6 +1299,7 @@
__FILE__,
__LINE__,
"Error in binding localhost!!!\n");
+ fprintf(stderr, "upnp: stop socket bind 127.0.0.1: errno %d\n", errno);
sock_close(miniServerStopSock);
return UPNP_E_SOCKET_BIND;
}
+18 -6
View File
@@ -38,7 +38,8 @@ mkdir -p "$work/obj" "$work/stubs"
# 1. The plugin table and the library list, read with the PS5 toolchain's nm.
# Plus our own plugins (ps5/modules): ps5http, http(s) through the console.
TARGET=ps5 NM="$sdk/bin/prospero-nm" APP_MODULES="vlc_entry__ps5http" bash "$here/gen-static-modules.sh" "$static"
TARGET=ps5 NM="$sdk/bin/prospero-nm" APP_MODULES="vlc_entry__ps5http vlc_entry__ps5vdec" \
bash "$here/gen-static-modules.sh" "$static"
# 2. Our objects, in an archive so --exclude-libs=ALL keeps them out of the
# title's exports (the converter refuses application exports).
@@ -52,12 +53,13 @@ cc "${cflags[@]}" -c "$static/static_modules.c" -o "$work/obj/static_modules.o"
cc "${cflags[@]}" -std=c11 -c "$repo/third_party/volk/volk.c" -o "$work/obj/volk.o"
cc "${cflags[@]}" -std=gnu11 -c "$repo/src/platform_ps5.c" -o "$work/obj/platform_ps5.o"
cc "${cflags[@]}" -std=gnu11 -c "$here/modules/ps5http.c" -o "$work/obj/ps5http.o"
cc "${cflags[@]}" -std=gnu11 -c "$here/modules/ps5vdec.c" -o "$work/obj/ps5vdec.o"
for f in imgui imgui_draw imgui_tables imgui_widgets; do
cc "${cflags[@]}" "${cxxflags[@]}" -c "$repo/third_party/imgui/$f.cpp" -o "$work/obj/$f.o"
done
cc "${cflags[@]}" "${cxxflags[@]}" -c "$repo/third_party/imgui/backends/imgui_impl_vulkan.cpp" \
-o "$work/obj/imgui_impl_vulkan.o"
for f in gfx image prefs player library network osub lang web ui main; do
for f in gfx image prefs player subconv library network osub lang web ui main; do
cc "${cflags[@]}" "${cxxflags[@]}" -c "$repo/src/$f.cc" -o "$work/obj/$f.o"
done
"$sdk/bin/prospero-ar" rcs "$work/libprobe.a" "$work"/obj/*.o
@@ -73,6 +75,10 @@ stub() {
}
stub libSceAgc vendor/ps5/sdk/stubs/agc_canary_link_stub.c
stub libSceAgcDriver vendor/ps5/sdk/stubs/agc_driver_canary_link_stub.c
# The console's video decoder (ps5/modules/ps5vdec.c): our own stub.
cc -std=c11 -O2 -fPIC -c "$here/stubs/videodec2_link_stub.c" -o "$work/libSceVideodec2_stub.o"
"$sdk/bin/prospero-lld" --shared -soname libSceVideodec2.prx \
-o "$work/stubs/libSceVideodec2.so" "$work/libSceVideodec2_stub.o"
# 3. VLC's archives for lld: -lfoo becomes our prefix's libfoo.a; the system
# libraries (pthread, dl, atomic, ...) are the SDK's .so stubs, linked below.
@@ -90,6 +96,8 @@ while read -r item; do
esac
done < "$static/link.rsp"
vlc_inputs+=("$prefix/lib/libps5compat.a")
# GNU libiconv: subtitle files that aren't UTF-8 (src/subconv.cc)
vlc_inputs+=("$prefix/lib/libiconv.a")
# 4. Link.
# shellcheck source=/dev/null
@@ -140,7 +148,7 @@ fi
-u vlc_static_modules \
"$work/app_crt.o" "$work/app_cpp_runtime.o" \
--start-group "$work/libprobe.a" "${vlc_inputs[@]}" --end-group \
"$work/stubs/libSceAgc.so" "$work/stubs/libSceAgcDriver.so" \
"$work/stubs/libSceAgc.so" "$work/stubs/libSceAgcDriver.so" "$work/stubs/libSceVideodec2.so" \
"${radv_link_inputs[@]}" \
--as-needed "$sdk"/target/lib/*.so 2>&1 | tee "$work/link.log" | grep -E "error|warning" | head -60
[[ ${PIPESTATUS[0]} -eq 0 && -f $work/llvm-pie.elf ]] || { echo "link failed: $work/link.log" >&2; exit 1; }
@@ -150,7 +158,8 @@ grep -aq "Video memory output" "$work/llvm-pie.elf" ||
"$tool" link --in "$work/llvm-pie.elf" --out "$work/eboot.elf" \
--stub-dir "$sdk/target/lib" --stub "$work/stubs/libSceAgc.so" \
--stub "$work/stubs/libSceAgcDriver.so" --module-sdk 0x02000009 \
--stub "$work/stubs/libSceAgcDriver.so" --stub "$work/stubs/libSceVideodec2.so" \
--module-sdk 0x02000009 \
--companion-sdk 0x08050001 --file-name eboot.elf
# 5. The title folder.
@@ -189,8 +198,11 @@ cp "$repo/assets/fonts/Inter-SemiBold.ttf" "$app/fonts/subtitle.ttf"
cp "$repo/assets/fonts/Inter-Regular.ttf" "$app/fonts/mono.ttf"
# Noto fonts for the scripts Inter lacks (Arabic, Hebrew, CJK, Thai, ...):
# subtitles (patches/0005) and file names in the interface.
mkdir -p "$app/fonts/fallback"
cp "$repo/assets/fonts/fallback/"* "$app/fonts/fallback/"
mkdir -p "$app/fonts/fallback" "$app/fonts/licenses"
# only fonts in fallback/: libass loads every file there (the OFL texts were
# "Error opening memory font" in every log); their licences beside them
cp "$repo/assets/fonts/fallback/"*.tt[fc] "$app/fonts/fallback/"
cp "$repo/assets/fonts/fallback/"*.txt "$app/fonts/licenses/"
# HTTPS: Mozilla's CA list (curl.se/ca), where GnuTLS looks for it (/app0/certs).
mkdir -p "$app/certs"
cp "$repo/assets/certs/cacert.pem" "$app/certs/"
+97 -2
View File
@@ -150,6 +150,97 @@ static bool unmap_direct(void *addr, size_t len)
return found;
}
/*
* VLC's big pictures (patches/0015). A 4K 10-bit picture is 25 MiB and VLC
* keeps 20 to 30 of them, more than the heap (flexible memory) holds: the
* video then failed to start, a black screen (issue #9). Direct memory has
* room for them.
*/
#define BIG_MAX 128
static struct {
void *addr;
size_t len;
int64_t start;
} big_maps[BIG_MAX];
void *vlc_ps5_big_alloc(size_t len)
{
len = (len + DIRECT_ALIGNMENT - 1) & ~(DIRECT_ALIGNMENT - 1);
void *result = NULL;
pthread_mutex_lock(&direct_lock);
int slot = -1;
for (int i = 0; i < BIG_MAX && slot < 0; i++) {
if (!big_maps[i].addr) {
slot = i;
}
}
int64_t start = -1;
int rc = slot < 0 ? -1 :
sceKernelAllocateDirectMemory(0, sceKernelGetDirectMemorySize(), len,
DIRECT_ALIGNMENT, DIRECT_TYPE_CPU, &start);
if (rc == 0) {
result = ADDRESS_HINT;
rc = sceKernelMapDirectMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE,
0, start, DIRECT_ALIGNMENT);
if (rc != 0) {
result = NULL;
rc = sceKernelMapDirectMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE,
0, start, DIRECT_ALIGNMENT);
}
if (rc != 0) {
sceKernelReleaseDirectMemory(start, len);
result = NULL;
}
}
if (!result && slot >= 0) {
/* Direct memory full (the console's video decoder takes much of it
* for 4K, console run 7): flexible memory, of which there was 1.6 GiB
* left; start -1 marks it. */
start = -1;
result = ADDRESS_HINT;
rc = sceKernelMapFlexibleMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE, 0);
if (rc != 0) {
result = NULL;
rc = sceKernelMapFlexibleMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE, 0);
}
if (rc != 0)
result = NULL;
}
if (result) {
big_maps[slot].addr = result;
big_maps[slot].len = len;
big_maps[slot].start = start;
}
pthread_mutex_unlock(&direct_lock);
if (!result) {
report(slot < 0 ? "big picture (table full)" : "big picture", NULL, len, rc);
}
return result;
}
/* 1 if addr was vlc_ps5_big_alloc's (now freed), 0 if not. */
int vlc_ps5_big_free(void *addr)
{
int found = 0;
pthread_mutex_lock(&direct_lock);
for (int i = 0; i < BIG_MAX && !found; i++) {
if (big_maps[i].addr && big_maps[i].addr == addr) {
if (big_maps[i].start < 0) {
sceKernelMunmap(addr, big_maps[i].len); /* (released, it never came back) */
big_maps[i].addr = NULL;
found = 1;
break;
}
sceKernelMunmap(addr, big_maps[i].len);
sceKernelReleaseDirectMemory(big_maps[i].start, big_maps[i].len);
big_maps[i].addr = NULL;
found = 1;
}
}
pthread_mutex_unlock(&direct_lock);
return found;
}
void *__wrap_mmap(void *addr, size_t len, int prot, int flags, int fd,
off_t offset)
{
@@ -248,7 +339,7 @@ void *__wrap_mmap(void *addr, size_t len, int prot, int flags, int fd,
return MAP_FAILED;
}
if ((flags & MAP_FIXED) && result != addr) {
sceKernelReleaseFlexibleMemory(result, len);
sceKernelMunmap(result, len);
errno = EINVAL;
return MAP_FAILED;
}
@@ -261,7 +352,11 @@ int __wrap_munmap(void *addr, size_t len)
if (unmap_direct(addr, len)) {
return 0;
}
if (sceKernelReleaseFlexibleMemory(addr, len) == 0) {
/* Flexible memory comes back with munmap, not with
* sceKernelReleaseFlexibleMemory: released, it stayed taken (the app's
* self-test on the console, 2026-10-13: 32 MiB released, 0 back; 32 MiB
* unmapped, all back). Every big free VLC and FFmpeg made leaked so. */
if (sceKernelMunmap(addr, len) == 0) {
return 0;
}
/* A reserved range, or a file mapping. */
+29 -1
View File
@@ -264,6 +264,10 @@ build_smb2() {
fetch "https://github.com/sahlberg/libsmb2/archive/refs/tags/libsmb2-$v.tar.gz" "libsmb2-$v.tar.gz"
unpack "libsmb2-$v.tar.gz" "$d"
patch -d "$src/$d" -p1 -s < "$src/vlc-3.0.24/contrib/src/smb2/0001-cmake-add-ENABLE_LIBKRB5-and-ENABLE_GSSAPI-options.patch"
# VLC-PS5's own (patches/smb2/): big socket buffers (the TCP window)
for p in "$(dirname "$(dirname "$here")")"/patches/smb2/*.patch; do
patch -d "$src/$d" -p1 -s < "$p"
done
cmake -S "$src/$d" -B "$src/build-smb2-$target" -G Ninja ${cmake_cross:-} \
-DCMAKE_INSTALL_PREFIX="$prefix" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
@@ -281,6 +285,11 @@ build_upnp() {
for p in libtool-nostdlib-workaround miniserver; do
patch -d "$src/$d" -p1 -s < "$src/vlc-3.0.24/contrib/src/upnp/$p.patch"
done
# Ours: discovery without the SSDP listener when port 1900 can't be had
# (sandboxed on the console: UPNP_E_SOCKET_BIND).
for p in "$(dirname "$(dirname "$here")")"/patches/upnp/*.patch; do
patch -d "$src/$d" -p1 -s < "$p"
done
cmake -S "$src/$d" -B "$src/build-upnp-$target" -G Ninja ${cmake_cross:-} \
-DCMAKE_INSTALL_PREFIX="$prefix" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON -DUPNP_BUILD_SHARED=OFF -DUPNP_BUILD_STATIC=ON \
@@ -320,6 +329,11 @@ build_dvdread() {
local v=6.1.3
fetch "https://download.videolan.org/pub/videolan/libdvdread/$v/libdvdread-$v.tar.bz2"
unpack "libdvdread-$v.tar.bz2" "libdvdread-$v"
# VLC-PS5's own (patches/dvdread/): DVD images read from a stream (a network
# share) without libdvdcss, which the PS5 build doesn't have.
for p in "$(dirname "$(dirname "$here")")"/patches/dvdread/*.patch; do
patch -d "$src/libdvdread-$v" -p1 -s < "$p"
done
(cd "$src/libdvdread-$v" && ./configure --prefix="$prefix" --libdir="$prefix/lib" \
${host_triple:+--host=$host_triple --build=x86_64-pc-linux-gnu} \
--enable-static --disable-shared --with-pic --disable-apidoc &&
@@ -365,7 +379,21 @@ build_libarchive() {
cmake --build "$src/build-libarchive-$target" && cmake --install "$src/build-libarchive-$target"
}
all=(nasm compat zlib ffmpeg dav1d ebml matroska dvbpsi freetype fribidi harfbuzz gmp nettle gnutls smb2 upnp libxml2 ass dvdread dvdnav bluray libarchive)
# Character sets for subtitle files that aren't UTF-8 (Windows-1252, GBK,
# Big5, Shift JIS, Windows-1256...): the console's libc has no iconv. The app
# converts such a file to UTF-8 before VLC reads it (src/subconv.cc).
build_iconv() {
local v=1.18
fetch "https://ftp.gnu.org/gnu/libiconv/libiconv-$v.tar.gz"
unpack "libiconv-$v.tar.gz" "libiconv-$v"
(cd "$src/libiconv-$v" && ./configure --prefix="$prefix" --libdir="$prefix/lib" \
${host_triple:+--host=$host_triple --build=x86_64-pc-linux-gnu} \
--enable-static --disable-shared --disable-nls --with-pic &&
make lib/localcharset.h && make -j"$jobs" -C lib && make -C lib install &&
install -m 644 include/iconv.h.inst "$prefix/include/iconv.h")
}
all=(nasm compat zlib ffmpeg dav1d ebml matroska dvbpsi freetype fribidi harfbuzz gmp nettle gnutls smb2 upnp libxml2 ass dvdread dvdnav bluray libarchive iconv)
recipes=("$@")
[[ ${#recipes[@]} -gt 0 ]] || recipes=("${all[@]}")
for r in "${recipes[@]}"; do
+514 -10
View File
@@ -17,7 +17,12 @@
#include <errno.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/socket.h>
#include <time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,6 +32,7 @@
#include <vlc_common.h>
#include <vlc_access.h>
#include <vlc_interrupt.h>
#include <stdatomic.h>
#include <vlc_plugin.h>
#include <vlc_url.h>
@@ -69,13 +75,76 @@ static int http_template = -1;
/* The console refused a request outright (run 15: 0x8095f00c on every https
* request): VLC's own http module does the rest of the session's. */
static bool service_refused;
/* failures in a row that no answer came between: the service itself only
* after a few (one cancelled search turned it off for the whole session and
* the next channel went to VLC's own http, 2026-10-18) */
static atomic_int service_failures;
static atomic_int https_name_refusals;
/* Servers the console's SSL turned down: straight to VLC's own http next
* time (every segment of a channel paid a refused attempt first). After
* several different ones it refuses https as a whole this session (a log of
* 2026-10-13: every https server refused, GitHub too). */
#define REFUSED_MAX 64
static vlc_mutex_t refused_lock = VLC_STATIC_MUTEX;
static char *refused_hosts[REFUSED_MAX];
static unsigned refused_count;
static bool https_refused;
static char *url_host(const char *url)
{
const char *p = strstr(url, "://");
if (!p)
return NULL;
p += 3;
size_t n = strcspn(p, "/?#");
return strndup(p, n);
}
static bool host_refused(const char *url)
{
if (strncasecmp(url, "https:", 6))
return false;
char *host = url_host(url);
bool refused = false;
vlc_mutex_lock(&refused_lock);
refused = https_refused;
for (unsigned i = 0; host && !refused && i < refused_count; i++)
refused = !strcasecmp(refused_hosts[i], host);
vlc_mutex_unlock(&refused_lock);
free(host);
return refused;
}
static unsigned ssl_refused_count;
static void refuse_host(const char *url, bool ssl)
{
char *host = url_host(url);
if (!host)
return;
vlc_mutex_lock(&refused_lock);
bool known = false;
for (unsigned i = 0; i < refused_count; i++)
known = known || !strcasecmp(refused_hosts[i], host);
if (!known && refused_count < REFUSED_MAX) {
refused_hosts[refused_count++] = host;
host = NULL;
if (ssl && ++ssl_refused_count == 4) {
https_refused = true;
fprintf(stderr, "ps5http: SSL refused 4 different servers: VLC's own http takes every https link\n");
}
}
vlc_mutex_unlock(&refused_lock);
free(host);
}
static void start_service(void)
{
sceNetInit();
int pool = sceNetPoolCreate("vlcps5_http", 1024 * 1024, 0);
int pool = sceNetPoolCreate("vlcps5_http", 4 * 1024 * 1024, 0); /* room for parallel pieces */
int ssl = sceSslInit(320 * 1024);
int http = pool >= 0 && ssl >= 0 ? sceHttpInit(pool, ssl, 4 * 1024 * 1024) : -1;
int http = pool >= 0 && ssl >= 0 ? sceHttpInit(pool, ssl, 8 * 1024 * 1024) : -1;
if (http < 0) {
fprintf(stderr, "ps5http: the console's HTTP service didn't start (net %d, ssl %d, http %d)\n",
pool, ssl, http);
@@ -106,8 +175,24 @@ typedef struct ps5http_sys {
char *content_type;
char *redirect; /* Location of a 3xx */
int status;
long serial; /* the player's open this belongs to (0: none) */
bool logged_direct;
mtime_t opened_at; /* for the speed in the log */
uint64_t read_bytes;
mtime_t read_wait; /* time spent inside the console's read */
bool cancel_logged;
struct parallel *par; /* a segment fetched over several connections, or NULL */
} ps5http_sys;
/* The player (src/player.cc): its open number was stopped */
extern int vlc_ps5_stream_cancelled(long serial) __attribute__((weak));
extern int vlc_ps5_log_details(void) __attribute__((weak));
static bool cancelled(ps5http_sys *sys)
{
return sys->serial && vlc_ps5_stream_cancelled && vlc_ps5_stream_cancelled(sys->serial);
}
static void drop_request(ps5http_sys *sys)
{
if (sys->req >= 0)
@@ -147,6 +232,303 @@ static void abort_on_interrupt(void *data)
sceHttpAbortRequest(*req);
}
/* The app's own name lookup (ps5/compat/vlc_resolver.c): the console's
* DNS can be one that blocks (a PS5 set up to keep away from updates sends
* names to an address that refuses): every named server failed with
* 0x8041013d while bare addresses worked (2026-10-18). */
extern int vlcps5_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
struct addrinfo **res);
extern void vlcps5_freeaddrinfo(struct addrinfo *ai);
static atomic_bool direct_broken; /* a server answered an address-only request wrongly */
/* An http:// link with a name: the same link with the address our lookup
* gives, and the name for the Host header ("name" or "name:port"). NULL: as
* it is (https: the secure connection needs the name; an address already). */
static char *direct_url(const char *url, char **host_header)
{
*host_header = NULL;
if (atomic_load(&direct_broken) || strncasecmp(url, "http://", 7))
return NULL;
const char *h = url + 7;
size_t hlen = strcspn(h, "/?#");
if (!hlen || h[0] == '[' || memchr(h, '@', hlen))
return NULL;
char *hostport = strndup(h, hlen);
if (!hostport)
return NULL;
char *colon = strchr(hostport, ':');
char name[256];
snprintf(name, sizeof(name), "%.*s", colon ? (int)(colon - hostport) : (int)hlen, hostport);
struct in_addr ip;
if (inet_pton(AF_INET, name, &ip) == 1) {
free(hostport);
return NULL;
}
struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM }, *res = NULL;
if (vlcps5_getaddrinfo(name, NULL, &hints, &res) != 0 || !res) {
free(hostport);
return NULL;
}
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, addr, sizeof(addr));
vlcps5_freeaddrinfo(res);
char *out = NULL;
if (asprintf(&out, "http://%s%s%s", addr, colon ? colon : "", h + hlen) < 0) {
free(hostport);
return NULL;
}
*host_header = hostport;
return out;
}
/* ---- a whole segment over several connections ------------------------------
*
* One connection to a far server is often slower than the line: the console
* read BBC America at a steady 700 KiB/s, a 4 s segment in 5 s, and the
* channel froze while the same server played on a PC (2026-10-18). A file of
* a few MiB served with byte ranges (a live channel's segment) is fetched by
* PAR_WORKERS connections at once, PAR_CHUNK at a time, into memory; VLC
* reads it in order as the pieces come. */
#define PAR_CHUNK ((uint64_t)512 << 10)
#define PAR_WORKERS 4
#define PAR_MIN ((uint64_t)1 << 20) /* smaller: one connection is enough */
#define PAR_MAX ((uint64_t)24 << 20) /* bigger (films): one connection, as before */
typedef struct parallel {
char *url, *ua, *ref;
long serial;
uint8_t *buf;
uint64_t size;
unsigned chunks, next;
uint32_t *filled; /* bytes in so far, per chunk */
bool *failed;
bool stop;
int reqs[PAR_WORKERS]; /* each worker's request, for an abort */
pthread_t threads[PAR_WORKERS];
int nthreads;
uint64_t fetched;
pthread_mutex_t lock;
pthread_cond_t cond;
} parallel;
static void add_headers(int req, const char *host_header, const char *ua, const char *ref)
{
if (host_header)
sceHttpAddRequestHeader(req, "Host", host_header, HEADER_OVERWRITE);
if (ua && *ua)
sceHttpAddRequestHeader(req, "User-Agent", ua, HEADER_OVERWRITE);
if (ref && *ref)
sceHttpAddRequestHeader(req, "Referer", ref, HEADER_OVERWRITE);
sceHttpAddRequestHeader(req, "Accept", "*/*", HEADER_OVERWRITE);
sceHttpAddRequestHeader(req, "Cache-Control", "no-cache", HEADER_OVERWRITE);
sceHttpAddRequestHeader(req, "Pragma", "no-cache", HEADER_OVERWRITE);
}
static bool par_cancelled(parallel *p)
{
return p->serial && vlc_ps5_stream_cancelled && vlc_ps5_stream_cancelled(p->serial);
}
/* One piece, from where it got to: true when it's all in. */
static bool par_fetch(parallel *p, int w, unsigned idx)
{
uint64_t start = idx * PAR_CHUNK, end = start + PAR_CHUNK;
if (end > p->size)
end = p->size;
pthread_mutex_lock(&p->lock);
uint64_t from = start + p->filled[idx];
pthread_mutex_unlock(&p->lock);
if (from >= end)
return true;
char *host_header = NULL;
char *direct = direct_url(p->url, &host_header);
const char *url = direct ? direct : p->url;
int conn = sceHttpCreateConnectionWithURL(http_template, url, 1);
int req = conn >= 0 ? sceHttpCreateRequestWithURL(conn, METHOD_GET, url, 0) : -1;
free(direct);
bool ok = false;
if (req >= 0) {
add_headers(req, host_header, p->ua, p->ref);
char range[64];
snprintf(range, sizeof(range), "bytes=%" PRIu64 "-%" PRIu64, from, end - 1);
sceHttpAddRequestHeader(req, "Range", range, HEADER_OVERWRITE);
pthread_mutex_lock(&p->lock);
p->reqs[w] = p->stop ? -1 : req;
bool stop = p->stop;
pthread_mutex_unlock(&p->lock);
int status = 0;
if (!stop && sceHttpSendRequest(req, NULL, 0) >= 0 && sceHttpGetStatusCode(req, &status) >= 0 &&
(status == 206 || (status == 200 && from == 0))) {
ok = true;
while (from < end) {
size_t want = end - from > (64u << 10) ? (64u << 10) : (size_t)(end - from);
int n = sceHttpReadData(req, p->buf + from, want);
if (n <= 0) {
ok = false;
break;
}
from += (uint64_t)n;
pthread_mutex_lock(&p->lock);
p->filled[idx] += (uint32_t)n;
p->fetched += (uint64_t)n;
stop = p->stop;
pthread_cond_broadcast(&p->cond);
pthread_mutex_unlock(&p->lock);
if (stop || par_cancelled(p)) {
ok = false;
break;
}
}
}
pthread_mutex_lock(&p->lock);
p->reqs[w] = -1;
pthread_mutex_unlock(&p->lock);
sceHttpDeleteRequest(req);
}
if (conn >= 0)
sceHttpDeleteConnection(conn);
free(host_header);
return ok;
}
struct par_worker {
parallel *p;
int w;
};
static void *par_run(void *arg)
{
struct par_worker *pw = arg;
parallel *p = pw->p;
int w = pw->w;
free(pw);
for (;;) {
pthread_mutex_lock(&p->lock);
if (p->stop || p->next >= p->chunks) {
pthread_mutex_unlock(&p->lock);
break;
}
unsigned idx = p->next++;
pthread_mutex_unlock(&p->lock);
bool ok = false;
for (int tries = 0; tries < 3 && !ok && !p->stop && !par_cancelled(p); tries++)
ok = par_fetch(p, w, idx);
if (!ok) {
pthread_mutex_lock(&p->lock);
p->failed[idx] = true;
pthread_cond_broadcast(&p->cond);
pthread_mutex_unlock(&p->lock);
}
}
return NULL;
}
static void par_free(parallel *p)
{
if (!p)
return;
pthread_mutex_lock(&p->lock);
p->stop = true;
for (int w = 0; w < PAR_WORKERS; w++)
if (p->reqs[w] >= 0)
sceHttpAbortRequest(p->reqs[w]);
pthread_cond_broadcast(&p->cond);
pthread_mutex_unlock(&p->lock);
for (int i = 0; i < p->nthreads; i++)
pthread_join(p->threads[i], NULL);
pthread_mutex_destroy(&p->lock);
pthread_cond_destroy(&p->cond);
free(p->buf);
free(p->filled);
free(p->failed);
free(p->url);
free(p->ua);
free(p->ref);
free(p);
}
static parallel *par_start(stream_t *access, uint64_t size, long serial)
{
parallel *p = calloc(1, sizeof(*p));
if (!p)
return NULL;
p->size = size;
p->chunks = (unsigned)((size + PAR_CHUNK - 1) / PAR_CHUNK);
p->buf = malloc(size);
p->filled = calloc(p->chunks, sizeof(*p->filled));
p->failed = calloc(p->chunks, sizeof(*p->failed));
p->url = strdup(access->psz_url);
p->ua = var_InheritString(access, "http-user-agent");
p->ref = var_InheritString(access, "http-referrer");
p->serial = serial;
for (int w = 0; w < PAR_WORKERS; w++)
p->reqs[w] = -1;
pthread_mutex_init(&p->lock, NULL);
pthread_cond_init(&p->cond, NULL);
if (!p->buf || !p->filled || !p->failed || !p->url) {
par_free(p);
return NULL;
}
int workers = p->chunks < PAR_WORKERS ? (int)p->chunks : PAR_WORKERS;
for (int w = 0; w < workers; w++) {
struct par_worker *pw = malloc(sizeof(*pw));
if (!pw)
break;
pw->p = p;
pw->w = w;
if (pthread_create(&p->threads[p->nthreads], NULL, par_run, pw) != 0) {
free(pw);
break;
}
p->nthreads++;
}
if (!p->nthreads) {
par_free(p);
return NULL;
}
return p;
}
/* VLC's read from the pieces: what's in at `pos`, waiting for it if needed. */
static ssize_t par_read(stream_t *access, ps5http_sys *sys, void *buf, size_t len)
{
parallel *p = sys->par;
if (sys->pos >= p->size)
return 0;
unsigned idx = (unsigned)(sys->pos / PAR_CHUNK);
uint64_t within = sys->pos % PAR_CHUNK;
pthread_mutex_lock(&p->lock);
while (p->filled[idx] <= within && !p->failed[idx] && !p->stop) {
pthread_mutex_unlock(&p->lock);
if (vlc_killed() || cancelled(sys))
return 0;
pthread_mutex_lock(&p->lock);
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_nsec += 50 * 1000000;
if (ts.tv_nsec >= 1000000000) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}
if (p->filled[idx] <= within && !p->failed[idx])
pthread_cond_timedwait(&p->cond, &p->lock, &ts);
}
size_t have = p->filled[idx] > within ? (size_t)(p->filled[idx] - within) : 0;
bool failed = !have && p->failed[idx];
pthread_mutex_unlock(&p->lock);
if (failed) {
PLOG("a piece at %" PRIu64 " couldn't be fetched", sys->pos);
return 0;
}
if (len > have)
len = have;
memcpy(buf, p->buf + sys->pos, len);
sys->pos += len;
sys->read_bytes += len;
(void)access;
return (ssize_t)len;
}
/* Sends a GET from `offset`; fills status, size, type, redirect. */
static int send_request(stream_t *access, uint64_t offset)
{
@@ -156,17 +538,26 @@ static int send_request(stream_t *access, uint64_t offset)
sys->redirect = NULL;
sys->eof = false;
sys->conn = sceHttpCreateConnectionWithURL(http_template, access->psz_url, 1);
char *host_header = NULL;
char *direct = direct_url(access->psz_url, &host_header);
const char *url = direct ? direct : access->psz_url;
sys->conn = sceHttpCreateConnectionWithURL(http_template, url, 1);
if (sys->conn < 0) {
PLOG("connection failed (%#x)", (unsigned)sys->conn);
free(direct);
free(host_header);
return VLC_EGENERIC;
}
sys->req = sceHttpCreateRequestWithURL(sys->conn, METHOD_GET, access->psz_url, 0);
sys->req = sceHttpCreateRequestWithURL(sys->conn, METHOD_GET, url, 0);
free(direct);
if (sys->req < 0) {
PLOG("request failed (%#x)", (unsigned)sys->req);
free(host_header);
drop_request(sys);
return VLC_EGENERIC;
}
if (host_header)
sceHttpAddRequestHeader(sys->req, "Host", host_header, HEADER_OVERWRITE);
char *ua = var_InheritString(access, "http-user-agent");
char *ref = var_InheritString(access, "http-referrer");
if (ua && *ua)
@@ -176,6 +567,11 @@ static int send_request(stream_t *access, uint64_t offset)
free(ua);
free(ref);
sceHttpAddRequestHeader(sys->req, "Accept", "*/*", HEADER_OVERWRITE);
/* never a cached copy: a live playlist read again came back the same
* (BBC, 2026-10-13: 20 s on, the same ten segments), VLC ran out of
* segments and the channel stopped */
sceHttpAddRequestHeader(sys->req, "Cache-Control", "no-cache", HEADER_OVERWRITE);
sceHttpAddRequestHeader(sys->req, "Pragma", "no-cache", HEADER_OVERWRITE);
if (offset > 0) {
char range[48];
snprintf(range, sizeof(range), "bytes=%" PRIu64 "-", offset);
@@ -186,14 +582,61 @@ static int send_request(stream_t *access, uint64_t offset)
int r = sceHttpSendRequest(sys->req, NULL, 0);
vlc_interrupt_unregister();
if (r < 0) {
PLOG("sending failed (%#x): VLC's own http is used from now on", (unsigned)r);
service_refused = true;
/* 0x8095xxxx: the console's SSL turned this one server down (its
* certificate, its ciphers). VLC's own http takes this link; the
* service stays for the others. Anything else: the service itself. */
bool ssl = ((unsigned)r & 0xFFFF0000u) == 0x80950000u;
/* 0x8043xxxx: this server's connection (down, refused, timed out):
* this link only too. Taken as the service's, one dead channel sent
* every stream after it to VLC's own http (2026-10-13). */
bool net = ((unsigned)r & 0xFFFF0000u) == 0x80430000u ||
((unsigned)r & 0xFFFF0000u) == 0x80410000u; /* 0x8041: the network's errno */
/* stopped on purpose (the player left, a search was typed over):
* nothing wrong with anything */
bool stopped = vlc_killed() || cancelled(sys);
int in_row = stopped || ssl || net ? 0 : atomic_fetch_add(&service_failures, 1) + 1;
PLOG("sending failed (%#x): %s", (unsigned)r,
stopped ? "stopped"
: ssl ? "SSL refused this server, VLC's own http takes this link"
: net ? "connection failed, VLC's own http tries this link"
: in_row >= 3 ? "third time in a row: VLC's own http is used from now on"
: "VLC's own http takes this link");
if (in_row >= 3)
service_refused = true;
if (ssl)
refuse_host(access->psz_url, true);
/* https by name refused (the console's DNS): this one's https links
* straight to VLC's own http from now on, no failed try first */
if (net && !strncasecmp(access->psz_url, "https://", 8) &&
((unsigned)r & 0xFFFF0000u) == 0x80410000u && atomic_fetch_add(&https_name_refusals, 1) + 1 == 3) {
vlc_mutex_lock(&refused_lock);
https_refused = true;
vlc_mutex_unlock(&refused_lock);
PLOG("https refused 3 times by name (the console's DNS?): VLC's own http takes every https link");
}
free(host_header);
drop_request(sys);
return VLC_EGENERIC;
}
atomic_store(&service_failures, 0);
int status = 0;
sceHttpGetStatusCode(sys->req, &status);
sys->status = status;
if (host_header && (status == 400 || status == 403 || status == 404 || status == 421)) {
/* the server wanted its name, not just its address (the Host header
* didn't get through): no more address-only requests this session */
PLOG("HTTP %d to %s by address: VLC's own http takes it, no more by address", status, host_header);
atomic_store(&direct_broken, true);
free(host_header);
drop_request(sys);
return VLC_EGENERIC;
}
if (host_header && !sys->logged_direct) {
sys->logged_direct = true;
PLOG("%s by the app's own name lookup", host_header);
}
free(host_header);
host_header = NULL;
char *headers = NULL;
size_t hlen = 0;
@@ -220,11 +663,32 @@ static int send_request(stream_t *access, uint64_t offset)
static ssize_t Read(stream_t *access, void *buf, size_t len)
{
ps5http_sys *sys = access->p_sys;
if (sys->par)
return par_read(access, sys, buf, len);
if (sys->eof || sys->req < 0)
return 0;
if (cancelled(sys)) {
/* the player left this video: no waiting for the rest of a slow
* server's segment (the next video waited 10 s, 2026-10-18) */
if (!sys->cancel_logged)
PLOG("stopped by the player: connection ended");
sys->cancel_logged = true;
sys->eof = true;
return 0;
}
/* A little at a time: VLC's prefetch asks for 16 MiB at the start, and a
* live channel (no size, 4-8 Mbit/s) took 15-33 s to fill that before the
* first picture (issue #11's log). */
size_t most = sys->size && sys->can_seek ? ((size_t)1 << 20) : ((size_t)64 << 10);
if (len > most)
len = most;
vlc_interrupt_register(abort_on_interrupt, &sys->req);
mtime_t t0 = mdate();
int n = sceHttpReadData(sys->req, buf, len);
sys->read_wait += mdate() - t0;
vlc_interrupt_unregister();
if (n > 0)
sys->read_bytes += (uint64_t)n;
if (n <= 0) {
if (n < 0)
PLOG("read failed (%#x)", (unsigned)n);
@@ -238,6 +702,10 @@ static ssize_t Read(stream_t *access, void *buf, size_t len)
static int Seek(stream_t *access, uint64_t offset)
{
ps5http_sys *sys = access->p_sys;
if (sys->par) {
sys->pos = offset < sys->size ? offset : sys->size;
return VLC_SUCCESS;
}
if (!sys->can_seek)
return VLC_EGENERIC;
if (sys->size && offset >= sys->size) {
@@ -294,6 +762,19 @@ static void Close(vlc_object_t *obj)
{
stream_t *access = (stream_t *)obj;
ps5http_sys *sys = access->p_sys;
/* each download's speed: a live channel's segments must come faster than
* they play (a 4 s piece in under 4 s), or it freezes */
if (sys->read_bytes >= (256u << 10) && vlc_ps5_log_details && vlc_ps5_log_details()) {
double secs = (mdate() - sys->opened_at) / 1e6, wait = sys->read_wait / 1e6;
if (sys->par)
PLOG("read %" PRIu64 " KiB in %.2f s (%.0f KiB/s; %d connections)", sys->read_bytes >> 10, secs,
secs > 0 ? (sys->read_bytes >> 10) / secs : 0.0, sys->par->nthreads);
else
PLOG("read %" PRIu64 " KiB in %.2f s (%.0f KiB/s; %.2f s waiting for the network)",
sys->read_bytes >> 10, secs, secs > 0 ? (sys->read_bytes >> 10) / secs : 0.0, wait);
}
par_free(sys->par);
sys->par = NULL;
drop_request(sys);
free(sys->content_type);
free(sys->redirect);
@@ -304,7 +785,7 @@ static int Open(vlc_object_t *obj)
{
stream_t *access = (stream_t *)obj;
pthread_once(&service_once, start_service);
if (http_template < 0 || service_refused)
if (http_template < 0 || service_refused || host_refused(access->psz_url))
return VLC_EGENERIC; /* VLC's own http module takes over */
ps5http_sys *sys = calloc(1, sizeof(*sys));
@@ -312,6 +793,13 @@ static int Open(vlc_object_t *obj)
return VLC_ENOMEM;
sys->conn = sys->req = -1;
access->p_sys = sys;
sys->serial = (long)var_InheritInteger(access, "ps5http-serial");
sys->opened_at = mdate();
if (cancelled(sys)) {
free(sys);
access->p_sys = NULL;
return VLC_EGENERIC; /* a segment for a video already stopped */
}
PLOG("open %s", access->psz_url);
if (send_request(access, 0) != VLC_SUCCESS)
@@ -319,10 +807,16 @@ static int Open(vlc_object_t *obj)
if (sys->redirect) {
/* VLC opens the new address (and probes the modules again). */
char *to = vlc_uri_resolve(access->psz_url, sys->redirect);
PLOG("redirected (%d) to %s", sys->status, to ? to : sys->redirect);
free(access->psz_url);
access->psz_url = to ? to : strdup(sys->redirect);
if (!to)
to = strdup(sys->redirect);
if (!to)
goto error;
PLOG("redirected (%d) to %s", sys->status, to);
/* Not freed here: access_New() keeps the old address (to spot a
* loop) and frees it itself. Freeing it too was a double free. */
access->psz_url = to;
Close(obj);
access->p_sys = NULL;
return VLC_ACCESS_REDIRECT;
}
if (sys->status == 401 || sys->status == 407) {
@@ -334,6 +828,11 @@ static int Open(vlc_object_t *obj)
PLOG("HTTP %d", sys->status);
goto error;
}
if (sys->status == 200 && sys->can_seek && sys->size >= PAR_MIN && sys->size <= PAR_MAX) {
sys->par = par_start(access, sys->size, sys->serial);
if (sys->par)
drop_request(sys); /* the pieces have their own connections */
}
access->pf_read = Read;
access->pf_block = NULL;
access->pf_seek = Seek;
@@ -342,6 +841,7 @@ static int Open(vlc_object_t *obj)
error:
Close(obj);
access->p_sys = NULL; /* the next module (VLC's own http) starts clean */
return VLC_EGENERIC;
}
@@ -352,5 +852,9 @@ vlc_module_begin()
set_subcategory(SUBCAT_INPUT_ACCESS)
set_capability("access", 300)
add_shortcut("http", "https")
/* the player's number for the open (see vlc_ps5_stream_cancelled) */
add_integer("ps5http-serial", 0, "Player open", NULL, true)
change_private()
change_safe()
set_callbacks(Open, Close)
vlc_module_end()
File diff suppressed because it is too large. Load diff
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# VLC-PS5's changes to the console's Vulkan driver (patches/mesa/): applied to
# the RADV source tree PS5_Vulkan's tools/build-radv.sh made, built, and
# installed where ps5/build-title.sh links it from. Run after build-radv.sh
# (which puts back the fork's own files when its revision changes).
#
# bash ps5/radv-patches.sh
#
# patches/mesa/0001: HDR10 output (the framebuffers switched in place, the
# output's dynamic range read back) for src/player.cc, and the output's
# refresh for films (23.976 / 24 / 50 Hz) for src/main.cc. One patch per file:
# each run starts the file again from the fork's original.
set -euo pipefail
here=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
repo=$(dirname "$here")
vk=${PS5_VULKAN:-$HOME/ps5/PS5_Vulkan}
src=$vk/.deps/work/radv-src
build=$vk/.deps/work/radv-build-ps5-release
install=$vk/.deps/native/radv-release
ninja=${NINJA:-$(command -v ninja || echo "$HOME/.local/bin/ninja")}
[[ -d $src && -f $build/build.ninja ]] || { echo "build RADV first: $vk/tools/build-radv.sh release" >&2; exit 2; }
for p in "$repo"/patches/mesa/*.patch; do
# each file keeps its fork original beside it, so a patch goes on once
target=$(sed -n 's/^+++ b\///p' "$p" | head -1)
[[ -f $src/$target.orig-vlcps5 ]] || cp "$src/$target" "$src/$target.orig-vlcps5"
cp "$src/$target.orig-vlcps5" "$src/$target"
patch -d "$src" -p1 -s < "$p"
echo "applied $(basename "$p")"
done
export PATH="$vk/.deps/work/radv-clc-bin:$PATH"
"$ninja" -C "$build" src/amd/vulkan/libvulkan_radeon.a > "$build.vlcps5.log" 2>&1 ||
{ grep -E "error|FAILED" "$build.vlcps5.log" | head -20 >&2; exit 1; }
cp "$build/src/amd/vulkan/libvulkan_radeon.a" "$install/lib/libvulkan_radeon.ps5.a"
printf 'VLC-PS5 patches: %s\n' "$(cd "$repo/patches/mesa" && ls *.patch | tr '\n' ' ')" >> "$install/PROVENANCE.txt"
echo "==> RADV with VLC-PS5's patches in $install"
+38
View File
@@ -0,0 +1,38 @@
{
"ageLevel": {
"default": 0
},
"applicationCategoryType": 0,
"applicationDrmType": "free",
"attribute": 0,
"attribute2": 0,
"attribute3": 524352,
"conceptId": "85300",
"contentBadgeType": 1,
"contentId": "UP9000-PPSA85300_00-VLCFORPS50000001",
"contentVersion": "01.000.006",
"downloadDataSize": 256,
"gameIntent": {
"permittedIntents": [
{
"intentType": "launchActivity"
}
]
},
"localizedParameters": {
"defaultLanguage": "en-US",
"en-US": {
"titleName": "VLC"
}
},
"masterVersion": "01.00",
"pubtools": {
"creationDate": "2026-10-06 00:00:00",
"loudnessSnd0": "-28.00",
"toolVersion": "2.00"
},
"requiredSystemSoftwareVersion": "0x0000000000000000",
"sdkVersion": "0x0000000000000000",
"titleId": "PPSA85300",
"versionFileUri": ""
}
+4 -11
View File
@@ -2,23 +2,16 @@
"ageLevel": {
"default": 0
},
"applicationCategoryType": 0,
"applicationCategoryType": 65536,
"applicationDrmType": "free",
"attribute": 0,
"attribute": 1644167168,
"attribute2": 0,
"attribute3": 524352,
"conceptId": "85300",
"contentBadgeType": 1,
"contentBadgeType": 2,
"contentId": "UP9000-PPSA85300_00-VLCFORPS50000001",
"contentVersion": "01.000.000",
"contentVersion": "01.000.006",
"downloadDataSize": 256,
"gameIntent": {
"permittedIntents": [
{
"intentType": "launchActivity"
}
]
},
"localizedParameters": {
"defaultLanguage": "en-US",
"en-US": {
+17
View File
@@ -0,0 +1,17 @@
/*
* Link stub for the console's libSceVideodec2: the names the title imports
* (ps5/modules/ps5vdec.c). Only linked against, never run: the console's own
* library answers these calls.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
int sceVideodec2QueryComputeMemoryInfo(void *info) { (void)info; return -1; }
int sceVideodec2AllocateComputeQueue(const void *config, const void *memory, void **queue) { (void)config; (void)memory; (void)queue; return -1; }
int sceVideodec2ReleaseComputeQueue(void *queue) { (void)queue; return -1; }
int sceVideodec2QueryDecoderMemoryInfo(const void *config, void *memory) { (void)config; (void)memory; return -1; }
int sceVideodec2CreateDecoder(const void *config, const void *memory, void **decoder) { (void)config; (void)memory; (void)decoder; return -1; }
int sceVideodec2DeleteDecoder(void *decoder) { (void)decoder; return -1; }
int sceVideodec2Decode(void *decoder, const void *input, void *frame, void *output) { (void)decoder; (void)input; (void)frame; (void)output; return -1; }
int sceVideodec2Flush(void *decoder, void *frame, void *output) { (void)decoder; (void)frame; (void)output; return -1; }
int sceVideodec2Reset(void *decoder) { (void)decoder; return -1; }
int sceVideodec2GetPictureInfo(const void *output, void *first, void *second) { (void)output; (void)first; (void)second; return -1; }
+10
View File
@@ -0,0 +1,10 @@
#version 450
// One triangle over the whole target (the UI layer composited in HDR mode).
layout(location = 0) out vec2 uv;
void main()
{
vec2 p = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
uv = p;
gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0);
}
+45
View File
@@ -0,0 +1,45 @@
#version 450
// HDR output: the UI layer (8-bit, premultiplied, the TV's gamma) over the
// PQ picture. Its colours become light at a graphics white of pc.nits
// (BT.2408's 203), BT.709 -> BT.2020, then PQ; premultiplied again so it
// blends with ONE, ONE_MINUS_SRC_ALPHA as on an SDR screen.
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 color;
layout(set = 0, binding = 0) uniform sampler2D ui;
layout(push_constant) uniform Push {
float nits;
} pc;
const float PQ_M1 = 0.1593017578125, PQ_M2 = 78.84375;
const float PQ_C1 = 0.8359375, PQ_C2 = 18.8515625, PQ_C3 = 18.6875;
vec3 nits_to_pq(vec3 nits)
{
vec3 y = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(PQ_M1));
return pow((PQ_C1 + PQ_C2 * y) / (1.0 + PQ_C3 * y), vec3(PQ_M2));
}
void main()
{
vec4 c = texture(ui, uv);
if (c.a <= 0.0) {
color = vec4(0.0);
return;
}
vec3 straight = clamp(c.rgb / c.a, 0.0, 1.0);
vec3 lin = pow(straight, vec3(2.2)) * pc.nits;
/* BT.709 -> BT.2020 primaries (GLSL matrices are by column) */
lin = mat3(0.6274, 0.0691, 0.0164,
0.3293, 0.9195, 0.0880,
0.0433, 0.0114, 0.8956) * lin;
/* The blend happens on PQ codes: half-transparent black over the picture
* halved the code, which darkened it far more than on an SDR screen.
* There the blend is on gamma codes, leaving (1 - a)^2.2 of the light;
* the coverage that leaves that much of a 100-nit picture is used. */
const float ref = 100.0;
float left = pow(1.0 - c.a, 2.2);
float a = c.a < 1.0 ? 1.0 - nits_to_pq(vec3(ref * left)).x / nits_to_pq(vec3(ref)).x : 1.0;
color = vec4(nits_to_pq(lin) * a, a);
}
+103 -4
View File
@@ -1,8 +1,10 @@
#version 450
// Planar YCbCr (VLC's I420 / J420 / I0AL) to RGB. Same constants as
// Planar YCbCr (VLC's I420 / J420 / I0AL, or NV12 / P010) to RGB. Same constants as
// host/vlc_probe.c, which checked them against real frames in World 1.
// Then the picture controls: brightness and contrast on luma, hue and
// saturation on chroma, gamma on the result.
// saturation on chroma, gamma on the result. HDR (PQ, HLG) is tone mapped
// to SDR between the two; with HDR10 output on (outp.x), the picture goes
// out as PQ, BT.2020 instead.
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 color;
@@ -19,8 +21,96 @@ layout(push_constant) uniform Push {
vec4 adjust; // brightness, contrast, saturation, gamma exponent
vec4 view; // 360: yaw, pitch, tan(fov / 2), screen aspect
vec4 xform; // quarter turns clockwise, mirror, upside down, sharpen amount
vec4 hdr; // transfer (0 SDR, 1 PQ, 2 HLG), peak (nits), BT.2020 primaries (1), NV12/P010 (1)
vec4 outp; // HDR10 output (1): PQ, BT.2020; -, -, -
} pc;
/* HDR to SDR, the same sums as hdr_to_sdr() in player.cc (screenshots). */
const float SDR_WHITE = 203.0; // HDR's reference white (BT.2408) = the TV's white
const float PQ_M1 = 0.1593017578125, PQ_M2 = 78.84375;
const float PQ_C1 = 0.8359375, PQ_C2 = 18.8515625, PQ_C3 = 18.6875;
vec3 pq_to_nits(vec3 e)
{
vec3 p = pow(clamp(e, 0.0, 1.0), vec3(1.0 / PQ_M2));
return 10000.0 * pow(max(p - PQ_C1, 0.0) / (PQ_C2 - PQ_C3 * p), vec3(1.0 / PQ_M1));
}
float nits_to_pq(float nits)
{
float y = pow(clamp(nits / 10000.0, 0.0, 1.0), PQ_M1);
return pow((PQ_C1 + PQ_C2 * y) / (1.0 + PQ_C3 * y), PQ_M2);
}
/* HLG: scene light, then the system gamma of a 1000-nit TV (BT.2100) */
vec3 hlg_to_nits(vec3 e)
{
const float a = 0.17883277, b = 0.28466892, c = 0.55991073;
e = clamp(e, 0.0, 1.0);
vec3 s = mix(e * e / 3.0, (exp((e - c) / a) + b) / 12.0, step(vec3(0.5), e));
float ys = max(dot(s, vec3(0.2627, 0.6780, 0.0593)), 1e-6);
return 1000.0 * pow(ys, 0.2) * s;
}
vec3 nits_to_pq3(vec3 nits)
{
vec3 y = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(PQ_M1));
return pow((PQ_C1 + PQ_C2 * y) / (1.0 + PQ_C3 * y), vec3(PQ_M2));
}
/* HDR10 output: the picture as PQ with BT.2020 primaries. HDR10 is that
* already and goes through untouched; HLG and SDR become light (SDR white
* at 203 nits), then BT.2020, then PQ. */
vec3 to_pq_output(vec3 e)
{
if (pc.hdr.x > 0.5 && pc.hdr.x < 1.5 && pc.hdr.z > 0.5)
return e;
vec3 nits;
if (pc.hdr.x > 0.5)
nits = pc.hdr.x < 1.5 ? pq_to_nits(e) : hlg_to_nits(e);
else
nits = pow(clamp(e, 0.0, 1.0), vec3(2.4)) * SDR_WHITE;
if (pc.hdr.z < 0.5) {
/* BT.709 -> BT.2020 primaries */
nits = mat3(0.6274, 0.0691, 0.0164,
0.3293, 0.9195, 0.0880,
0.0433, 0.0114, 0.8956) * nits;
}
return nits_to_pq3(nits);
}
vec3 hdr_to_sdr(vec3 e)
{
vec3 nits = pc.hdr.x < 1.5 ? pq_to_nits(e) : hlg_to_nits(e);
/* BT.2390's roll-off on the brightest channel (keeps the hue): up to
* about half of SDR white nothing changes, above it the highlights bend
* down to fit under white. */
float peak = pc.hdr.y;
float sig = max(nits.r, max(nits.g, nits.b));
if (sig > 0.0 && peak > SDR_WHITE) {
float src = nits_to_pq(peak);
float e1 = min(nits_to_pq(sig) / src, 1.0);
float maxl = nits_to_pq(SDR_WHITE) / src;
float ks = 1.5 * maxl - 0.5;
float e2 = e1;
if (e1 > ks) {
float t = (e1 - ks) / (1.0 - ks), t2 = t * t, t3 = t2 * t;
e2 = (2.0 * t3 - 3.0 * t2 + 1.0) * ks + (t3 - 2.0 * t2 + t) * (1.0 - ks) +
(-2.0 * t3 + 3.0 * t2) * maxl;
}
nits *= pq_to_nits(vec3(e2 * src)).r / sig;
}
vec3 lin = nits / SDR_WHITE;
if (pc.hdr.z > 0.5) {
/* BT.2020 -> BT.709 primaries (linear light; GLSL matrices are by column) */
lin = mat3(1.6605, -0.1246, -0.0182,
-0.5876, 1.1329, -0.1006,
-0.0728, -0.0083, 1.1187) * lin;
}
/* back to a TV's signal (BT.1886, gamma 2.4) */
return pow(clamp(lin, 0.0, 1.0), vec3(1.0 / 2.4));
}
/* Rotate and flip: the point of the picture this pixel shows. */
vec2 turned_uv()
{
@@ -69,8 +159,11 @@ void main()
around += texture(tex_y, at + vec2(float(dx), float(dy)) * t).r;
y = clamp(y + (y - around * 0.125 * s) * pc.xform.w, 0.0, 1.0);
}
float u = texture(tex_u, at).r * s - 0.5;
float v = texture(tex_v, at).r * s - 0.5;
/* NV12 / P010: U and V side by side in the second plane */
vec2 chroma = pc.hdr.w > 0.5 ? texture(tex_u, at).rg
: vec2(texture(tex_u, at).r, texture(tex_v, at).r);
float u = chroma.x * s - 0.5;
float v = chroma.y * s - 0.5;
if (pc.params.y > 0.5) {
y = (y - 16.0 / 255.0) * (255.0 / 219.0);
u *= 255.0 / 224.0;
@@ -82,5 +175,11 @@ void main()
vec3 yuv = vec3(y, uv2);
vec3 rgb = clamp(vec3(dot(pc.row0.xyz, yuv), dot(pc.row1.xyz, yuv), dot(pc.row2.xyz, yuv)),
0.0, 1.0);
if (pc.outp.x > 0.5) {
color = vec4(to_pq_output(rgb), 1.0);
return;
}
if (pc.hdr.x > 0.5)
rgb = hdr_to_sdr(rgb);
color = vec4(pow(rgb, vec3(pc.adjust.w)), 1.0);
}
+43
View File
@@ -0,0 +1,43 @@
// 1116.2.0
#pragma once
const uint32_t spv_fullscreen_vert[] = {
0x07230203,0x00010300,0x0008000b,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000c,0x00000018,0x00000020,
0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,
0x00000009,0x00000070,0x00060005,0x0000000c,0x565f6c67,0x65747265,0x646e4978,0x00007865,
0x00030005,0x00000018,0x00007675,0x00060005,0x0000001e,0x505f6c67,0x65567265,0x78657472,
0x00000000,0x00060006,0x0000001e,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,
0x0000001e,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000001e,
0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000001e,0x00000003,
0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000020,0x00000000,0x00040047,
0x0000000c,0x0000000b,0x0000002a,0x00040047,0x00000018,0x0000001e,0x00000000,0x00030047,
0x0000001e,0x00000002,0x00050048,0x0000001e,0x00000000,0x0000000b,0x00000000,0x00050048,
0x0000001e,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000001e,0x00000002,0x0000000b,
0x00000003,0x00050048,0x0000001e,0x00000003,0x0000000b,0x00000004,0x00020013,0x00000002,
0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,
0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,0x00000007,0x00040015,0x0000000a,
0x00000020,0x00000001,0x00040020,0x0000000b,0x00000001,0x0000000a,0x0004003b,0x0000000b,
0x0000000c,0x00000001,0x0004002b,0x0000000a,0x0000000e,0x00000001,0x0004002b,0x0000000a,
0x00000010,0x00000002,0x00040020,0x00000017,0x00000003,0x00000007,0x0004003b,0x00000017,
0x00000018,0x00000003,0x00040017,0x0000001a,0x00000006,0x00000004,0x00040015,0x0000001b,
0x00000020,0x00000000,0x0004002b,0x0000001b,0x0000001c,0x00000001,0x0004001c,0x0000001d,
0x00000006,0x0000001c,0x0006001e,0x0000001e,0x0000001a,0x00000006,0x0000001d,0x0000001d,
0x00040020,0x0000001f,0x00000003,0x0000001e,0x0004003b,0x0000001f,0x00000020,0x00000003,
0x0004002b,0x0000000a,0x00000021,0x00000000,0x0004002b,0x00000006,0x00000023,0x40000000,
0x0004002b,0x00000006,0x00000025,0x3f800000,0x0004002b,0x00000006,0x00000028,0x00000000,
0x00040020,0x0000002c,0x00000003,0x0000001a,0x00050036,0x00000002,0x00000004,0x00000000,
0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x00000009,0x00000007,0x0004003d,
0x0000000a,0x0000000d,0x0000000c,0x000500c4,0x0000000a,0x0000000f,0x0000000d,0x0000000e,
0x000500c7,0x0000000a,0x00000011,0x0000000f,0x00000010,0x0004006f,0x00000006,0x00000012,
0x00000011,0x0004003d,0x0000000a,0x00000013,0x0000000c,0x000500c7,0x0000000a,0x00000014,
0x00000013,0x00000010,0x0004006f,0x00000006,0x00000015,0x00000014,0x00050050,0x00000007,
0x00000016,0x00000012,0x00000015,0x0003003e,0x00000009,0x00000016,0x0004003d,0x00000007,
0x00000019,0x00000009,0x0003003e,0x00000018,0x00000019,0x0004003d,0x00000007,0x00000022,
0x00000009,0x0005008e,0x00000007,0x00000024,0x00000022,0x00000023,0x00050050,0x00000007,
0x00000026,0x00000025,0x00000025,0x00050083,0x00000007,0x00000027,0x00000024,0x00000026,
0x00050051,0x00000006,0x00000029,0x00000027,0x00000000,0x00050051,0x00000006,0x0000002a,
0x00000027,0x00000001,0x00070050,0x0000001a,0x0000002b,0x00000029,0x0000002a,0x00000028,
0x00000025,0x00050041,0x0000002c,0x0000002d,0x00000020,0x00000021,0x0003003e,0x0000002d,
0x0000002b,0x000100fd,0x00010038
};
+109
View File
@@ -0,0 +1,109 @@
// 1116.2.0
#pragma once
const uint32_t spv_ui_pq_frag[] = {
0x07230203,0x00010300,0x0008000b,0x00000093,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000035,0x00000042,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00060005,0x0000000b,0x7374696e,0x5f6f745f,0x76287170,0x003b3366,0x00040005,
0x0000000a,0x7374696e,0x00000000,0x00030005,0x0000000d,0x00000079,0x00030005,0x0000002d,
0x00000063,0x00030005,0x00000031,0x00006975,0x00030005,0x00000035,0x00007675,0x00040005,
0x00000042,0x6f6c6f63,0x00000072,0x00050005,0x00000045,0x61727473,0x74686769,0x00000000,
0x00030005,0x0000004f,0x006e696c,0x00040005,0x00000054,0x68737550,0x00000000,0x00050006,
0x00000054,0x00000000,0x7374696e,0x00000000,0x00030005,0x00000056,0x00006370,0x00040005,
0x0000006d,0x7466656c,0x00000000,0x00030005,0x00000072,0x00000061,0x00040005,0x0000007d,
0x61726170,0x0000006d,0x00040005,0x00000082,0x61726170,0x0000006d,0x00040005,0x00000089,
0x61726170,0x0000006d,0x00040047,0x00000031,0x00000021,0x00000000,0x00040047,0x00000031,
0x00000022,0x00000000,0x00040047,0x00000035,0x0000001e,0x00000000,0x00040047,0x00000042,
0x0000001e,0x00000000,0x00030047,0x00000054,0x00000002,0x00050048,0x00000054,0x00000000,
0x00000023,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,
0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000003,0x00040020,0x00000008,
0x00000007,0x00000007,0x00040021,0x00000009,0x00000007,0x00000008,0x0004002b,0x00000006,
0x0000000f,0x461c4000,0x0004002b,0x00000006,0x00000012,0x00000000,0x0004002b,0x00000006,
0x00000013,0x3f800000,0x0004002b,0x00000006,0x00000017,0x3e232000,0x0006002c,0x00000007,
0x00000018,0x00000017,0x00000017,0x00000017,0x0004002b,0x00000006,0x0000001a,0x3f560000,
0x0004002b,0x00000006,0x0000001b,0x4196d000,0x0004002b,0x00000006,0x00000020,0x41958000,
0x0004002b,0x00000006,0x00000026,0x429db000,0x0006002c,0x00000007,0x00000027,0x00000026,
0x00000026,0x00000026,0x00040017,0x0000002b,0x00000006,0x00000004,0x00040020,0x0000002c,
0x00000007,0x0000002b,0x00090019,0x0000002e,0x00000006,0x00000001,0x00000000,0x00000000,
0x00000000,0x00000001,0x00000000,0x0003001b,0x0000002f,0x0000002e,0x00040020,0x00000030,
0x00000000,0x0000002f,0x0004003b,0x00000030,0x00000031,0x00000000,0x00040017,0x00000033,
0x00000006,0x00000002,0x00040020,0x00000034,0x00000001,0x00000033,0x0004003b,0x00000034,
0x00000035,0x00000001,0x00040015,0x00000038,0x00000020,0x00000000,0x0004002b,0x00000038,
0x00000039,0x00000003,0x00040020,0x0000003a,0x00000007,0x00000006,0x00020014,0x0000003d,
0x00040020,0x00000041,0x00000003,0x0000002b,0x0004003b,0x00000041,0x00000042,0x00000003,
0x0007002c,0x0000002b,0x00000043,0x00000012,0x00000012,0x00000012,0x00000012,0x0004002b,
0x00000006,0x00000051,0x400ccccd,0x0006002c,0x00000007,0x00000052,0x00000051,0x00000051,
0x00000051,0x0003001e,0x00000054,0x00000006,0x00040020,0x00000055,0x00000009,0x00000054,
0x0004003b,0x00000055,0x00000056,0x00000009,0x00040015,0x00000057,0x00000020,0x00000001,
0x0004002b,0x00000057,0x00000058,0x00000000,0x00040020,0x00000059,0x00000009,0x00000006,
0x00040018,0x0000005d,0x00000007,0x00000003,0x0004002b,0x00000006,0x0000005e,0x3f209d49,
0x0004002b,0x00000006,0x0000005f,0x3d8d844d,0x0004002b,0x00000006,0x00000060,0x3c86594b,
0x0006002c,0x00000007,0x00000061,0x0000005e,0x0000005f,0x00000060,0x0004002b,0x00000006,
0x00000062,0x3ea89a02,0x0004002b,0x00000006,0x00000063,0x3f6b645a,0x0004002b,0x00000006,
0x00000064,0x3db43958,0x0006002c,0x00000007,0x00000065,0x00000062,0x00000063,0x00000064,
0x0004002b,0x00000006,0x00000066,0x3d315b57,0x0004002b,0x00000006,0x00000067,0x3c3ac711,
0x0004002b,0x00000006,0x00000068,0x3f65460b,0x0006002c,0x00000007,0x00000069,0x00000066,
0x00000067,0x00000068,0x0006002c,0x0000005d,0x0000006a,0x00000061,0x00000065,0x00000069,
0x0004002b,0x00000006,0x00000079,0x42c80000,0x0004002b,0x00000038,0x0000007f,0x00000000,
0x0006002c,0x00000007,0x00000081,0x00000079,0x00000079,0x00000079,0x00050036,0x00000002,
0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000002c,0x0000002d,
0x00000007,0x0004003b,0x00000008,0x00000045,0x00000007,0x0004003b,0x00000008,0x0000004f,
0x00000007,0x0004003b,0x0000003a,0x0000006d,0x00000007,0x0004003b,0x0000003a,0x00000072,
0x00000007,0x0004003b,0x0000003a,0x00000076,0x00000007,0x0004003b,0x00000008,0x0000007d,
0x00000007,0x0004003b,0x00000008,0x00000082,0x00000007,0x0004003b,0x00000008,0x00000089,
0x00000007,0x0004003d,0x0000002f,0x00000032,0x00000031,0x0004003d,0x00000033,0x00000036,
0x00000035,0x00050057,0x0000002b,0x00000037,0x00000032,0x00000036,0x0003003e,0x0000002d,
0x00000037,0x00050041,0x0000003a,0x0000003b,0x0000002d,0x00000039,0x0004003d,0x00000006,
0x0000003c,0x0000003b,0x000500bc,0x0000003d,0x0000003e,0x0000003c,0x00000012,0x000300f7,
0x00000040,0x00000000,0x000400fa,0x0000003e,0x0000003f,0x00000040,0x000200f8,0x0000003f,
0x0003003e,0x00000042,0x00000043,0x000100fd,0x000200f8,0x00000040,0x0004003d,0x0000002b,
0x00000046,0x0000002d,0x0008004f,0x00000007,0x00000047,0x00000046,0x00000046,0x00000000,
0x00000001,0x00000002,0x00050041,0x0000003a,0x00000048,0x0000002d,0x00000039,0x0004003d,
0x00000006,0x00000049,0x00000048,0x00060050,0x00000007,0x0000004a,0x00000049,0x00000049,
0x00000049,0x00050088,0x00000007,0x0000004b,0x00000047,0x0000004a,0x00060050,0x00000007,
0x0000004c,0x00000012,0x00000012,0x00000012,0x00060050,0x00000007,0x0000004d,0x00000013,
0x00000013,0x00000013,0x0008000c,0x00000007,0x0000004e,0x00000001,0x0000002b,0x0000004b,
0x0000004c,0x0000004d,0x0003003e,0x00000045,0x0000004e,0x0004003d,0x00000007,0x00000050,
0x00000045,0x0007000c,0x00000007,0x00000053,0x00000001,0x0000001a,0x00000050,0x00000052,
0x00050041,0x00000059,0x0000005a,0x00000056,0x00000058,0x0004003d,0x00000006,0x0000005b,
0x0000005a,0x0005008e,0x00000007,0x0000005c,0x00000053,0x0000005b,0x0003003e,0x0000004f,
0x0000005c,0x0004003d,0x00000007,0x0000006b,0x0000004f,0x00050091,0x00000007,0x0000006c,
0x0000006a,0x0000006b,0x0003003e,0x0000004f,0x0000006c,0x00050041,0x0000003a,0x0000006e,
0x0000002d,0x00000039,0x0004003d,0x00000006,0x0000006f,0x0000006e,0x00050083,0x00000006,
0x00000070,0x00000013,0x0000006f,0x0007000c,0x00000006,0x00000071,0x00000001,0x0000001a,
0x00000070,0x00000051,0x0003003e,0x0000006d,0x00000071,0x00050041,0x0000003a,0x00000073,
0x0000002d,0x00000039,0x0004003d,0x00000006,0x00000074,0x00000073,0x000500b8,0x0000003d,
0x00000075,0x00000074,0x00000013,0x000300f7,0x00000078,0x00000000,0x000400fa,0x00000075,
0x00000077,0x00000087,0x000200f8,0x00000077,0x0004003d,0x00000006,0x0000007a,0x0000006d,
0x00050085,0x00000006,0x0000007b,0x00000079,0x0000007a,0x00060050,0x00000007,0x0000007c,
0x0000007b,0x0000007b,0x0000007b,0x0003003e,0x0000007d,0x0000007c,0x00050039,0x00000007,
0x0000007e,0x0000000b,0x0000007d,0x00050051,0x00000006,0x00000080,0x0000007e,0x00000000,
0x0003003e,0x00000082,0x00000081,0x00050039,0x00000007,0x00000083,0x0000000b,0x00000082,
0x00050051,0x00000006,0x00000084,0x00000083,0x00000000,0x00050088,0x00000006,0x00000085,
0x00000080,0x00000084,0x00050083,0x00000006,0x00000086,0x00000013,0x00000085,0x0003003e,
0x00000076,0x00000086,0x000200f9,0x00000078,0x000200f8,0x00000087,0x0003003e,0x00000076,
0x00000013,0x000200f9,0x00000078,0x000200f8,0x00000078,0x0004003d,0x00000006,0x00000088,
0x00000076,0x0003003e,0x00000072,0x00000088,0x0004003d,0x00000007,0x0000008a,0x0000004f,
0x0003003e,0x00000089,0x0000008a,0x00050039,0x00000007,0x0000008b,0x0000000b,0x00000089,
0x0004003d,0x00000006,0x0000008c,0x00000072,0x0005008e,0x00000007,0x0000008d,0x0000008b,
0x0000008c,0x0004003d,0x00000006,0x0000008e,0x00000072,0x00050051,0x00000006,0x0000008f,
0x0000008d,0x00000000,0x00050051,0x00000006,0x00000090,0x0000008d,0x00000001,0x00050051,
0x00000006,0x00000091,0x0000008d,0x00000002,0x00070050,0x0000002b,0x00000092,0x0000008f,
0x00000090,0x00000091,0x0000008e,0x0003003e,0x00000042,0x00000092,0x000100fd,0x00010038,
0x00050036,0x00000007,0x0000000b,0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a,
0x000200f8,0x0000000c,0x0004003b,0x00000008,0x0000000d,0x00000007,0x0004003d,0x00000007,
0x0000000e,0x0000000a,0x00060050,0x00000007,0x00000010,0x0000000f,0x0000000f,0x0000000f,
0x00050088,0x00000007,0x00000011,0x0000000e,0x00000010,0x00060050,0x00000007,0x00000014,
0x00000012,0x00000012,0x00000012,0x00060050,0x00000007,0x00000015,0x00000013,0x00000013,
0x00000013,0x0008000c,0x00000007,0x00000016,0x00000001,0x0000002b,0x00000011,0x00000014,
0x00000015,0x0007000c,0x00000007,0x00000019,0x00000001,0x0000001a,0x00000016,0x00000018,
0x0003003e,0x0000000d,0x00000019,0x0004003d,0x00000007,0x0000001c,0x0000000d,0x0005008e,
0x00000007,0x0000001d,0x0000001c,0x0000001b,0x00060050,0x00000007,0x0000001e,0x0000001a,
0x0000001a,0x0000001a,0x00050081,0x00000007,0x0000001f,0x0000001e,0x0000001d,0x0004003d,
0x00000007,0x00000021,0x0000000d,0x0005008e,0x00000007,0x00000022,0x00000021,0x00000020,
0x00060050,0x00000007,0x00000023,0x00000013,0x00000013,0x00000013,0x00050081,0x00000007,
0x00000024,0x00000023,0x00000022,0x00050088,0x00000007,0x00000025,0x0000001f,0x00000024,
0x0007000c,0x00000007,0x00000028,0x00000001,0x0000001a,0x00000025,0x00000027,0x000200fe,
0x00000028,0x00010038
};
+570 -294
View File
@@ -1,300 +1,576 @@
// 1116.2.0
#pragma once
const uint32_t spv_video_frag[] = {
0x07230203,0x00010300,0x0008000b,0x000001a8,0x00000000,0x00020011,0x00000001,0x00020011,
0x07230203,0x00010300,0x0008000b,0x00000336,0x00000000,0x00020011,0x00000001,0x00020011,
0x00000032,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,
0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000010,
0x0000019e,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,
0x00000004,0x6e69616d,0x00000000,0x00050005,0x00000009,0x6e727574,0x755f6465,0x00002876,
0x00060005,0x0000000b,0x65687073,0x61636972,0x76755f6c,0x00000028,0x00030005,0x0000000e,
0x0000006e,0x00030005,0x00000010,0x00007675,0x00040005,0x00000013,0x68737550,0x00000000,
0x00050006,0x00000013,0x00000000,0x30776f72,0x00000000,0x00050006,0x00000013,0x00000001,
0x31776f72,0x00000000,0x00050006,0x00000013,0x00000002,0x32776f72,0x00000000,0x00050006,
0x00000013,0x00000003,0x61726170,0x0000736d,0x00060006,0x00000013,0x00000004,0x735f7675,
0x656c6163,0x00000000,0x00050006,0x00000013,0x00000005,0x756a6461,0x00007473,0x00050006,
0x00000013,0x00000006,0x77656976,0x00000000,0x00050006,0x00000013,0x00000007,0x726f6678,
0x0000006d,0x00030005,0x00000015,0x00006370,0x00030005,0x00000039,0x00000071,0x00030005,
0x00000068,0x0063646e,0x00030005,0x00000073,0x00000064,0x00030005,0x00000086,0x00007063,
0x00030005,0x0000008a,0x00007073,0x00030005,0x000000a4,0x00007963,0x00030005,0x000000a8,
0x00007973,0x00030005,0x000000c2,0x006e6f6c,0x00030005,0x000000c8,0x0074616c,0x00030005,
0x000000dc,0x00000073,0x00030005,0x000000df,0x00007461,0x00030005,0x000000ea,0x00000079,
0x00040005,0x000000ee,0x5f786574,0x00000079,0x00030005,0x000000fb,0x00000074,0x00040005,
0x00000104,0x756f7261,0x0000646e,0x00030005,0x00000105,0x00007964,0x00030005,0x0000010e,
0x00007864,0x00030005,0x0000013c,0x00000075,0x00040005,0x0000013d,0x5f786574,0x00000075,
0x00030005,0x00000145,0x00000076,0x00040005,0x00000146,0x5f786574,0x00000076,0x00030005,
0x00000167,0x00000063,0x00030005,0x0000016b,0x00006e73,0x00030005,0x0000016f,0x00327675,
0x00030005,0x00000182,0x00767579,0x00030005,0x00000188,0x00626772,0x00040005,0x0000019e,
0x6f6c6f63,0x00000072,0x00040047,0x00000010,0x0000001e,0x00000000,0x00030047,0x00000013,
0x00000002,0x00050048,0x00000013,0x00000000,0x00000023,0x00000000,0x00050048,0x00000013,
0x00000001,0x00000023,0x00000010,0x00050048,0x00000013,0x00000002,0x00000023,0x00000020,
0x00050048,0x00000013,0x00000003,0x00000023,0x00000030,0x00050048,0x00000013,0x00000004,
0x00000023,0x00000040,0x00050048,0x00000013,0x00000005,0x00000023,0x00000050,0x00050048,
0x00000013,0x00000006,0x00000023,0x00000060,0x00050048,0x00000013,0x00000007,0x00000023,
0x00000070,0x00040047,0x000000ee,0x00000021,0x00000000,0x00040047,0x000000ee,0x00000022,
0x00000000,0x00040047,0x0000013d,0x00000021,0x00000001,0x00040047,0x0000013d,0x00000022,
0x00000000,0x00040047,0x00000146,0x00000021,0x00000002,0x00040047,0x00000146,0x00000022,
0x00000000,0x00040047,0x0000019e,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,
0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000188,
0x0000031c,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,
0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000b,0x745f7170,0x696e5f6f,0x76287374,
0x003b3366,0x00030005,0x0000000a,0x00000065,0x00060005,0x00000010,0x7374696e,0x5f6f745f,
0x66287170,0x00003b31,0x00040005,0x0000000f,0x7374696e,0x00000000,0x00070005,0x00000013,
0x5f676c68,0x6e5f6f74,0x28737469,0x3b336676,0x00000000,0x00030005,0x00000012,0x00000065,
0x00070005,0x00000016,0x7374696e,0x5f6f745f,0x28337170,0x3b336676,0x00000000,0x00040005,
0x00000015,0x7374696e,0x00000000,0x00070005,0x00000019,0x705f6f74,0x756f5f71,0x74757074,
0x33667628,0x0000003b,0x00030005,0x00000018,0x00000065,0x00060005,0x0000001c,0x5f726468,
0x735f6f74,0x76287264,0x003b3366,0x00030005,0x0000001b,0x00000065,0x00050005,0x00000020,
0x6e727574,0x755f6465,0x00002876,0x00060005,0x00000022,0x65687073,0x61636972,0x76755f6c,
0x00000028,0x00030005,0x00000024,0x00000070,0x00030005,0x00000042,0x00000079,0x00030005,
0x00000057,0x00000073,0x00030005,0x00000071,0x00007379,0x00030005,0x00000083,0x00000079,
0x00040005,0x0000009b,0x68737550,0x00000000,0x00050006,0x0000009b,0x00000000,0x30776f72,
0x00000000,0x00050006,0x0000009b,0x00000001,0x31776f72,0x00000000,0x00050006,0x0000009b,
0x00000002,0x32776f72,0x00000000,0x00050006,0x0000009b,0x00000003,0x61726170,0x0000736d,
0x00060006,0x0000009b,0x00000004,0x735f7675,0x656c6163,0x00000000,0x00050006,0x0000009b,
0x00000005,0x756a6461,0x00007473,0x00050006,0x0000009b,0x00000006,0x77656976,0x00000000,
0x00050006,0x0000009b,0x00000007,0x726f6678,0x0000006d,0x00040006,0x0000009b,0x00000008,
0x00726468,0x00050006,0x0000009b,0x00000009,0x7074756f,0x00000000,0x00030005,0x0000009d,
0x00006370,0x00040005,0x000000bd,0x7374696e,0x00000000,0x00040005,0x000000c4,0x61726170,
0x0000006d,0x00040005,0x000000c8,0x61726170,0x0000006d,0x00040005,0x000000eb,0x61726170,
0x0000006d,0x00040005,0x000000f0,0x7374696e,0x00000000,0x00040005,0x000000f7,0x61726170,
0x0000006d,0x00040005,0x000000fb,0x61726170,0x0000006d,0x00040005,0x000000ff,0x6b616570,
0x00000000,0x00030005,0x00000103,0x00676973,0x00030005,0x00000113,0x00637273,0x00040005,
0x00000114,0x61726170,0x0000006d,0x00030005,0x00000117,0x00003165,0x00040005,0x00000118,
0x61726170,0x0000006d,0x00040005,0x0000011e,0x6c78616d,0x00000000,0x00040005,0x0000011f,
0x61726170,0x0000006d,0x00030005,0x00000123,0x0000736b,0x00030005,0x00000127,0x00003265,
0x00030005,0x0000012e,0x00000074,0x00030005,0x00000135,0x00003274,0x00030005,0x00000139,
0x00003374,0x00040005,0x0000015d,0x61726170,0x0000006d,0x00030005,0x00000164,0x006e696c,
0x00030005,0x00000186,0x0000006e,0x00030005,0x00000188,0x00007675,0x00030005,0x000001a3,
0x00000071,0x00030005,0x000001d2,0x0063646e,0x00030005,0x000001da,0x00000064,0x00030005,
0x000001ed,0x00007063,0x00030005,0x000001f1,0x00007073,0x00030005,0x0000020b,0x00007963,
0x00030005,0x0000020f,0x00007973,0x00030005,0x00000229,0x006e6f6c,0x00030005,0x0000022f,
0x0074616c,0x00030005,0x00000243,0x00000073,0x00030005,0x00000246,0x00007461,0x00030005,
0x00000251,0x00000079,0x00040005,0x00000255,0x5f786574,0x00000079,0x00030005,0x00000261,
0x00000074,0x00040005,0x0000026a,0x756f7261,0x0000646e,0x00030005,0x0000026b,0x00007964,
0x00030005,0x00000274,0x00007864,0x00040005,0x000002a2,0x6f726863,0x0000616d,0x00040005,
0x000002a9,0x5f786574,0x00000075,0x00040005,0x000002b3,0x5f786574,0x00000076,0x00030005,
0x000002ba,0x00000075,0x00030005,0x000002c0,0x00000076,0x00030005,0x000002df,0x00000063,
0x00030005,0x000002e3,0x00006e73,0x00030005,0x000002e7,0x00327675,0x00030005,0x000002fa,
0x00767579,0x00030005,0x00000300,0x00626772,0x00040005,0x0000031c,0x6f6c6f63,0x00000072,
0x00040005,0x0000031d,0x61726170,0x0000006d,0x00040005,0x0000032a,0x61726170,0x0000006d,
0x00030047,0x0000009b,0x00000002,0x00050048,0x0000009b,0x00000000,0x00000023,0x00000000,
0x00050048,0x0000009b,0x00000001,0x00000023,0x00000010,0x00050048,0x0000009b,0x00000002,
0x00000023,0x00000020,0x00050048,0x0000009b,0x00000003,0x00000023,0x00000030,0x00050048,
0x0000009b,0x00000004,0x00000023,0x00000040,0x00050048,0x0000009b,0x00000005,0x00000023,
0x00000050,0x00050048,0x0000009b,0x00000006,0x00000023,0x00000060,0x00050048,0x0000009b,
0x00000007,0x00000023,0x00000070,0x00050048,0x0000009b,0x00000008,0x00000023,0x00000080,
0x00050048,0x0000009b,0x00000009,0x00000023,0x00000090,0x00040047,0x00000188,0x0000001e,
0x00000000,0x00040047,0x00000255,0x00000021,0x00000000,0x00040047,0x00000255,0x00000022,
0x00000000,0x00040047,0x000002a9,0x00000021,0x00000001,0x00040047,0x000002a9,0x00000022,
0x00000000,0x00040047,0x000002b3,0x00000021,0x00000002,0x00040047,0x000002b3,0x00000022,
0x00000000,0x00040047,0x0000031c,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,
0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,
0x00000002,0x00030021,0x00000008,0x00000007,0x00040020,0x0000000d,0x00000007,0x00000007,
0x00040020,0x0000000f,0x00000001,0x00000007,0x0004003b,0x0000000f,0x00000010,0x00000001,
0x00040017,0x00000012,0x00000006,0x00000004,0x000a001e,0x00000013,0x00000012,0x00000012,
0x00000012,0x00000012,0x00000007,0x00000012,0x00000012,0x00000012,0x00040020,0x00000014,
0x00000009,0x00000013,0x0004003b,0x00000014,0x00000015,0x00000009,0x00040015,0x00000016,
0x00000020,0x00000001,0x0004002b,0x00000016,0x00000017,0x00000004,0x00040020,0x00000018,
0x00000009,0x00000007,0x0004002b,0x00000016,0x0000001c,0x00000007,0x00040015,0x0000001d,
0x00000020,0x00000000,0x0004002b,0x0000001d,0x0000001e,0x00000001,0x00040020,0x0000001f,
0x00000009,0x00000006,0x0004002b,0x00000006,0x00000022,0x3f000000,0x00020014,0x00000023,
0x0004002b,0x00000006,0x00000027,0x3f800000,0x0004002b,0x0000001d,0x00000028,0x00000000,
0x00040020,0x00000029,0x00000007,0x00000006,0x0004002b,0x0000001d,0x0000002e,0x00000002,
0x00040020,0x00000038,0x00000007,0x00000016,0x0004002b,0x00000016,0x0000003f,0x00000001,
0x0004002b,0x00000016,0x0000004b,0x00000002,0x0004002b,0x00000016,0x00000058,0x00000003,
0x0004002b,0x00000006,0x0000006d,0x40000000,0x00040017,0x00000071,0x00000006,0x00000003,
0x00040020,0x00000072,0x00000007,0x00000071,0x0004002b,0x00000016,0x00000076,0x00000006,
0x0004002b,0x0000001d,0x0000007a,0x00000003,0x0004002b,0x00000006,0x000000cb,0xbf800000,
0x0004002b,0x00000006,0x000000cf,0x40c90fdb,0x0004002b,0x00000006,0x000000d3,0x40490fdb,
0x00090019,0x000000eb,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,
0x00000000,0x0003001b,0x000000ec,0x000000eb,0x00040020,0x000000ed,0x00000000,0x000000ec,
0x0004003b,0x000000ed,0x000000ee,0x00000000,0x0004002b,0x00000006,0x000000f7,0x00000000,
0x0004002b,0x00000016,0x000000fd,0x00000000,0x00040017,0x000000ff,0x00000016,0x00000002,
0x0004002b,0x00000016,0x00000106,0xffffffff,0x0004002b,0x00000006,0x00000132,0x3e000000,
0x0004003b,0x000000ed,0x0000013d,0x00000000,0x0004003b,0x000000ed,0x00000146,0x00000000,
0x0004002b,0x00000006,0x00000154,0x3d808081,0x0004002b,0x00000006,0x00000156,0x3f950a85,
0x0004002b,0x00000006,0x00000158,0x3f91b6db,0x0004002b,0x00000016,0x0000015f,0x00000005,
0x00040020,0x00000189,0x00000009,0x00000012,0x00040020,0x0000019d,0x00000003,0x00000012,
0x0004003b,0x0000019d,0x0000019e,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,
0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000029,0x000000dc,0x00000007,0x0004003b,
0x0000000d,0x000000df,0x00000007,0x0004003b,0x0000000d,0x000000e3,0x00000007,0x0004003b,
0x00000029,0x000000ea,0x00000007,0x0004003b,0x0000000d,0x000000fb,0x00000007,0x0004003b,
0x00000029,0x00000104,0x00000007,0x0004003b,0x00000038,0x00000105,0x00000007,0x0004003b,
0x00000038,0x0000010e,0x00000007,0x0004003b,0x00000029,0x0000013c,0x00000007,0x0004003b,
0x00000029,0x00000145,0x00000007,0x0004003b,0x00000029,0x00000167,0x00000007,0x0004003b,
0x00000029,0x0000016b,0x00000007,0x0004003b,0x0000000d,0x0000016f,0x00000007,0x0004003b,
0x00000072,0x00000182,0x00000007,0x0004003b,0x00000072,0x00000188,0x00000007,0x00060041,
0x0000001f,0x000000dd,0x00000015,0x00000058,0x00000028,0x0004003d,0x00000006,0x000000de,
0x000000dd,0x0003003e,0x000000dc,0x000000de,0x00060041,0x0000001f,0x000000e0,0x00000015,
0x00000058,0x0000007a,0x0004003d,0x00000006,0x000000e1,0x000000e0,0x000500ba,0x00000023,
0x000000e2,0x000000e1,0x00000022,0x000300f7,0x000000e5,0x00000000,0x000400fa,0x000000e2,
0x000000e4,0x000000e7,0x000200f8,0x000000e4,0x00040039,0x00000007,0x000000e6,0x0000000b,
0x0003003e,0x000000e3,0x000000e6,0x000200f9,0x000000e5,0x000200f8,0x000000e7,0x00040039,
0x00000007,0x000000e8,0x00000009,0x0003003e,0x000000e3,0x000000e8,0x000200f9,0x000000e5,
0x000200f8,0x000000e5,0x0004003d,0x00000007,0x000000e9,0x000000e3,0x0003003e,0x000000df,
0x000000e9,0x0004003d,0x000000ec,0x000000ef,0x000000ee,0x0004003d,0x00000007,0x000000f0,
0x000000df,0x00050057,0x00000012,0x000000f1,0x000000ef,0x000000f0,0x00050051,0x00000006,
0x000000f2,0x000000f1,0x00000000,0x0004003d,0x00000006,0x000000f3,0x000000dc,0x00050085,
0x00000006,0x000000f4,0x000000f2,0x000000f3,0x0003003e,0x000000ea,0x000000f4,0x00060041,
0x0000001f,0x000000f5,0x00000015,0x0000001c,0x0000007a,0x0004003d,0x00000006,0x000000f6,
0x000000f5,0x000500ba,0x00000023,0x000000f8,0x000000f6,0x000000f7,0x000300f7,0x000000fa,
0x00000000,0x000400fa,0x000000f8,0x000000f9,0x000000fa,0x000200f8,0x000000f9,0x0004003d,
0x000000ec,0x000000fc,0x000000ee,0x00040064,0x000000eb,0x000000fe,0x000000fc,0x00050067,
0x000000ff,0x00000100,0x000000fe,0x000000fd,0x0004006f,0x00000007,0x00000101,0x00000100,
0x00050050,0x00000007,0x00000102,0x00000027,0x00000027,0x00050088,0x00000007,0x00000103,
0x00000102,0x00000101,0x0003003e,0x000000fb,0x00000103,0x0003003e,0x00000104,0x000000f7,
0x0003003e,0x00000105,0x00000106,0x000200f9,0x00000107,0x000200f8,0x00000107,0x000400f6,
0x00000109,0x0000010a,0x00000000,0x000200f9,0x0000010b,0x000200f8,0x0000010b,0x0004003d,
0x00000016,0x0000010c,0x00000105,0x000500b3,0x00000023,0x0000010d,0x0000010c,0x0000003f,
0x000400fa,0x0000010d,0x00000108,0x00000109,0x000200f8,0x00000108,0x0003003e,0x0000010e,
0x00000106,0x000200f9,0x0000010f,0x000200f8,0x0000010f,0x000400f6,0x00000111,0x00000112,
0x00000000,0x000200f9,0x00000113,0x000200f8,0x00000113,0x0004003d,0x00000016,0x00000114,
0x0000010e,0x000500b3,0x00000023,0x00000115,0x00000114,0x0000003f,0x000400fa,0x00000115,
0x00000110,0x00000111,0x000200f8,0x00000110,0x0004003d,0x00000016,0x00000116,0x0000010e,
0x000500ab,0x00000023,0x00000117,0x00000116,0x000000fd,0x0004003d,0x00000016,0x00000118,
0x00000105,0x000500ab,0x00000023,0x00000119,0x00000118,0x000000fd,0x000500a6,0x00000023,
0x0000011a,0x00000117,0x00000119,0x000300f7,0x0000011c,0x00000000,0x000400fa,0x0000011a,
0x0000011b,0x0000011c,0x000200f8,0x0000011b,0x0004003d,0x000000ec,0x0000011d,0x000000ee,
0x0004003d,0x00000007,0x0000011e,0x000000df,0x0004003d,0x00000016,0x0000011f,0x0000010e,
0x0004006f,0x00000006,0x00000120,0x0000011f,0x0004003d,0x00000016,0x00000121,0x00000105,
0x0004006f,0x00000006,0x00000122,0x00000121,0x00050050,0x00000007,0x00000123,0x00000120,
0x00000122,0x0004003d,0x00000007,0x00000124,0x000000fb,0x00050085,0x00000007,0x00000125,
0x00000123,0x00000124,0x00050081,0x00000007,0x00000126,0x0000011e,0x00000125,0x00050057,
0x00000012,0x00000127,0x0000011d,0x00000126,0x00050051,0x00000006,0x00000128,0x00000127,
0x00000000,0x0004003d,0x00000006,0x00000129,0x00000104,0x00050081,0x00000006,0x0000012a,
0x00000129,0x00000128,0x0003003e,0x00000104,0x0000012a,0x000200f9,0x0000011c,0x000200f8,
0x0000011c,0x000200f9,0x00000112,0x000200f8,0x00000112,0x0004003d,0x00000016,0x0000012b,
0x0000010e,0x00050080,0x00000016,0x0000012c,0x0000012b,0x0000003f,0x0003003e,0x0000010e,
0x0000012c,0x000200f9,0x0000010f,0x000200f8,0x00000111,0x000200f9,0x0000010a,0x000200f8,
0x0000010a,0x0004003d,0x00000016,0x0000012d,0x00000105,0x00050080,0x00000016,0x0000012e,
0x0000012d,0x0000003f,0x0003003e,0x00000105,0x0000012e,0x000200f9,0x00000107,0x000200f8,
0x00000109,0x0004003d,0x00000006,0x0000012f,0x000000ea,0x0004003d,0x00000006,0x00000130,
0x000000ea,0x0004003d,0x00000006,0x00000131,0x00000104,0x00050085,0x00000006,0x00000133,
0x00000131,0x00000132,0x0004003d,0x00000006,0x00000134,0x000000dc,0x00050085,0x00000006,
0x00000135,0x00000133,0x00000134,0x00050083,0x00000006,0x00000136,0x00000130,0x00000135,
0x00060041,0x0000001f,0x00000137,0x00000015,0x0000001c,0x0000007a,0x0004003d,0x00000006,
0x00000138,0x00000137,0x00050085,0x00000006,0x00000139,0x00000136,0x00000138,0x00050081,
0x00000006,0x0000013a,0x0000012f,0x00000139,0x0008000c,0x00000006,0x0000013b,0x00000001,
0x0000002b,0x0000013a,0x000000f7,0x00000027,0x0003003e,0x000000ea,0x0000013b,0x000200f9,
0x000000fa,0x000200f8,0x000000fa,0x0004003d,0x000000ec,0x0000013e,0x0000013d,0x0004003d,
0x00000007,0x0000013f,0x000000df,0x00050057,0x00000012,0x00000140,0x0000013e,0x0000013f,
0x00050051,0x00000006,0x00000141,0x00000140,0x00000000,0x0004003d,0x00000006,0x00000142,
0x000000dc,0x00050085,0x00000006,0x00000143,0x00000141,0x00000142,0x00050083,0x00000006,
0x00000144,0x00000143,0x00000022,0x0003003e,0x0000013c,0x00000144,0x0004003d,0x000000ec,
0x00000147,0x00000146,0x0004003d,0x00000007,0x00000148,0x000000df,0x00050057,0x00000012,
0x00000149,0x00000147,0x00000148,0x00050051,0x00000006,0x0000014a,0x00000149,0x00000000,
0x0004003d,0x00000006,0x0000014b,0x000000dc,0x00050085,0x00000006,0x0000014c,0x0000014a,
0x0000014b,0x00050083,0x00000006,0x0000014d,0x0000014c,0x00000022,0x0003003e,0x00000145,
0x0000014d,0x00060041,0x0000001f,0x0000014e,0x00000015,0x00000058,0x0000001e,0x0004003d,
0x00000006,0x0000014f,0x0000014e,0x000500ba,0x00000023,0x00000150,0x0000014f,0x00000022,
0x000300f7,0x00000152,0x00000000,0x000400fa,0x00000150,0x00000151,0x00000152,0x000200f8,
0x00000151,0x0004003d,0x00000006,0x00000153,0x000000ea,0x00050083,0x00000006,0x00000155,
0x00000153,0x00000154,0x00050085,0x00000006,0x00000157,0x00000155,0x00000156,0x0003003e,
0x000000ea,0x00000157,0x0004003d,0x00000006,0x00000159,0x0000013c,0x00050085,0x00000006,
0x0000015a,0x00000159,0x00000158,0x0003003e,0x0000013c,0x0000015a,0x0004003d,0x00000006,
0x0000015b,0x00000145,0x00050085,0x00000006,0x0000015c,0x0000015b,0x00000158,0x0003003e,
0x00000145,0x0000015c,0x000200f9,0x00000152,0x000200f8,0x00000152,0x0004003d,0x00000006,
0x0000015d,0x000000ea,0x00050083,0x00000006,0x0000015e,0x0000015d,0x00000022,0x00060041,
0x0000001f,0x00000160,0x00000015,0x0000015f,0x0000001e,0x0004003d,0x00000006,0x00000161,
0x00000160,0x00050085,0x00000006,0x00000162,0x0000015e,0x00000161,0x00050081,0x00000006,
0x00000163,0x00000162,0x00000022,0x00060041,0x0000001f,0x00000164,0x00000015,0x0000015f,
0x00000028,0x0004003d,0x00000006,0x00000165,0x00000164,0x00050081,0x00000006,0x00000166,
0x00000163,0x00000165,0x0003003e,0x000000ea,0x00000166,0x00060041,0x0000001f,0x00000168,
0x00000015,0x00000058,0x0000002e,0x0004003d,0x00000006,0x00000169,0x00000168,0x0006000c,
0x00000006,0x0000016a,0x00000001,0x0000000e,0x00000169,0x0003003e,0x00000167,0x0000016a,
0x00060041,0x0000001f,0x0000016c,0x00000015,0x00000058,0x0000002e,0x0004003d,0x00000006,
0x0000016d,0x0000016c,0x0006000c,0x00000006,0x0000016e,0x00000001,0x0000000d,0x0000016d,
0x0003003e,0x0000016b,0x0000016e,0x0004003d,0x00000006,0x00000170,0x0000013c,0x0004003d,
0x00000006,0x00000171,0x00000167,0x00050085,0x00000006,0x00000172,0x00000170,0x00000171,
0x0004003d,0x00000006,0x00000173,0x00000145,0x0004003d,0x00000006,0x00000174,0x0000016b,
0x00050085,0x00000006,0x00000175,0x00000173,0x00000174,0x00050083,0x00000006,0x00000176,
0x00000172,0x00000175,0x0004003d,0x00000006,0x00000177,0x0000013c,0x0004003d,0x00000006,
0x00000178,0x0000016b,0x00050085,0x00000006,0x00000179,0x00000177,0x00000178,0x0004003d,
0x00000006,0x0000017a,0x00000145,0x0004003d,0x00000006,0x0000017b,0x00000167,0x00050085,
0x00000006,0x0000017c,0x0000017a,0x0000017b,0x00050081,0x00000006,0x0000017d,0x00000179,
0x0000017c,0x00050050,0x00000007,0x0000017e,0x00000176,0x0000017d,0x00060041,0x0000001f,
0x0000017f,0x00000015,0x0000015f,0x0000002e,0x0004003d,0x00000006,0x00000180,0x0000017f,
0x0005008e,0x00000007,0x00000181,0x0000017e,0x00000180,0x0003003e,0x0000016f,0x00000181,
0x0004003d,0x00000006,0x00000183,0x000000ea,0x0004003d,0x00000007,0x00000184,0x0000016f,
0x00050051,0x00000006,0x00000185,0x00000184,0x00000000,0x00050051,0x00000006,0x00000186,
0x00000184,0x00000001,0x00060050,0x00000071,0x00000187,0x00000183,0x00000185,0x00000186,
0x0003003e,0x00000182,0x00000187,0x00050041,0x00000189,0x0000018a,0x00000015,0x000000fd,
0x0004003d,0x00000012,0x0000018b,0x0000018a,0x0008004f,0x00000071,0x0000018c,0x0000018b,
0x0000018b,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000071,0x0000018d,0x00000182,
0x00050094,0x00000006,0x0000018e,0x0000018c,0x0000018d,0x00050041,0x00000189,0x0000018f,
0x00000015,0x0000003f,0x0004003d,0x00000012,0x00000190,0x0000018f,0x0008004f,0x00000071,
0x00000191,0x00000190,0x00000190,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000071,
0x00000192,0x00000182,0x00050094,0x00000006,0x00000193,0x00000191,0x00000192,0x00050041,
0x00000189,0x00000194,0x00000015,0x0000004b,0x0004003d,0x00000012,0x00000195,0x00000194,
0x0008004f,0x00000071,0x00000196,0x00000195,0x00000195,0x00000000,0x00000001,0x00000002,
0x0004003d,0x00000071,0x00000197,0x00000182,0x00050094,0x00000006,0x00000198,0x00000196,
0x00000197,0x00060050,0x00000071,0x00000199,0x0000018e,0x00000193,0x00000198,0x00060050,
0x00000071,0x0000019a,0x000000f7,0x000000f7,0x000000f7,0x00060050,0x00000071,0x0000019b,
0x00000027,0x00000027,0x00000027,0x0008000c,0x00000071,0x0000019c,0x00000001,0x0000002b,
0x00000199,0x0000019a,0x0000019b,0x0003003e,0x00000188,0x0000019c,0x0004003d,0x00000071,
0x0000019f,0x00000188,0x00060041,0x0000001f,0x000001a0,0x00000015,0x0000015f,0x0000007a,
0x0004003d,0x00000006,0x000001a1,0x000001a0,0x00060050,0x00000071,0x000001a2,0x000001a1,
0x000001a1,0x000001a1,0x0007000c,0x00000071,0x000001a3,0x00000001,0x0000001a,0x0000019f,
0x000001a2,0x00050051,0x00000006,0x000001a4,0x000001a3,0x00000000,0x00050051,0x00000006,
0x000001a5,0x000001a3,0x00000001,0x00050051,0x00000006,0x000001a6,0x000001a3,0x00000002,
0x00070050,0x00000012,0x000001a7,0x000001a4,0x000001a5,0x000001a6,0x00000027,0x0003003e,
0x0000019e,0x000001a7,0x000100fd,0x00010038,0x00050036,0x00000007,0x00000009,0x00000000,
0x00000008,0x000200f8,0x0000000a,0x0004003b,0x0000000d,0x0000000e,0x00000007,0x0004003b,
0x00000038,0x00000039,0x00000007,0x0004003d,0x00000007,0x00000011,0x00000010,0x00050041,
0x00000018,0x00000019,0x00000015,0x00000017,0x0004003d,0x00000007,0x0000001a,0x00000019,
0x00050088,0x00000007,0x0000001b,0x00000011,0x0000001a,0x0003003e,0x0000000e,0x0000001b,
0x00060041,0x0000001f,0x00000020,0x00000015,0x0000001c,0x0000001e,0x0004003d,0x00000006,
0x00000021,0x00000020,0x000500ba,0x00000023,0x00000024,0x00000021,0x00000022,0x000300f7,
0x00000026,0x00000000,0x000400fa,0x00000024,0x00000025,0x00000026,0x000200f8,0x00000025,
0x00050041,0x00000029,0x0000002a,0x0000000e,0x00000028,0x0004003d,0x00000006,0x0000002b,
0x0000002a,0x00050083,0x00000006,0x0000002c,0x00000027,0x0000002b,0x00050041,0x00000029,
0x0000002d,0x0000000e,0x00000028,0x0003003e,0x0000002d,0x0000002c,0x000200f9,0x00000026,
0x000200f8,0x00000026,0x00060041,0x0000001f,0x0000002f,0x00000015,0x0000001c,0x0000002e,
0x0004003d,0x00000006,0x00000030,0x0000002f,0x000500ba,0x00000023,0x00000031,0x00000030,
0x00000022,0x000300f7,0x00000033,0x00000000,0x000400fa,0x00000031,0x00000032,0x00000033,
0x000200f8,0x00000032,0x00050041,0x00000029,0x00000034,0x0000000e,0x0000001e,0x0004003d,
0x00000006,0x00000035,0x00000034,0x00050083,0x00000006,0x00000036,0x00000027,0x00000035,
0x00050041,0x00000029,0x00000037,0x0000000e,0x0000001e,0x0003003e,0x00000037,0x00000036,
0x000200f9,0x00000033,0x000200f8,0x00000033,0x00060041,0x0000001f,0x0000003a,0x00000015,
0x0000001c,0x00000028,0x0004003d,0x00000006,0x0000003b,0x0000003a,0x00050081,0x00000006,
0x0000003c,0x0000003b,0x00000022,0x0004006e,0x00000016,0x0000003d,0x0000003c,0x0003003e,
0x00000039,0x0000003d,0x0004003d,0x00000016,0x0000003e,0x00000039,0x000500aa,0x00000023,
0x00000040,0x0000003e,0x0000003f,0x000300f7,0x00000042,0x00000000,0x000400fa,0x00000040,
0x00000041,0x00000049,0x000200f8,0x00000041,0x00050041,0x00000029,0x00000043,0x0000000e,
0x0000001e,0x0004003d,0x00000006,0x00000044,0x00000043,0x00050041,0x00000029,0x00000045,
0x0000000e,0x00000028,0x0004003d,0x00000006,0x00000046,0x00000045,0x00050083,0x00000006,
0x00000047,0x00000027,0x00000046,0x00050050,0x00000007,0x00000048,0x00000044,0x00000047,
0x0003003e,0x0000000e,0x00000048,0x000200f9,0x00000042,0x000200f8,0x00000049,0x0004003d,
0x00000016,0x0000004a,0x00000039,0x000500aa,0x00000023,0x0000004c,0x0000004a,0x0000004b,
0x000300f7,0x0000004e,0x00000000,0x000400fa,0x0000004c,0x0000004d,0x00000056,0x000200f8,
0x0000004d,0x00050041,0x00000029,0x0000004f,0x0000000e,0x00000028,0x0004003d,0x00000006,
0x00000050,0x0000004f,0x00050083,0x00000006,0x00000051,0x00000027,0x00000050,0x00050041,
0x00000029,0x00000052,0x0000000e,0x0000001e,0x0004003d,0x00000006,0x00000053,0x00000052,
0x00050083,0x00000006,0x00000054,0x00000027,0x00000053,0x00050050,0x00000007,0x00000055,
0x00000051,0x00000054,0x0003003e,0x0000000e,0x00000055,0x000200f9,0x0000004e,0x000200f8,
0x00000056,0x0004003d,0x00000016,0x00000057,0x00000039,0x000500aa,0x00000023,0x00000059,
0x00000057,0x00000058,0x000300f7,0x0000005b,0x00000000,0x000400fa,0x00000059,0x0000005a,
0x0000005b,0x000200f8,0x0000005a,0x00050041,0x00000029,0x0000005c,0x0000000e,0x0000001e,
0x0004003d,0x00000006,0x0000005d,0x0000005c,0x00050083,0x00000006,0x0000005e,0x00000027,
0x0000005d,0x00050041,0x00000029,0x0000005f,0x0000000e,0x00000028,0x0004003d,0x00000006,
0x00000060,0x0000005f,0x00050050,0x00000007,0x00000061,0x0000005e,0x00000060,0x0003003e,
0x0000000e,0x00000061,0x000200f9,0x0000005b,0x000200f8,0x0000005b,0x000200f9,0x0000004e,
0x000200f8,0x0000004e,0x000200f9,0x00000042,0x000200f8,0x00000042,0x0004003d,0x00000007,
0x00000062,0x0000000e,0x00050041,0x00000018,0x00000063,0x00000015,0x00000017,0x0004003d,
0x00000007,0x00000064,0x00000063,0x00050085,0x00000007,0x00000065,0x00000062,0x00000064,
0x000200fe,0x00000065,0x00010038,0x00050036,0x00000007,0x0000000b,0x00000000,0x00000008,
0x000200f8,0x0000000c,0x0004003b,0x0000000d,0x00000068,0x00000007,0x0004003b,0x00000072,
0x00000073,0x00000007,0x0004003b,0x00000029,0x00000086,0x00000007,0x0004003b,0x00000029,
0x0000008a,0x00000007,0x0004003b,0x00000029,0x000000a4,0x00000007,0x0004003b,0x00000029,
0x000000a8,0x00000007,0x0004003b,0x00000029,0x000000c2,0x00000007,0x0004003b,0x00000029,
0x000000c8,0x00000007,0x0004003d,0x00000007,0x00000069,0x00000010,0x00050041,0x00000018,
0x0000006a,0x00000015,0x00000017,0x0004003d,0x00000007,0x0000006b,0x0000006a,0x00050088,
0x00000007,0x0000006c,0x00000069,0x0000006b,0x0005008e,0x00000007,0x0000006e,0x0000006c,
0x0000006d,0x00050050,0x00000007,0x0000006f,0x00000027,0x00000027,0x00050083,0x00000007,
0x00000070,0x0000006e,0x0000006f,0x0003003e,0x00000068,0x00000070,0x00050041,0x00000029,
0x00000074,0x00000068,0x00000028,0x0004003d,0x00000006,0x00000075,0x00000074,0x00060041,
0x0000001f,0x00000077,0x00000015,0x00000076,0x0000002e,0x0004003d,0x00000006,0x00000078,
0x00000077,0x00050085,0x00000006,0x00000079,0x00000075,0x00000078,0x00060041,0x0000001f,
0x0000007b,0x00000015,0x00000076,0x0000007a,0x0004003d,0x00000006,0x0000007c,0x0000007b,
0x00050085,0x00000006,0x0000007d,0x00000079,0x0000007c,0x00050041,0x00000029,0x0000007e,
0x00000068,0x0000001e,0x0004003d,0x00000006,0x0000007f,0x0000007e,0x0004007f,0x00000006,
0x00000080,0x0000007f,0x00060041,0x0000001f,0x00000081,0x00000015,0x00000076,0x0000002e,
0x0004003d,0x00000006,0x00000082,0x00000081,0x00050085,0x00000006,0x00000083,0x00000080,
0x00000082,0x00060050,0x00000071,0x00000084,0x0000007d,0x00000083,0x00000027,0x0006000c,
0x00000071,0x00000085,0x00000001,0x00000045,0x00000084,0x0003003e,0x00000073,0x00000085,
0x00060041,0x0000001f,0x00000087,0x00000015,0x00000076,0x0000001e,0x0004003d,0x00000006,
0x00000088,0x00000087,0x0006000c,0x00000006,0x00000089,0x00000001,0x0000000e,0x00000088,
0x0003003e,0x00000086,0x00000089,0x00060041,0x0000001f,0x0000008b,0x00000015,0x00000076,
0x0000001e,0x0004003d,0x00000006,0x0000008c,0x0000008b,0x0006000c,0x00000006,0x0000008d,
0x00000001,0x0000000d,0x0000008c,0x0003003e,0x0000008a,0x0000008d,0x00050041,0x00000029,
0x0000008e,0x00000073,0x00000028,0x0004003d,0x00000006,0x0000008f,0x0000008e,0x00050041,
0x00000029,0x00000090,0x00000073,0x0000001e,0x0004003d,0x00000006,0x00000091,0x00000090,
0x0004003d,0x00000006,0x00000092,0x00000086,0x00050085,0x00000006,0x00000093,0x00000091,
0x00000092,0x00050041,0x00000029,0x00000094,0x00000073,0x0000002e,0x0004003d,0x00000006,
0x00000095,0x00000094,0x0004003d,0x00000006,0x00000096,0x0000008a,0x00050085,0x00000006,
0x00000097,0x00000095,0x00000096,0x00050081,0x00000006,0x00000098,0x00000093,0x00000097,
0x00050041,0x00000029,0x00000099,0x00000073,0x0000001e,0x0004003d,0x00000006,0x0000009a,
0x00000099,0x0004007f,0x00000006,0x0000009b,0x0000009a,0x0004003d,0x00000006,0x0000009c,
0x0000008a,0x00050085,0x00000006,0x0000009d,0x0000009b,0x0000009c,0x00050041,0x00000029,
0x0000009e,0x00000073,0x0000002e,0x0004003d,0x00000006,0x0000009f,0x0000009e,0x0004003d,
0x00000006,0x000000a0,0x00000086,0x00050085,0x00000006,0x000000a1,0x0000009f,0x000000a0,
0x00050081,0x00000006,0x000000a2,0x0000009d,0x000000a1,0x00060050,0x00000071,0x000000a3,
0x0000008f,0x00000098,0x000000a2,0x0003003e,0x00000073,0x000000a3,0x00060041,0x0000001f,
0x000000a5,0x00000015,0x00000076,0x00000028,0x0004003d,0x00000006,0x000000a6,0x000000a5,
0x0006000c,0x00000006,0x000000a7,0x00000001,0x0000000e,0x000000a6,0x0003003e,0x000000a4,
0x000000a7,0x00060041,0x0000001f,0x000000a9,0x00000015,0x00000076,0x00000028,0x0004003d,
0x00000006,0x000000aa,0x000000a9,0x0006000c,0x00000006,0x000000ab,0x00000001,0x0000000d,
0x000000aa,0x0003003e,0x000000a8,0x000000ab,0x00050041,0x00000029,0x000000ac,0x00000073,
0x00000028,0x0004003d,0x00000006,0x000000ad,0x000000ac,0x0004003d,0x00000006,0x000000ae,
0x000000a4,0x00050085,0x00000006,0x000000af,0x000000ad,0x000000ae,0x00050041,0x00000029,
0x000000b0,0x00000073,0x0000002e,0x0004003d,0x00000006,0x000000b1,0x000000b0,0x0004003d,
0x00000006,0x000000b2,0x000000a8,0x00050085,0x00000006,0x000000b3,0x000000b1,0x000000b2,
0x00050081,0x00000006,0x000000b4,0x000000af,0x000000b3,0x00050041,0x00000029,0x000000b5,
0x00000073,0x0000001e,0x0004003d,0x00000006,0x000000b6,0x000000b5,0x00050041,0x00000029,
0x000000b7,0x00000073,0x00000028,0x0004003d,0x00000006,0x000000b8,0x000000b7,0x0004007f,
0x00000006,0x000000b9,0x000000b8,0x0004003d,0x00000006,0x000000ba,0x000000a8,0x00050085,
0x00000006,0x000000bb,0x000000b9,0x000000ba,0x00050041,0x00000029,0x000000bc,0x00000073,
0x0000002e,0x0004003d,0x00000006,0x000000bd,0x000000bc,0x0004003d,0x00000006,0x000000be,
0x000000a4,0x00050085,0x00000006,0x000000bf,0x000000bd,0x000000be,0x00050081,0x00000006,
0x000000c0,0x000000bb,0x000000bf,0x00060050,0x00000071,0x000000c1,0x000000b4,0x000000b6,
0x000000c0,0x0003003e,0x00000073,0x000000c1,0x00050041,0x00000029,0x000000c3,0x00000073,
0x00000028,0x0004003d,0x00000006,0x000000c4,0x000000c3,0x00050041,0x00000029,0x000000c5,
0x00000073,0x0000002e,0x0004003d,0x00000006,0x000000c6,0x000000c5,0x0007000c,0x00000006,
0x000000c7,0x00000001,0x00000019,0x000000c4,0x000000c6,0x0003003e,0x000000c2,0x000000c7,
0x00050041,0x00000029,0x000000c9,0x00000073,0x0000001e,0x0004003d,0x00000006,0x000000ca,
0x000000c9,0x0008000c,0x00000006,0x000000cc,0x00000001,0x0000002b,0x000000ca,0x000000cb,
0x00000027,0x0006000c,0x00000006,0x000000cd,0x00000001,0x00000010,0x000000cc,0x0003003e,
0x000000c8,0x000000cd,0x0004003d,0x00000006,0x000000ce,0x000000c2,0x00050088,0x00000006,
0x000000d0,0x000000ce,0x000000cf,0x00050081,0x00000006,0x000000d1,0x000000d0,0x00000022,
0x0004003d,0x00000006,0x000000d2,0x000000c8,0x00050088,0x00000006,0x000000d4,0x000000d2,
0x000000d3,0x00050083,0x00000006,0x000000d5,0x00000022,0x000000d4,0x00050050,0x00000007,
0x000000d6,0x000000d1,0x000000d5,0x00050041,0x00000018,0x000000d7,0x00000015,0x00000017,
0x0004003d,0x00000007,0x000000d8,0x000000d7,0x00050085,0x00000007,0x000000d9,0x000000d6,
0x000000d8,0x000200fe,0x000000d9,0x00010038
0x00000003,0x00040020,0x00000008,0x00000007,0x00000007,0x00040021,0x00000009,0x00000007,
0x00000008,0x00040020,0x0000000d,0x00000007,0x00000006,0x00040021,0x0000000e,0x00000006,
0x0000000d,0x00040017,0x0000001e,0x00000006,0x00000002,0x00030021,0x0000001f,0x0000001e,
0x0004002b,0x00000006,0x00000026,0x00000000,0x0004002b,0x00000006,0x00000027,0x3f800000,
0x0004002b,0x00000006,0x0000002b,0x3c4fcdac,0x0006002c,0x00000007,0x0000002c,0x0000002b,
0x0000002b,0x0000002b,0x0004002b,0x00000006,0x0000002e,0x461c4000,0x0004002b,0x00000006,
0x00000030,0x3f560000,0x0004002b,0x00000006,0x00000035,0x4196d000,0x0004002b,0x00000006,
0x00000036,0x41958000,0x0004002b,0x00000006,0x0000003c,0x40c8e06b,0x0006002c,0x00000007,
0x0000003d,0x0000003c,0x0000003c,0x0000003c,0x0004002b,0x00000006,0x00000046,0x3e232000,
0x0004002b,0x00000006,0x0000004f,0x429db000,0x0004002b,0x00000006,0x0000005b,0x40400000,
0x0004002b,0x00000006,0x0000005f,0x3f0f564f,0x0004002b,0x00000006,0x00000062,0x3e371ff0,
0x0004002b,0x00000006,0x00000066,0x3e91c020,0x0004002b,0x00000006,0x00000069,0x41400000,
0x0004002b,0x00000006,0x0000006c,0x3f000000,0x0006002c,0x00000007,0x0000006d,0x0000006c,
0x0000006c,0x0000006c,0x0004002b,0x00000006,0x00000073,0x3e86809d,0x0004002b,0x00000006,
0x00000074,0x3f2d9168,0x0004002b,0x00000006,0x00000075,0x3d72e48f,0x0006002c,0x00000007,
0x00000076,0x00000073,0x00000074,0x00000075,0x0004002b,0x00000006,0x00000078,0x358637bd,
0x0004002b,0x00000006,0x0000007a,0x447a0000,0x0004002b,0x00000006,0x0000007c,0x3e4ccccd,
0x0006002c,0x00000007,0x0000008a,0x00000046,0x00000046,0x00000046,0x0006002c,0x00000007,
0x00000095,0x0000004f,0x0000004f,0x0000004f,0x00020014,0x00000099,0x00040017,0x0000009a,
0x00000006,0x00000004,0x000c001e,0x0000009b,0x0000009a,0x0000009a,0x0000009a,0x0000009a,
0x0000001e,0x0000009a,0x0000009a,0x0000009a,0x0000009a,0x0000009a,0x00040020,0x0000009c,
0x00000009,0x0000009b,0x0004003b,0x0000009c,0x0000009d,0x00000009,0x00040015,0x0000009e,
0x00000020,0x00000001,0x0004002b,0x0000009e,0x0000009f,0x00000008,0x00040015,0x000000a0,
0x00000020,0x00000000,0x0004002b,0x000000a0,0x000000a1,0x00000000,0x00040020,0x000000a2,
0x00000009,0x00000006,0x0004002b,0x00000006,0x000000aa,0x3fc00000,0x0004002b,0x000000a0,
0x000000af,0x00000002,0x0004002b,0x00000006,0x000000d1,0x4019999a,0x0006002c,0x00000007,
0x000000d2,0x000000d1,0x000000d1,0x000000d1,0x0004002b,0x00000006,0x000000d4,0x434b0000,
0x00040018,0x000000db,0x00000007,0x00000003,0x0004002b,0x00000006,0x000000dc,0x3f209d49,
0x0004002b,0x00000006,0x000000dd,0x3d8d844d,0x0004002b,0x00000006,0x000000de,0x3c86594b,
0x0006002c,0x00000007,0x000000df,0x000000dc,0x000000dd,0x000000de,0x0004002b,0x00000006,
0x000000e0,0x3ea89a02,0x0004002b,0x00000006,0x000000e1,0x3f6b645a,0x0004002b,0x00000006,
0x000000e2,0x3db43958,0x0006002c,0x00000007,0x000000e3,0x000000e0,0x000000e1,0x000000e2,
0x0004002b,0x00000006,0x000000e4,0x3d315b57,0x0004002b,0x00000006,0x000000e5,0x3c3ac711,
0x0004002b,0x00000006,0x000000e6,0x3f65460b,0x0006002c,0x00000007,0x000000e7,0x000000e4,
0x000000e5,0x000000e6,0x0006002c,0x000000db,0x000000e8,0x000000df,0x000000e3,0x000000e7,
0x0004002b,0x000000a0,0x00000100,0x00000001,0x0004002b,0x00000006,0x0000013d,0x40000000,
0x0004002b,0x00000006,0x00000150,0xc0000000,0x0004002b,0x00000006,0x0000016d,0x3fd48b44,
0x0004002b,0x00000006,0x0000016e,0xbdff2e49,0x0004002b,0x00000006,0x0000016f,0xbc95182b,
0x0006002c,0x00000007,0x00000170,0x0000016d,0x0000016e,0x0000016f,0x0004002b,0x00000006,
0x00000171,0xbf166cf4,0x0004002b,0x00000006,0x00000172,0x3f9102de,0x0004002b,0x00000006,
0x00000173,0xbdce075f,0x0006002c,0x00000007,0x00000174,0x00000171,0x00000172,0x00000173,
0x0004002b,0x00000006,0x00000175,0xbd95182b,0x0004002b,0x00000006,0x00000176,0xbc07fcb9,
0x0004002b,0x00000006,0x00000177,0x3f8f3190,0x0006002c,0x00000007,0x00000178,0x00000175,
0x00000176,0x00000177,0x0006002c,0x000000db,0x00000179,0x00000170,0x00000174,0x00000178,
0x0004002b,0x00000006,0x00000180,0x3ed55555,0x0006002c,0x00000007,0x00000181,0x00000180,
0x00000180,0x00000180,0x00040020,0x00000185,0x00000007,0x0000001e,0x00040020,0x00000187,
0x00000001,0x0000001e,0x0004003b,0x00000187,0x00000188,0x00000001,0x0004002b,0x0000009e,
0x0000018a,0x00000004,0x00040020,0x0000018b,0x00000009,0x0000001e,0x0004002b,0x0000009e,
0x0000018f,0x00000007,0x00040020,0x000001a2,0x00000007,0x0000009e,0x0004002b,0x0000009e,
0x000001a9,0x00000001,0x0004002b,0x0000009e,0x000001b5,0x00000002,0x0004002b,0x0000009e,
0x000001c2,0x00000003,0x0004002b,0x0000009e,0x000001dd,0x00000006,0x0004002b,0x000000a0,
0x000001e1,0x00000003,0x0004002b,0x00000006,0x00000232,0xbf800000,0x0004002b,0x00000006,
0x00000236,0x40c90fdb,0x0004002b,0x00000006,0x0000023a,0x40490fdb,0x00090019,0x00000252,
0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x0003001b,
0x00000253,0x00000252,0x00040020,0x00000254,0x00000000,0x00000253,0x0004003b,0x00000254,
0x00000255,0x00000000,0x0004002b,0x0000009e,0x00000263,0x00000000,0x00040017,0x00000265,
0x0000009e,0x00000002,0x0004002b,0x0000009e,0x0000026c,0xffffffff,0x0004002b,0x00000006,
0x00000298,0x3e000000,0x0004003b,0x00000254,0x000002a9,0x00000000,0x0004003b,0x00000254,
0x000002b3,0x00000000,0x0004002b,0x00000006,0x000002cc,0x3d808081,0x0004002b,0x00000006,
0x000002ce,0x3f950a85,0x0004002b,0x00000006,0x000002d0,0x3f91b6db,0x0004002b,0x0000009e,
0x000002d7,0x00000005,0x00040020,0x00000301,0x00000009,0x0000009a,0x0004002b,0x0000009e,
0x00000315,0x00000009,0x00040020,0x0000031b,0x00000003,0x0000009a,0x0004003b,0x0000031b,
0x0000031c,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,
0x00000005,0x0004003b,0x0000000d,0x00000243,0x00000007,0x0004003b,0x00000185,0x00000246,
0x00000007,0x0004003b,0x00000185,0x0000024a,0x00000007,0x0004003b,0x0000000d,0x00000251,
0x00000007,0x0004003b,0x00000185,0x00000261,0x00000007,0x0004003b,0x0000000d,0x0000026a,
0x00000007,0x0004003b,0x000001a2,0x0000026b,0x00000007,0x0004003b,0x000001a2,0x00000274,
0x00000007,0x0004003b,0x00000185,0x000002a2,0x00000007,0x0004003b,0x00000185,0x000002a6,
0x00000007,0x0004003b,0x0000000d,0x000002ba,0x00000007,0x0004003b,0x0000000d,0x000002c0,
0x00000007,0x0004003b,0x0000000d,0x000002df,0x00000007,0x0004003b,0x0000000d,0x000002e3,
0x00000007,0x0004003b,0x00000185,0x000002e7,0x00000007,0x0004003b,0x00000008,0x000002fa,
0x00000007,0x0004003b,0x00000008,0x00000300,0x00000007,0x0004003b,0x00000008,0x0000031d,
0x00000007,0x0004003b,0x00000008,0x0000032a,0x00000007,0x00060041,0x000000a2,0x00000244,
0x0000009d,0x000001c2,0x000000a1,0x0004003d,0x00000006,0x00000245,0x00000244,0x0003003e,
0x00000243,0x00000245,0x00060041,0x000000a2,0x00000247,0x0000009d,0x000001c2,0x000001e1,
0x0004003d,0x00000006,0x00000248,0x00000247,0x000500ba,0x00000099,0x00000249,0x00000248,
0x0000006c,0x000300f7,0x0000024c,0x00000000,0x000400fa,0x00000249,0x0000024b,0x0000024e,
0x000200f8,0x0000024b,0x00040039,0x0000001e,0x0000024d,0x00000022,0x0003003e,0x0000024a,
0x0000024d,0x000200f9,0x0000024c,0x000200f8,0x0000024e,0x00040039,0x0000001e,0x0000024f,
0x00000020,0x0003003e,0x0000024a,0x0000024f,0x000200f9,0x0000024c,0x000200f8,0x0000024c,
0x0004003d,0x0000001e,0x00000250,0x0000024a,0x0003003e,0x00000246,0x00000250,0x0004003d,
0x00000253,0x00000256,0x00000255,0x0004003d,0x0000001e,0x00000257,0x00000246,0x00050057,
0x0000009a,0x00000258,0x00000256,0x00000257,0x00050051,0x00000006,0x00000259,0x00000258,
0x00000000,0x0004003d,0x00000006,0x0000025a,0x00000243,0x00050085,0x00000006,0x0000025b,
0x00000259,0x0000025a,0x0003003e,0x00000251,0x0000025b,0x00060041,0x000000a2,0x0000025c,
0x0000009d,0x0000018f,0x000001e1,0x0004003d,0x00000006,0x0000025d,0x0000025c,0x000500ba,
0x00000099,0x0000025e,0x0000025d,0x00000026,0x000300f7,0x00000260,0x00000000,0x000400fa,
0x0000025e,0x0000025f,0x00000260,0x000200f8,0x0000025f,0x0004003d,0x00000253,0x00000262,
0x00000255,0x00040064,0x00000252,0x00000264,0x00000262,0x00050067,0x00000265,0x00000266,
0x00000264,0x00000263,0x0004006f,0x0000001e,0x00000267,0x00000266,0x00050050,0x0000001e,
0x00000268,0x00000027,0x00000027,0x00050088,0x0000001e,0x00000269,0x00000268,0x00000267,
0x0003003e,0x00000261,0x00000269,0x0003003e,0x0000026a,0x00000026,0x0003003e,0x0000026b,
0x0000026c,0x000200f9,0x0000026d,0x000200f8,0x0000026d,0x000400f6,0x0000026f,0x00000270,
0x00000000,0x000200f9,0x00000271,0x000200f8,0x00000271,0x0004003d,0x0000009e,0x00000272,
0x0000026b,0x000500b3,0x00000099,0x00000273,0x00000272,0x000001a9,0x000400fa,0x00000273,
0x0000026e,0x0000026f,0x000200f8,0x0000026e,0x0003003e,0x00000274,0x0000026c,0x000200f9,
0x00000275,0x000200f8,0x00000275,0x000400f6,0x00000277,0x00000278,0x00000000,0x000200f9,
0x00000279,0x000200f8,0x00000279,0x0004003d,0x0000009e,0x0000027a,0x00000274,0x000500b3,
0x00000099,0x0000027b,0x0000027a,0x000001a9,0x000400fa,0x0000027b,0x00000276,0x00000277,
0x000200f8,0x00000276,0x0004003d,0x0000009e,0x0000027c,0x00000274,0x000500ab,0x00000099,
0x0000027d,0x0000027c,0x00000263,0x0004003d,0x0000009e,0x0000027e,0x0000026b,0x000500ab,
0x00000099,0x0000027f,0x0000027e,0x00000263,0x000500a6,0x00000099,0x00000280,0x0000027d,
0x0000027f,0x000300f7,0x00000282,0x00000000,0x000400fa,0x00000280,0x00000281,0x00000282,
0x000200f8,0x00000281,0x0004003d,0x00000253,0x00000283,0x00000255,0x0004003d,0x0000001e,
0x00000284,0x00000246,0x0004003d,0x0000009e,0x00000285,0x00000274,0x0004006f,0x00000006,
0x00000286,0x00000285,0x0004003d,0x0000009e,0x00000287,0x0000026b,0x0004006f,0x00000006,
0x00000288,0x00000287,0x00050050,0x0000001e,0x00000289,0x00000286,0x00000288,0x0004003d,
0x0000001e,0x0000028a,0x00000261,0x00050085,0x0000001e,0x0000028b,0x00000289,0x0000028a,
0x00050081,0x0000001e,0x0000028c,0x00000284,0x0000028b,0x00050057,0x0000009a,0x0000028d,
0x00000283,0x0000028c,0x00050051,0x00000006,0x0000028e,0x0000028d,0x00000000,0x0004003d,
0x00000006,0x0000028f,0x0000026a,0x00050081,0x00000006,0x00000290,0x0000028f,0x0000028e,
0x0003003e,0x0000026a,0x00000290,0x000200f9,0x00000282,0x000200f8,0x00000282,0x000200f9,
0x00000278,0x000200f8,0x00000278,0x0004003d,0x0000009e,0x00000291,0x00000274,0x00050080,
0x0000009e,0x00000292,0x00000291,0x000001a9,0x0003003e,0x00000274,0x00000292,0x000200f9,
0x00000275,0x000200f8,0x00000277,0x000200f9,0x00000270,0x000200f8,0x00000270,0x0004003d,
0x0000009e,0x00000293,0x0000026b,0x00050080,0x0000009e,0x00000294,0x00000293,0x000001a9,
0x0003003e,0x0000026b,0x00000294,0x000200f9,0x0000026d,0x000200f8,0x0000026f,0x0004003d,
0x00000006,0x00000295,0x00000251,0x0004003d,0x00000006,0x00000296,0x00000251,0x0004003d,
0x00000006,0x00000297,0x0000026a,0x00050085,0x00000006,0x00000299,0x00000297,0x00000298,
0x0004003d,0x00000006,0x0000029a,0x00000243,0x00050085,0x00000006,0x0000029b,0x00000299,
0x0000029a,0x00050083,0x00000006,0x0000029c,0x00000296,0x0000029b,0x00060041,0x000000a2,
0x0000029d,0x0000009d,0x0000018f,0x000001e1,0x0004003d,0x00000006,0x0000029e,0x0000029d,
0x00050085,0x00000006,0x0000029f,0x0000029c,0x0000029e,0x00050081,0x00000006,0x000002a0,
0x00000295,0x0000029f,0x0008000c,0x00000006,0x000002a1,0x00000001,0x0000002b,0x000002a0,
0x00000026,0x00000027,0x0003003e,0x00000251,0x000002a1,0x000200f9,0x00000260,0x000200f8,
0x00000260,0x00060041,0x000000a2,0x000002a3,0x0000009d,0x0000009f,0x000001e1,0x0004003d,
0x00000006,0x000002a4,0x000002a3,0x000500ba,0x00000099,0x000002a5,0x000002a4,0x0000006c,
0x000300f7,0x000002a8,0x00000000,0x000400fa,0x000002a5,0x000002a7,0x000002ae,0x000200f8,
0x000002a7,0x0004003d,0x00000253,0x000002aa,0x000002a9,0x0004003d,0x0000001e,0x000002ab,
0x00000246,0x00050057,0x0000009a,0x000002ac,0x000002aa,0x000002ab,0x0007004f,0x0000001e,
0x000002ad,0x000002ac,0x000002ac,0x00000000,0x00000001,0x0003003e,0x000002a6,0x000002ad,
0x000200f9,0x000002a8,0x000200f8,0x000002ae,0x0004003d,0x00000253,0x000002af,0x000002a9,
0x0004003d,0x0000001e,0x000002b0,0x00000246,0x00050057,0x0000009a,0x000002b1,0x000002af,
0x000002b0,0x00050051,0x00000006,0x000002b2,0x000002b1,0x00000000,0x0004003d,0x00000253,
0x000002b4,0x000002b3,0x0004003d,0x0000001e,0x000002b5,0x00000246,0x00050057,0x0000009a,
0x000002b6,0x000002b4,0x000002b5,0x00050051,0x00000006,0x000002b7,0x000002b6,0x00000000,
0x00050050,0x0000001e,0x000002b8,0x000002b2,0x000002b7,0x0003003e,0x000002a6,0x000002b8,
0x000200f9,0x000002a8,0x000200f8,0x000002a8,0x0004003d,0x0000001e,0x000002b9,0x000002a6,
0x0003003e,0x000002a2,0x000002b9,0x00050041,0x0000000d,0x000002bb,0x000002a2,0x000000a1,
0x0004003d,0x00000006,0x000002bc,0x000002bb,0x0004003d,0x00000006,0x000002bd,0x00000243,
0x00050085,0x00000006,0x000002be,0x000002bc,0x000002bd,0x00050083,0x00000006,0x000002bf,
0x000002be,0x0000006c,0x0003003e,0x000002ba,0x000002bf,0x00050041,0x0000000d,0x000002c1,
0x000002a2,0x00000100,0x0004003d,0x00000006,0x000002c2,0x000002c1,0x0004003d,0x00000006,
0x000002c3,0x00000243,0x00050085,0x00000006,0x000002c4,0x000002c2,0x000002c3,0x00050083,
0x00000006,0x000002c5,0x000002c4,0x0000006c,0x0003003e,0x000002c0,0x000002c5,0x00060041,
0x000000a2,0x000002c6,0x0000009d,0x000001c2,0x00000100,0x0004003d,0x00000006,0x000002c7,
0x000002c6,0x000500ba,0x00000099,0x000002c8,0x000002c7,0x0000006c,0x000300f7,0x000002ca,
0x00000000,0x000400fa,0x000002c8,0x000002c9,0x000002ca,0x000200f8,0x000002c9,0x0004003d,
0x00000006,0x000002cb,0x00000251,0x00050083,0x00000006,0x000002cd,0x000002cb,0x000002cc,
0x00050085,0x00000006,0x000002cf,0x000002cd,0x000002ce,0x0003003e,0x00000251,0x000002cf,
0x0004003d,0x00000006,0x000002d1,0x000002ba,0x00050085,0x00000006,0x000002d2,0x000002d1,
0x000002d0,0x0003003e,0x000002ba,0x000002d2,0x0004003d,0x00000006,0x000002d3,0x000002c0,
0x00050085,0x00000006,0x000002d4,0x000002d3,0x000002d0,0x0003003e,0x000002c0,0x000002d4,
0x000200f9,0x000002ca,0x000200f8,0x000002ca,0x0004003d,0x00000006,0x000002d5,0x00000251,
0x00050083,0x00000006,0x000002d6,0x000002d5,0x0000006c,0x00060041,0x000000a2,0x000002d8,
0x0000009d,0x000002d7,0x00000100,0x0004003d,0x00000006,0x000002d9,0x000002d8,0x00050085,
0x00000006,0x000002da,0x000002d6,0x000002d9,0x00050081,0x00000006,0x000002db,0x000002da,
0x0000006c,0x00060041,0x000000a2,0x000002dc,0x0000009d,0x000002d7,0x000000a1,0x0004003d,
0x00000006,0x000002dd,0x000002dc,0x00050081,0x00000006,0x000002de,0x000002db,0x000002dd,
0x0003003e,0x00000251,0x000002de,0x00060041,0x000000a2,0x000002e0,0x0000009d,0x000001c2,
0x000000af,0x0004003d,0x00000006,0x000002e1,0x000002e0,0x0006000c,0x00000006,0x000002e2,
0x00000001,0x0000000e,0x000002e1,0x0003003e,0x000002df,0x000002e2,0x00060041,0x000000a2,
0x000002e4,0x0000009d,0x000001c2,0x000000af,0x0004003d,0x00000006,0x000002e5,0x000002e4,
0x0006000c,0x00000006,0x000002e6,0x00000001,0x0000000d,0x000002e5,0x0003003e,0x000002e3,
0x000002e6,0x0004003d,0x00000006,0x000002e8,0x000002ba,0x0004003d,0x00000006,0x000002e9,
0x000002df,0x00050085,0x00000006,0x000002ea,0x000002e8,0x000002e9,0x0004003d,0x00000006,
0x000002eb,0x000002c0,0x0004003d,0x00000006,0x000002ec,0x000002e3,0x00050085,0x00000006,
0x000002ed,0x000002eb,0x000002ec,0x00050083,0x00000006,0x000002ee,0x000002ea,0x000002ed,
0x0004003d,0x00000006,0x000002ef,0x000002ba,0x0004003d,0x00000006,0x000002f0,0x000002e3,
0x00050085,0x00000006,0x000002f1,0x000002ef,0x000002f0,0x0004003d,0x00000006,0x000002f2,
0x000002c0,0x0004003d,0x00000006,0x000002f3,0x000002df,0x00050085,0x00000006,0x000002f4,
0x000002f2,0x000002f3,0x00050081,0x00000006,0x000002f5,0x000002f1,0x000002f4,0x00050050,
0x0000001e,0x000002f6,0x000002ee,0x000002f5,0x00060041,0x000000a2,0x000002f7,0x0000009d,
0x000002d7,0x000000af,0x0004003d,0x00000006,0x000002f8,0x000002f7,0x0005008e,0x0000001e,
0x000002f9,0x000002f6,0x000002f8,0x0003003e,0x000002e7,0x000002f9,0x0004003d,0x00000006,
0x000002fb,0x00000251,0x0004003d,0x0000001e,0x000002fc,0x000002e7,0x00050051,0x00000006,
0x000002fd,0x000002fc,0x00000000,0x00050051,0x00000006,0x000002fe,0x000002fc,0x00000001,
0x00060050,0x00000007,0x000002ff,0x000002fb,0x000002fd,0x000002fe,0x0003003e,0x000002fa,
0x000002ff,0x00050041,0x00000301,0x00000302,0x0000009d,0x00000263,0x0004003d,0x0000009a,
0x00000303,0x00000302,0x0008004f,0x00000007,0x00000304,0x00000303,0x00000303,0x00000000,
0x00000001,0x00000002,0x0004003d,0x00000007,0x00000305,0x000002fa,0x00050094,0x00000006,
0x00000306,0x00000304,0x00000305,0x00050041,0x00000301,0x00000307,0x0000009d,0x000001a9,
0x0004003d,0x0000009a,0x00000308,0x00000307,0x0008004f,0x00000007,0x00000309,0x00000308,
0x00000308,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,0x0000030a,0x000002fa,
0x00050094,0x00000006,0x0000030b,0x00000309,0x0000030a,0x00050041,0x00000301,0x0000030c,
0x0000009d,0x000001b5,0x0004003d,0x0000009a,0x0000030d,0x0000030c,0x0008004f,0x00000007,
0x0000030e,0x0000030d,0x0000030d,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,
0x0000030f,0x000002fa,0x00050094,0x00000006,0x00000310,0x0000030e,0x0000030f,0x00060050,
0x00000007,0x00000311,0x00000306,0x0000030b,0x00000310,0x00060050,0x00000007,0x00000312,
0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,0x00000313,0x00000027,0x00000027,
0x00000027,0x0008000c,0x00000007,0x00000314,0x00000001,0x0000002b,0x00000311,0x00000312,
0x00000313,0x0003003e,0x00000300,0x00000314,0x00060041,0x000000a2,0x00000316,0x0000009d,
0x00000315,0x000000a1,0x0004003d,0x00000006,0x00000317,0x00000316,0x000500ba,0x00000099,
0x00000318,0x00000317,0x0000006c,0x000300f7,0x0000031a,0x00000000,0x000400fa,0x00000318,
0x00000319,0x0000031a,0x000200f8,0x00000319,0x0004003d,0x00000007,0x0000031e,0x00000300,
0x0003003e,0x0000031d,0x0000031e,0x00050039,0x00000007,0x0000031f,0x00000019,0x0000031d,
0x00050051,0x00000006,0x00000320,0x0000031f,0x00000000,0x00050051,0x00000006,0x00000321,
0x0000031f,0x00000001,0x00050051,0x00000006,0x00000322,0x0000031f,0x00000002,0x00070050,
0x0000009a,0x00000323,0x00000320,0x00000321,0x00000322,0x00000027,0x0003003e,0x0000031c,
0x00000323,0x000100fd,0x000200f8,0x0000031a,0x00060041,0x000000a2,0x00000325,0x0000009d,
0x0000009f,0x000000a1,0x0004003d,0x00000006,0x00000326,0x00000325,0x000500ba,0x00000099,
0x00000327,0x00000326,0x0000006c,0x000300f7,0x00000329,0x00000000,0x000400fa,0x00000327,
0x00000328,0x00000329,0x000200f8,0x00000328,0x0004003d,0x00000007,0x0000032b,0x00000300,
0x0003003e,0x0000032a,0x0000032b,0x00050039,0x00000007,0x0000032c,0x0000001c,0x0000032a,
0x0003003e,0x00000300,0x0000032c,0x000200f9,0x00000329,0x000200f8,0x00000329,0x0004003d,
0x00000007,0x0000032d,0x00000300,0x00060041,0x000000a2,0x0000032e,0x0000009d,0x000002d7,
0x000001e1,0x0004003d,0x00000006,0x0000032f,0x0000032e,0x00060050,0x00000007,0x00000330,
0x0000032f,0x0000032f,0x0000032f,0x0007000c,0x00000007,0x00000331,0x00000001,0x0000001a,
0x0000032d,0x00000330,0x00050051,0x00000006,0x00000332,0x00000331,0x00000000,0x00050051,
0x00000006,0x00000333,0x00000331,0x00000001,0x00050051,0x00000006,0x00000334,0x00000331,
0x00000002,0x00070050,0x0000009a,0x00000335,0x00000332,0x00000333,0x00000334,0x00000027,
0x0003003e,0x0000031c,0x00000335,0x000100fd,0x00010038,0x00050036,0x00000007,0x0000000b,
0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a,0x000200f8,0x0000000c,0x0004003b,
0x00000008,0x00000024,0x00000007,0x0004003d,0x00000007,0x00000025,0x0000000a,0x00060050,
0x00000007,0x00000028,0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,0x00000029,
0x00000027,0x00000027,0x00000027,0x0008000c,0x00000007,0x0000002a,0x00000001,0x0000002b,
0x00000025,0x00000028,0x00000029,0x0007000c,0x00000007,0x0000002d,0x00000001,0x0000001a,
0x0000002a,0x0000002c,0x0003003e,0x00000024,0x0000002d,0x0004003d,0x00000007,0x0000002f,
0x00000024,0x00060050,0x00000007,0x00000031,0x00000030,0x00000030,0x00000030,0x00050083,
0x00000007,0x00000032,0x0000002f,0x00000031,0x00060050,0x00000007,0x00000033,0x00000026,
0x00000026,0x00000026,0x0007000c,0x00000007,0x00000034,0x00000001,0x00000028,0x00000032,
0x00000033,0x0004003d,0x00000007,0x00000037,0x00000024,0x0005008e,0x00000007,0x00000038,
0x00000037,0x00000036,0x00060050,0x00000007,0x00000039,0x00000035,0x00000035,0x00000035,
0x00050083,0x00000007,0x0000003a,0x00000039,0x00000038,0x00050088,0x00000007,0x0000003b,
0x00000034,0x0000003a,0x0007000c,0x00000007,0x0000003e,0x00000001,0x0000001a,0x0000003b,
0x0000003d,0x0005008e,0x00000007,0x0000003f,0x0000003e,0x0000002e,0x000200fe,0x0000003f,
0x00010038,0x00050036,0x00000006,0x00000010,0x00000000,0x0000000e,0x00030037,0x0000000d,
0x0000000f,0x000200f8,0x00000011,0x0004003b,0x0000000d,0x00000042,0x00000007,0x0004003d,
0x00000006,0x00000043,0x0000000f,0x00050088,0x00000006,0x00000044,0x00000043,0x0000002e,
0x0008000c,0x00000006,0x00000045,0x00000001,0x0000002b,0x00000044,0x00000026,0x00000027,
0x0007000c,0x00000006,0x00000047,0x00000001,0x0000001a,0x00000045,0x00000046,0x0003003e,
0x00000042,0x00000047,0x0004003d,0x00000006,0x00000048,0x00000042,0x00050085,0x00000006,
0x00000049,0x00000035,0x00000048,0x00050081,0x00000006,0x0000004a,0x00000030,0x00000049,
0x0004003d,0x00000006,0x0000004b,0x00000042,0x00050085,0x00000006,0x0000004c,0x00000036,
0x0000004b,0x00050081,0x00000006,0x0000004d,0x00000027,0x0000004c,0x00050088,0x00000006,
0x0000004e,0x0000004a,0x0000004d,0x0007000c,0x00000006,0x00000050,0x00000001,0x0000001a,
0x0000004e,0x0000004f,0x000200fe,0x00000050,0x00010038,0x00050036,0x00000007,0x00000013,
0x00000000,0x00000009,0x00030037,0x00000008,0x00000012,0x000200f8,0x00000014,0x0004003b,
0x00000008,0x00000057,0x00000007,0x0004003b,0x0000000d,0x00000071,0x00000007,0x0004003d,
0x00000007,0x00000053,0x00000012,0x00060050,0x00000007,0x00000054,0x00000026,0x00000026,
0x00000026,0x00060050,0x00000007,0x00000055,0x00000027,0x00000027,0x00000027,0x0008000c,
0x00000007,0x00000056,0x00000001,0x0000002b,0x00000053,0x00000054,0x00000055,0x0003003e,
0x00000012,0x00000056,0x0004003d,0x00000007,0x00000058,0x00000012,0x0004003d,0x00000007,
0x00000059,0x00000012,0x00050085,0x00000007,0x0000005a,0x00000058,0x00000059,0x00060050,
0x00000007,0x0000005c,0x0000005b,0x0000005b,0x0000005b,0x00050088,0x00000007,0x0000005d,
0x0000005a,0x0000005c,0x0004003d,0x00000007,0x0000005e,0x00000012,0x00060050,0x00000007,
0x00000060,0x0000005f,0x0000005f,0x0000005f,0x00050083,0x00000007,0x00000061,0x0000005e,
0x00000060,0x00060050,0x00000007,0x00000063,0x00000062,0x00000062,0x00000062,0x00050088,
0x00000007,0x00000064,0x00000061,0x00000063,0x0006000c,0x00000007,0x00000065,0x00000001,
0x0000001b,0x00000064,0x00060050,0x00000007,0x00000067,0x00000066,0x00000066,0x00000066,
0x00050081,0x00000007,0x00000068,0x00000065,0x00000067,0x00060050,0x00000007,0x0000006a,
0x00000069,0x00000069,0x00000069,0x00050088,0x00000007,0x0000006b,0x00000068,0x0000006a,
0x0004003d,0x00000007,0x0000006e,0x00000012,0x0007000c,0x00000007,0x0000006f,0x00000001,
0x00000030,0x0000006d,0x0000006e,0x0008000c,0x00000007,0x00000070,0x00000001,0x0000002e,
0x0000005d,0x0000006b,0x0000006f,0x0003003e,0x00000057,0x00000070,0x0004003d,0x00000007,
0x00000072,0x00000057,0x00050094,0x00000006,0x00000077,0x00000072,0x00000076,0x0007000c,
0x00000006,0x00000079,0x00000001,0x00000028,0x00000077,0x00000078,0x0003003e,0x00000071,
0x00000079,0x0004003d,0x00000006,0x0000007b,0x00000071,0x0007000c,0x00000006,0x0000007d,
0x00000001,0x0000001a,0x0000007b,0x0000007c,0x00050085,0x00000006,0x0000007e,0x0000007a,
0x0000007d,0x0004003d,0x00000007,0x0000007f,0x00000057,0x0005008e,0x00000007,0x00000080,
0x0000007f,0x0000007e,0x000200fe,0x00000080,0x00010038,0x00050036,0x00000007,0x00000016,
0x00000000,0x00000009,0x00030037,0x00000008,0x00000015,0x000200f8,0x00000017,0x0004003b,
0x00000008,0x00000083,0x00000007,0x0004003d,0x00000007,0x00000084,0x00000015,0x00060050,
0x00000007,0x00000085,0x0000002e,0x0000002e,0x0000002e,0x00050088,0x00000007,0x00000086,
0x00000084,0x00000085,0x00060050,0x00000007,0x00000087,0x00000026,0x00000026,0x00000026,
0x00060050,0x00000007,0x00000088,0x00000027,0x00000027,0x00000027,0x0008000c,0x00000007,
0x00000089,0x00000001,0x0000002b,0x00000086,0x00000087,0x00000088,0x0007000c,0x00000007,
0x0000008b,0x00000001,0x0000001a,0x00000089,0x0000008a,0x0003003e,0x00000083,0x0000008b,
0x0004003d,0x00000007,0x0000008c,0x00000083,0x0005008e,0x00000007,0x0000008d,0x0000008c,
0x00000035,0x00060050,0x00000007,0x0000008e,0x00000030,0x00000030,0x00000030,0x00050081,
0x00000007,0x0000008f,0x0000008e,0x0000008d,0x0004003d,0x00000007,0x00000090,0x00000083,
0x0005008e,0x00000007,0x00000091,0x00000090,0x00000036,0x00060050,0x00000007,0x00000092,
0x00000027,0x00000027,0x00000027,0x00050081,0x00000007,0x00000093,0x00000092,0x00000091,
0x00050088,0x00000007,0x00000094,0x0000008f,0x00000093,0x0007000c,0x00000007,0x00000096,
0x00000001,0x0000001a,0x00000094,0x00000095,0x000200fe,0x00000096,0x00010038,0x00050036,
0x00000007,0x00000019,0x00000000,0x00000009,0x00030037,0x00000008,0x00000018,0x000200f8,
0x0000001a,0x0004003b,0x00000008,0x000000bd,0x00000007,0x0004003b,0x00000008,0x000000c1,
0x00000007,0x0004003b,0x00000008,0x000000c4,0x00000007,0x0004003b,0x00000008,0x000000c8,
0x00000007,0x0004003b,0x00000008,0x000000eb,0x00000007,0x00060041,0x000000a2,0x000000a3,
0x0000009d,0x0000009f,0x000000a1,0x0004003d,0x00000006,0x000000a4,0x000000a3,0x000500ba,
0x00000099,0x000000a5,0x000000a4,0x0000006c,0x000300f7,0x000000a7,0x00000000,0x000400fa,
0x000000a5,0x000000a6,0x000000a7,0x000200f8,0x000000a6,0x00060041,0x000000a2,0x000000a8,
0x0000009d,0x0000009f,0x000000a1,0x0004003d,0x00000006,0x000000a9,0x000000a8,0x000500b8,
0x00000099,0x000000ab,0x000000a9,0x000000aa,0x000200f9,0x000000a7,0x000200f8,0x000000a7,
0x000700f5,0x00000099,0x000000ac,0x000000a5,0x0000001a,0x000000ab,0x000000a6,0x000300f7,
0x000000ae,0x00000000,0x000400fa,0x000000ac,0x000000ad,0x000000ae,0x000200f8,0x000000ad,
0x00060041,0x000000a2,0x000000b0,0x0000009d,0x0000009f,0x000000af,0x0004003d,0x00000006,
0x000000b1,0x000000b0,0x000500ba,0x00000099,0x000000b2,0x000000b1,0x0000006c,0x000200f9,
0x000000ae,0x000200f8,0x000000ae,0x000700f5,0x00000099,0x000000b3,0x000000ac,0x000000a7,
0x000000b2,0x000000ad,0x000300f7,0x000000b5,0x00000000,0x000400fa,0x000000b3,0x000000b4,
0x000000b5,0x000200f8,0x000000b4,0x0004003d,0x00000007,0x000000b6,0x00000018,0x000200fe,
0x000000b6,0x000200f8,0x000000b5,0x00060041,0x000000a2,0x000000b8,0x0000009d,0x0000009f,
0x000000a1,0x0004003d,0x00000006,0x000000b9,0x000000b8,0x000500ba,0x00000099,0x000000ba,
0x000000b9,0x0000006c,0x000300f7,0x000000bc,0x00000000,0x000400fa,0x000000ba,0x000000bb,
0x000000cc,0x000200f8,0x000000bb,0x00060041,0x000000a2,0x000000be,0x0000009d,0x0000009f,
0x000000a1,0x0004003d,0x00000006,0x000000bf,0x000000be,0x000500b8,0x00000099,0x000000c0,
0x000000bf,0x000000aa,0x000300f7,0x000000c3,0x00000000,0x000400fa,0x000000c0,0x000000c2,
0x000000c7,0x000200f8,0x000000c2,0x0004003d,0x00000007,0x000000c5,0x00000018,0x0003003e,
0x000000c4,0x000000c5,0x00050039,0x00000007,0x000000c6,0x0000000b,0x000000c4,0x0003003e,
0x000000c1,0x000000c6,0x000200f9,0x000000c3,0x000200f8,0x000000c7,0x0004003d,0x00000007,
0x000000c9,0x00000018,0x0003003e,0x000000c8,0x000000c9,0x00050039,0x00000007,0x000000ca,
0x00000013,0x000000c8,0x0003003e,0x000000c1,0x000000ca,0x000200f9,0x000000c3,0x000200f8,
0x000000c3,0x0004003d,0x00000007,0x000000cb,0x000000c1,0x0003003e,0x000000bd,0x000000cb,
0x000200f9,0x000000bc,0x000200f8,0x000000cc,0x0004003d,0x00000007,0x000000cd,0x00000018,
0x00060050,0x00000007,0x000000ce,0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,
0x000000cf,0x00000027,0x00000027,0x00000027,0x0008000c,0x00000007,0x000000d0,0x00000001,
0x0000002b,0x000000cd,0x000000ce,0x000000cf,0x0007000c,0x00000007,0x000000d3,0x00000001,
0x0000001a,0x000000d0,0x000000d2,0x0005008e,0x00000007,0x000000d5,0x000000d3,0x000000d4,
0x0003003e,0x000000bd,0x000000d5,0x000200f9,0x000000bc,0x000200f8,0x000000bc,0x00060041,
0x000000a2,0x000000d6,0x0000009d,0x0000009f,0x000000af,0x0004003d,0x00000006,0x000000d7,
0x000000d6,0x000500b8,0x00000099,0x000000d8,0x000000d7,0x0000006c,0x000300f7,0x000000da,
0x00000000,0x000400fa,0x000000d8,0x000000d9,0x000000da,0x000200f8,0x000000d9,0x0004003d,
0x00000007,0x000000e9,0x000000bd,0x00050091,0x00000007,0x000000ea,0x000000e8,0x000000e9,
0x0003003e,0x000000bd,0x000000ea,0x000200f9,0x000000da,0x000200f8,0x000000da,0x0004003d,
0x00000007,0x000000ec,0x000000bd,0x0003003e,0x000000eb,0x000000ec,0x00050039,0x00000007,
0x000000ed,0x00000016,0x000000eb,0x000200fe,0x000000ed,0x00010038,0x00050036,0x00000007,
0x0000001c,0x00000000,0x00000009,0x00030037,0x00000008,0x0000001b,0x000200f8,0x0000001d,
0x0004003b,0x00000008,0x000000f0,0x00000007,0x0004003b,0x00000008,0x000000f4,0x00000007,
0x0004003b,0x00000008,0x000000f7,0x00000007,0x0004003b,0x00000008,0x000000fb,0x00000007,
0x0004003b,0x0000000d,0x000000ff,0x00000007,0x0004003b,0x0000000d,0x00000103,0x00000007,
0x0004003b,0x0000000d,0x00000113,0x00000007,0x0004003b,0x0000000d,0x00000114,0x00000007,
0x0004003b,0x0000000d,0x00000117,0x00000007,0x0004003b,0x0000000d,0x00000118,0x00000007,
0x0004003b,0x0000000d,0x0000011e,0x00000007,0x0004003b,0x0000000d,0x0000011f,0x00000007,
0x0004003b,0x0000000d,0x00000123,0x00000007,0x0004003b,0x0000000d,0x00000127,0x00000007,
0x0004003b,0x0000000d,0x0000012e,0x00000007,0x0004003b,0x0000000d,0x00000135,0x00000007,
0x0004003b,0x0000000d,0x00000139,0x00000007,0x0004003b,0x00000008,0x0000015d,0x00000007,
0x0004003b,0x00000008,0x00000164,0x00000007,0x00060041,0x000000a2,0x000000f1,0x0000009d,
0x0000009f,0x000000a1,0x0004003d,0x00000006,0x000000f2,0x000000f1,0x000500b8,0x00000099,
0x000000f3,0x000000f2,0x000000aa,0x000300f7,0x000000f6,0x00000000,0x000400fa,0x000000f3,
0x000000f5,0x000000fa,0x000200f8,0x000000f5,0x0004003d,0x00000007,0x000000f8,0x0000001b,
0x0003003e,0x000000f7,0x000000f8,0x00050039,0x00000007,0x000000f9,0x0000000b,0x000000f7,
0x0003003e,0x000000f4,0x000000f9,0x000200f9,0x000000f6,0x000200f8,0x000000fa,0x0004003d,
0x00000007,0x000000fc,0x0000001b,0x0003003e,0x000000fb,0x000000fc,0x00050039,0x00000007,
0x000000fd,0x00000013,0x000000fb,0x0003003e,0x000000f4,0x000000fd,0x000200f9,0x000000f6,
0x000200f8,0x000000f6,0x0004003d,0x00000007,0x000000fe,0x000000f4,0x0003003e,0x000000f0,
0x000000fe,0x00060041,0x000000a2,0x00000101,0x0000009d,0x0000009f,0x00000100,0x0004003d,
0x00000006,0x00000102,0x00000101,0x0003003e,0x000000ff,0x00000102,0x00050041,0x0000000d,
0x00000104,0x000000f0,0x000000a1,0x0004003d,0x00000006,0x00000105,0x00000104,0x00050041,
0x0000000d,0x00000106,0x000000f0,0x00000100,0x0004003d,0x00000006,0x00000107,0x00000106,
0x00050041,0x0000000d,0x00000108,0x000000f0,0x000000af,0x0004003d,0x00000006,0x00000109,
0x00000108,0x0007000c,0x00000006,0x0000010a,0x00000001,0x00000028,0x00000107,0x00000109,
0x0007000c,0x00000006,0x0000010b,0x00000001,0x00000028,0x00000105,0x0000010a,0x0003003e,
0x00000103,0x0000010b,0x0004003d,0x00000006,0x0000010c,0x00000103,0x000500ba,0x00000099,
0x0000010d,0x0000010c,0x00000026,0x0004003d,0x00000006,0x0000010e,0x000000ff,0x000500ba,
0x00000099,0x0000010f,0x0000010e,0x000000d4,0x000500a7,0x00000099,0x00000110,0x0000010d,
0x0000010f,0x000300f7,0x00000112,0x00000000,0x000400fa,0x00000110,0x00000111,0x00000112,
0x000200f8,0x00000111,0x0004003d,0x00000006,0x00000115,0x000000ff,0x0003003e,0x00000114,
0x00000115,0x00050039,0x00000006,0x00000116,0x00000010,0x00000114,0x0003003e,0x00000113,
0x00000116,0x0004003d,0x00000006,0x00000119,0x00000103,0x0003003e,0x00000118,0x00000119,
0x00050039,0x00000006,0x0000011a,0x00000010,0x00000118,0x0004003d,0x00000006,0x0000011b,
0x00000113,0x00050088,0x00000006,0x0000011c,0x0000011a,0x0000011b,0x0007000c,0x00000006,
0x0000011d,0x00000001,0x00000025,0x0000011c,0x00000027,0x0003003e,0x00000117,0x0000011d,
0x0003003e,0x0000011f,0x000000d4,0x00050039,0x00000006,0x00000120,0x00000010,0x0000011f,
0x0004003d,0x00000006,0x00000121,0x00000113,0x00050088,0x00000006,0x00000122,0x00000120,
0x00000121,0x0003003e,0x0000011e,0x00000122,0x0004003d,0x00000006,0x00000124,0x0000011e,
0x00050085,0x00000006,0x00000125,0x000000aa,0x00000124,0x00050083,0x00000006,0x00000126,
0x00000125,0x0000006c,0x0003003e,0x00000123,0x00000126,0x0004003d,0x00000006,0x00000128,
0x00000117,0x0003003e,0x00000127,0x00000128,0x0004003d,0x00000006,0x00000129,0x00000117,
0x0004003d,0x00000006,0x0000012a,0x00000123,0x000500ba,0x00000099,0x0000012b,0x00000129,
0x0000012a,0x000300f7,0x0000012d,0x00000000,0x000400fa,0x0000012b,0x0000012c,0x0000012d,
0x000200f8,0x0000012c,0x0004003d,0x00000006,0x0000012f,0x00000117,0x0004003d,0x00000006,
0x00000130,0x00000123,0x00050083,0x00000006,0x00000131,0x0000012f,0x00000130,0x0004003d,
0x00000006,0x00000132,0x00000123,0x00050083,0x00000006,0x00000133,0x00000027,0x00000132,
0x00050088,0x00000006,0x00000134,0x00000131,0x00000133,0x0003003e,0x0000012e,0x00000134,
0x0004003d,0x00000006,0x00000136,0x0000012e,0x0004003d,0x00000006,0x00000137,0x0000012e,
0x00050085,0x00000006,0x00000138,0x00000136,0x00000137,0x0003003e,0x00000135,0x00000138,
0x0004003d,0x00000006,0x0000013a,0x00000135,0x0004003d,0x00000006,0x0000013b,0x0000012e,
0x00050085,0x00000006,0x0000013c,0x0000013a,0x0000013b,0x0003003e,0x00000139,0x0000013c,
0x0004003d,0x00000006,0x0000013e,0x00000139,0x00050085,0x00000006,0x0000013f,0x0000013d,
0x0000013e,0x0004003d,0x00000006,0x00000140,0x00000135,0x00050085,0x00000006,0x00000141,
0x0000005b,0x00000140,0x00050083,0x00000006,0x00000142,0x0000013f,0x00000141,0x00050081,
0x00000006,0x00000143,0x00000142,0x00000027,0x0004003d,0x00000006,0x00000144,0x00000123,
0x00050085,0x00000006,0x00000145,0x00000143,0x00000144,0x0004003d,0x00000006,0x00000146,
0x00000139,0x0004003d,0x00000006,0x00000147,0x00000135,0x00050085,0x00000006,0x00000148,
0x0000013d,0x00000147,0x00050083,0x00000006,0x00000149,0x00000146,0x00000148,0x0004003d,
0x00000006,0x0000014a,0x0000012e,0x00050081,0x00000006,0x0000014b,0x00000149,0x0000014a,
0x0004003d,0x00000006,0x0000014c,0x00000123,0x00050083,0x00000006,0x0000014d,0x00000027,
0x0000014c,0x00050085,0x00000006,0x0000014e,0x0000014b,0x0000014d,0x00050081,0x00000006,
0x0000014f,0x00000145,0x0000014e,0x0004003d,0x00000006,0x00000151,0x00000139,0x00050085,
0x00000006,0x00000152,0x00000150,0x00000151,0x0004003d,0x00000006,0x00000153,0x00000135,
0x00050085,0x00000006,0x00000154,0x0000005b,0x00000153,0x00050081,0x00000006,0x00000155,
0x00000152,0x00000154,0x0004003d,0x00000006,0x00000156,0x0000011e,0x00050085,0x00000006,
0x00000157,0x00000155,0x00000156,0x00050081,0x00000006,0x00000158,0x0000014f,0x00000157,
0x0003003e,0x00000127,0x00000158,0x000200f9,0x0000012d,0x000200f8,0x0000012d,0x0004003d,
0x00000006,0x00000159,0x00000127,0x0004003d,0x00000006,0x0000015a,0x00000113,0x00050085,
0x00000006,0x0000015b,0x00000159,0x0000015a,0x00060050,0x00000007,0x0000015c,0x0000015b,
0x0000015b,0x0000015b,0x0003003e,0x0000015d,0x0000015c,0x00050039,0x00000007,0x0000015e,
0x0000000b,0x0000015d,0x00050051,0x00000006,0x0000015f,0x0000015e,0x00000000,0x0004003d,
0x00000006,0x00000160,0x00000103,0x00050088,0x00000006,0x00000161,0x0000015f,0x00000160,
0x0004003d,0x00000007,0x00000162,0x000000f0,0x0005008e,0x00000007,0x00000163,0x00000162,
0x00000161,0x0003003e,0x000000f0,0x00000163,0x000200f9,0x00000112,0x000200f8,0x00000112,
0x0004003d,0x00000007,0x00000165,0x000000f0,0x00060050,0x00000007,0x00000166,0x000000d4,
0x000000d4,0x000000d4,0x00050088,0x00000007,0x00000167,0x00000165,0x00000166,0x0003003e,
0x00000164,0x00000167,0x00060041,0x000000a2,0x00000168,0x0000009d,0x0000009f,0x000000af,
0x0004003d,0x00000006,0x00000169,0x00000168,0x000500ba,0x00000099,0x0000016a,0x00000169,
0x0000006c,0x000300f7,0x0000016c,0x00000000,0x000400fa,0x0000016a,0x0000016b,0x0000016c,
0x000200f8,0x0000016b,0x0004003d,0x00000007,0x0000017a,0x00000164,0x00050091,0x00000007,
0x0000017b,0x00000179,0x0000017a,0x0003003e,0x00000164,0x0000017b,0x000200f9,0x0000016c,
0x000200f8,0x0000016c,0x0004003d,0x00000007,0x0000017c,0x00000164,0x00060050,0x00000007,
0x0000017d,0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,0x0000017e,0x00000027,
0x00000027,0x00000027,0x0008000c,0x00000007,0x0000017f,0x00000001,0x0000002b,0x0000017c,
0x0000017d,0x0000017e,0x0007000c,0x00000007,0x00000182,0x00000001,0x0000001a,0x0000017f,
0x00000181,0x000200fe,0x00000182,0x00010038,0x00050036,0x0000001e,0x00000020,0x00000000,
0x0000001f,0x000200f8,0x00000021,0x0004003b,0x00000185,0x00000186,0x00000007,0x0004003b,
0x000001a2,0x000001a3,0x00000007,0x0004003d,0x0000001e,0x00000189,0x00000188,0x00050041,
0x0000018b,0x0000018c,0x0000009d,0x0000018a,0x0004003d,0x0000001e,0x0000018d,0x0000018c,
0x00050088,0x0000001e,0x0000018e,0x00000189,0x0000018d,0x0003003e,0x00000186,0x0000018e,
0x00060041,0x000000a2,0x00000190,0x0000009d,0x0000018f,0x00000100,0x0004003d,0x00000006,
0x00000191,0x00000190,0x000500ba,0x00000099,0x00000192,0x00000191,0x0000006c,0x000300f7,
0x00000194,0x00000000,0x000400fa,0x00000192,0x00000193,0x00000194,0x000200f8,0x00000193,
0x00050041,0x0000000d,0x00000195,0x00000186,0x000000a1,0x0004003d,0x00000006,0x00000196,
0x00000195,0x00050083,0x00000006,0x00000197,0x00000027,0x00000196,0x00050041,0x0000000d,
0x00000198,0x00000186,0x000000a1,0x0003003e,0x00000198,0x00000197,0x000200f9,0x00000194,
0x000200f8,0x00000194,0x00060041,0x000000a2,0x00000199,0x0000009d,0x0000018f,0x000000af,
0x0004003d,0x00000006,0x0000019a,0x00000199,0x000500ba,0x00000099,0x0000019b,0x0000019a,
0x0000006c,0x000300f7,0x0000019d,0x00000000,0x000400fa,0x0000019b,0x0000019c,0x0000019d,
0x000200f8,0x0000019c,0x00050041,0x0000000d,0x0000019e,0x00000186,0x00000100,0x0004003d,
0x00000006,0x0000019f,0x0000019e,0x00050083,0x00000006,0x000001a0,0x00000027,0x0000019f,
0x00050041,0x0000000d,0x000001a1,0x00000186,0x00000100,0x0003003e,0x000001a1,0x000001a0,
0x000200f9,0x0000019d,0x000200f8,0x0000019d,0x00060041,0x000000a2,0x000001a4,0x0000009d,
0x0000018f,0x000000a1,0x0004003d,0x00000006,0x000001a5,0x000001a4,0x00050081,0x00000006,
0x000001a6,0x000001a5,0x0000006c,0x0004006e,0x0000009e,0x000001a7,0x000001a6,0x0003003e,
0x000001a3,0x000001a7,0x0004003d,0x0000009e,0x000001a8,0x000001a3,0x000500aa,0x00000099,
0x000001aa,0x000001a8,0x000001a9,0x000300f7,0x000001ac,0x00000000,0x000400fa,0x000001aa,
0x000001ab,0x000001b3,0x000200f8,0x000001ab,0x00050041,0x0000000d,0x000001ad,0x00000186,
0x00000100,0x0004003d,0x00000006,0x000001ae,0x000001ad,0x00050041,0x0000000d,0x000001af,
0x00000186,0x000000a1,0x0004003d,0x00000006,0x000001b0,0x000001af,0x00050083,0x00000006,
0x000001b1,0x00000027,0x000001b0,0x00050050,0x0000001e,0x000001b2,0x000001ae,0x000001b1,
0x0003003e,0x00000186,0x000001b2,0x000200f9,0x000001ac,0x000200f8,0x000001b3,0x0004003d,
0x0000009e,0x000001b4,0x000001a3,0x000500aa,0x00000099,0x000001b6,0x000001b4,0x000001b5,
0x000300f7,0x000001b8,0x00000000,0x000400fa,0x000001b6,0x000001b7,0x000001c0,0x000200f8,
0x000001b7,0x00050041,0x0000000d,0x000001b9,0x00000186,0x000000a1,0x0004003d,0x00000006,
0x000001ba,0x000001b9,0x00050083,0x00000006,0x000001bb,0x00000027,0x000001ba,0x00050041,
0x0000000d,0x000001bc,0x00000186,0x00000100,0x0004003d,0x00000006,0x000001bd,0x000001bc,
0x00050083,0x00000006,0x000001be,0x00000027,0x000001bd,0x00050050,0x0000001e,0x000001bf,
0x000001bb,0x000001be,0x0003003e,0x00000186,0x000001bf,0x000200f9,0x000001b8,0x000200f8,
0x000001c0,0x0004003d,0x0000009e,0x000001c1,0x000001a3,0x000500aa,0x00000099,0x000001c3,
0x000001c1,0x000001c2,0x000300f7,0x000001c5,0x00000000,0x000400fa,0x000001c3,0x000001c4,
0x000001c5,0x000200f8,0x000001c4,0x00050041,0x0000000d,0x000001c6,0x00000186,0x00000100,
0x0004003d,0x00000006,0x000001c7,0x000001c6,0x00050083,0x00000006,0x000001c8,0x00000027,
0x000001c7,0x00050041,0x0000000d,0x000001c9,0x00000186,0x000000a1,0x0004003d,0x00000006,
0x000001ca,0x000001c9,0x00050050,0x0000001e,0x000001cb,0x000001c8,0x000001ca,0x0003003e,
0x00000186,0x000001cb,0x000200f9,0x000001c5,0x000200f8,0x000001c5,0x000200f9,0x000001b8,
0x000200f8,0x000001b8,0x000200f9,0x000001ac,0x000200f8,0x000001ac,0x0004003d,0x0000001e,
0x000001cc,0x00000186,0x00050041,0x0000018b,0x000001cd,0x0000009d,0x0000018a,0x0004003d,
0x0000001e,0x000001ce,0x000001cd,0x00050085,0x0000001e,0x000001cf,0x000001cc,0x000001ce,
0x000200fe,0x000001cf,0x00010038,0x00050036,0x0000001e,0x00000022,0x00000000,0x0000001f,
0x000200f8,0x00000023,0x0004003b,0x00000185,0x000001d2,0x00000007,0x0004003b,0x00000008,
0x000001da,0x00000007,0x0004003b,0x0000000d,0x000001ed,0x00000007,0x0004003b,0x0000000d,
0x000001f1,0x00000007,0x0004003b,0x0000000d,0x0000020b,0x00000007,0x0004003b,0x0000000d,
0x0000020f,0x00000007,0x0004003b,0x0000000d,0x00000229,0x00000007,0x0004003b,0x0000000d,
0x0000022f,0x00000007,0x0004003d,0x0000001e,0x000001d3,0x00000188,0x00050041,0x0000018b,
0x000001d4,0x0000009d,0x0000018a,0x0004003d,0x0000001e,0x000001d5,0x000001d4,0x00050088,
0x0000001e,0x000001d6,0x000001d3,0x000001d5,0x0005008e,0x0000001e,0x000001d7,0x000001d6,
0x0000013d,0x00050050,0x0000001e,0x000001d8,0x00000027,0x00000027,0x00050083,0x0000001e,
0x000001d9,0x000001d7,0x000001d8,0x0003003e,0x000001d2,0x000001d9,0x00050041,0x0000000d,
0x000001db,0x000001d2,0x000000a1,0x0004003d,0x00000006,0x000001dc,0x000001db,0x00060041,
0x000000a2,0x000001de,0x0000009d,0x000001dd,0x000000af,0x0004003d,0x00000006,0x000001df,
0x000001de,0x00050085,0x00000006,0x000001e0,0x000001dc,0x000001df,0x00060041,0x000000a2,
0x000001e2,0x0000009d,0x000001dd,0x000001e1,0x0004003d,0x00000006,0x000001e3,0x000001e2,
0x00050085,0x00000006,0x000001e4,0x000001e0,0x000001e3,0x00050041,0x0000000d,0x000001e5,
0x000001d2,0x00000100,0x0004003d,0x00000006,0x000001e6,0x000001e5,0x0004007f,0x00000006,
0x000001e7,0x000001e6,0x00060041,0x000000a2,0x000001e8,0x0000009d,0x000001dd,0x000000af,
0x0004003d,0x00000006,0x000001e9,0x000001e8,0x00050085,0x00000006,0x000001ea,0x000001e7,
0x000001e9,0x00060050,0x00000007,0x000001eb,0x000001e4,0x000001ea,0x00000027,0x0006000c,
0x00000007,0x000001ec,0x00000001,0x00000045,0x000001eb,0x0003003e,0x000001da,0x000001ec,
0x00060041,0x000000a2,0x000001ee,0x0000009d,0x000001dd,0x00000100,0x0004003d,0x00000006,
0x000001ef,0x000001ee,0x0006000c,0x00000006,0x000001f0,0x00000001,0x0000000e,0x000001ef,
0x0003003e,0x000001ed,0x000001f0,0x00060041,0x000000a2,0x000001f2,0x0000009d,0x000001dd,
0x00000100,0x0004003d,0x00000006,0x000001f3,0x000001f2,0x0006000c,0x00000006,0x000001f4,
0x00000001,0x0000000d,0x000001f3,0x0003003e,0x000001f1,0x000001f4,0x00050041,0x0000000d,
0x000001f5,0x000001da,0x000000a1,0x0004003d,0x00000006,0x000001f6,0x000001f5,0x00050041,
0x0000000d,0x000001f7,0x000001da,0x00000100,0x0004003d,0x00000006,0x000001f8,0x000001f7,
0x0004003d,0x00000006,0x000001f9,0x000001ed,0x00050085,0x00000006,0x000001fa,0x000001f8,
0x000001f9,0x00050041,0x0000000d,0x000001fb,0x000001da,0x000000af,0x0004003d,0x00000006,
0x000001fc,0x000001fb,0x0004003d,0x00000006,0x000001fd,0x000001f1,0x00050085,0x00000006,
0x000001fe,0x000001fc,0x000001fd,0x00050081,0x00000006,0x000001ff,0x000001fa,0x000001fe,
0x00050041,0x0000000d,0x00000200,0x000001da,0x00000100,0x0004003d,0x00000006,0x00000201,
0x00000200,0x0004007f,0x00000006,0x00000202,0x00000201,0x0004003d,0x00000006,0x00000203,
0x000001f1,0x00050085,0x00000006,0x00000204,0x00000202,0x00000203,0x00050041,0x0000000d,
0x00000205,0x000001da,0x000000af,0x0004003d,0x00000006,0x00000206,0x00000205,0x0004003d,
0x00000006,0x00000207,0x000001ed,0x00050085,0x00000006,0x00000208,0x00000206,0x00000207,
0x00050081,0x00000006,0x00000209,0x00000204,0x00000208,0x00060050,0x00000007,0x0000020a,
0x000001f6,0x000001ff,0x00000209,0x0003003e,0x000001da,0x0000020a,0x00060041,0x000000a2,
0x0000020c,0x0000009d,0x000001dd,0x000000a1,0x0004003d,0x00000006,0x0000020d,0x0000020c,
0x0006000c,0x00000006,0x0000020e,0x00000001,0x0000000e,0x0000020d,0x0003003e,0x0000020b,
0x0000020e,0x00060041,0x000000a2,0x00000210,0x0000009d,0x000001dd,0x000000a1,0x0004003d,
0x00000006,0x00000211,0x00000210,0x0006000c,0x00000006,0x00000212,0x00000001,0x0000000d,
0x00000211,0x0003003e,0x0000020f,0x00000212,0x00050041,0x0000000d,0x00000213,0x000001da,
0x000000a1,0x0004003d,0x00000006,0x00000214,0x00000213,0x0004003d,0x00000006,0x00000215,
0x0000020b,0x00050085,0x00000006,0x00000216,0x00000214,0x00000215,0x00050041,0x0000000d,
0x00000217,0x000001da,0x000000af,0x0004003d,0x00000006,0x00000218,0x00000217,0x0004003d,
0x00000006,0x00000219,0x0000020f,0x00050085,0x00000006,0x0000021a,0x00000218,0x00000219,
0x00050081,0x00000006,0x0000021b,0x00000216,0x0000021a,0x00050041,0x0000000d,0x0000021c,
0x000001da,0x00000100,0x0004003d,0x00000006,0x0000021d,0x0000021c,0x00050041,0x0000000d,
0x0000021e,0x000001da,0x000000a1,0x0004003d,0x00000006,0x0000021f,0x0000021e,0x0004007f,
0x00000006,0x00000220,0x0000021f,0x0004003d,0x00000006,0x00000221,0x0000020f,0x00050085,
0x00000006,0x00000222,0x00000220,0x00000221,0x00050041,0x0000000d,0x00000223,0x000001da,
0x000000af,0x0004003d,0x00000006,0x00000224,0x00000223,0x0004003d,0x00000006,0x00000225,
0x0000020b,0x00050085,0x00000006,0x00000226,0x00000224,0x00000225,0x00050081,0x00000006,
0x00000227,0x00000222,0x00000226,0x00060050,0x00000007,0x00000228,0x0000021b,0x0000021d,
0x00000227,0x0003003e,0x000001da,0x00000228,0x00050041,0x0000000d,0x0000022a,0x000001da,
0x000000a1,0x0004003d,0x00000006,0x0000022b,0x0000022a,0x00050041,0x0000000d,0x0000022c,
0x000001da,0x000000af,0x0004003d,0x00000006,0x0000022d,0x0000022c,0x0007000c,0x00000006,
0x0000022e,0x00000001,0x00000019,0x0000022b,0x0000022d,0x0003003e,0x00000229,0x0000022e,
0x00050041,0x0000000d,0x00000230,0x000001da,0x00000100,0x0004003d,0x00000006,0x00000231,
0x00000230,0x0008000c,0x00000006,0x00000233,0x00000001,0x0000002b,0x00000231,0x00000232,
0x00000027,0x0006000c,0x00000006,0x00000234,0x00000001,0x00000010,0x00000233,0x0003003e,
0x0000022f,0x00000234,0x0004003d,0x00000006,0x00000235,0x00000229,0x00050088,0x00000006,
0x00000237,0x00000235,0x00000236,0x00050081,0x00000006,0x00000238,0x00000237,0x0000006c,
0x0004003d,0x00000006,0x00000239,0x0000022f,0x00050088,0x00000006,0x0000023b,0x00000239,
0x0000023a,0x00050083,0x00000006,0x0000023c,0x0000006c,0x0000023b,0x00050050,0x0000001e,
0x0000023d,0x00000238,0x0000023c,0x00050041,0x0000018b,0x0000023e,0x0000009d,0x0000018a,
0x0004003d,0x0000001e,0x0000023f,0x0000023e,0x00050085,0x0000001e,0x00000240,0x0000023d,
0x0000023f,0x000200fe,0x00000240,0x00010038
};
+371 -7
View File
@@ -11,17 +11,25 @@
#include "gfx.h"
#include "image.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include "platform.h"
#include "gen/fullscreen_vert.h"
#include "gen/ui_pq_frag.h"
#ifdef VLCPS5_HOST
#include <zlib.h>
#endif
/* The console's Vulkan driver, with patches/mesa/0001 (absent elsewhere). */
extern "C" int vlcps5_wsi_videoout_set_hdr(int enable) __attribute__((weak));
extern "C" int vlcps5_wsi_videoout_dynamic_range(void) __attribute__((weak));
extern "C" int vlcps5_wsi_videoout_set_refresh(int mode, int *period_us) __attribute__((weak));
Gfx gfx;
namespace {
@@ -50,6 +58,26 @@ VkDeviceMemory offscreen_memory, readback_memory;
VkBuffer readback;
void *readback_mapped;
/* HDR10 output (gfx.h): the UI layer, the 10-bit frame and the pipeline that
* puts the first over the second. 10:10:10:2 with blue in the low bits: the
* framebuffers' B,G,R order (VideoOut's Bgr10A2), as their 8-bit SDR is. */
const VkFormat HDR_FORMAT = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
const float UI_NITS = 203; /* BT.2408's graphics white */
struct Hdr {
VkImage ui_image, image;
VkDeviceMemory ui_memory, memory;
VkImageView ui_view, view;
VkRenderPass ui_pass;
VkFramebuffer ui_fb, fb;
VkSampler sampler;
VkDescriptorSetLayout set_layout;
VkDescriptorPool pool;
VkDescriptorSet set;
VkPipelineLayout layout;
VkPipeline pipeline;
} hdr;
enum PassNow { PASS_NONE, PASS_MAIN, PASS_UI, PASS_HDR } pass_now;
#define CHECK(expr) \
do { \
VkResult r_ = (expr); \
@@ -168,7 +196,8 @@ bool create_swapchain()
info.imageColorSpace = chosen.colorSpace;
info.imageExtent = { gfx.width, gfx.height };
info.imageArrayLayers = 1;
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
/* (copied into in HDR10 output: the 10-bit frame) */
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
info.compositeAlpha = (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
@@ -193,8 +222,9 @@ bool create_offscreen()
VkImage image;
VkImageView view;
if (!gfx_image(gfx.width, gfx.height, gfx.format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, &image,
&offscreen_memory, &view))
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
&image, &offscreen_memory, &view))
return false;
images.push_back(image);
views.push_back(view);
@@ -294,6 +324,223 @@ bool create_targets()
return true;
}
/* A pass over one colour attachment, cleared, ending in `final` and made
* visible to `next_stage`/`next_access` (what reads it next). */
bool make_pass(VkFormat format, VkImageLayout final, VkPipelineStageFlags next_stage,
VkAccessFlags next_access, VkRenderPass *pass)
{
VkAttachmentDescription color = {};
color.format = format;
color.samples = VK_SAMPLE_COUNT_1_BIT;
color.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
color.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
color.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
color.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
color.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
color.finalLayout = final;
VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &ref;
VkSubpassDependency deps[3] = {};
deps[0].srcSubpass = VK_SUBPASS_EXTERNAL;
deps[0].dstSubpass = 0;
deps[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
deps[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
deps[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
deps[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
deps[1].srcSubpass = VK_SUBPASS_EXTERNAL;
deps[1].dstSubpass = 0;
deps[1].srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
deps[1].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
deps[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
deps[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
deps[2].srcSubpass = 0;
deps[2].dstSubpass = VK_SUBPASS_EXTERNAL;
deps[2].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
deps[2].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
deps[2].dstStageMask = next_stage;
deps[2].dstAccessMask = next_access;
VkRenderPassCreateInfo rp = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
rp.attachmentCount = 1;
rp.pAttachments = &color;
rp.subpassCount = 1;
rp.pSubpasses = &subpass;
rp.dependencyCount = 3;
rp.pDependencies = deps;
CHECK(vkCreateRenderPass(gfx.device, &rp, nullptr, pass));
return true;
}
bool make_framebuffer(VkRenderPass pass, VkImageView view, VkFramebuffer *fb)
{
VkFramebufferCreateInfo fi = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
fi.renderPass = pass;
fi.attachmentCount = 1;
fi.pAttachments = &view;
fi.width = gfx.width;
fi.height = gfx.height;
fi.layers = 1;
CHECK(vkCreateFramebuffer(gfx.device, &fi, nullptr, fb));
return true;
}
/* HDR10 output's targets and the UI layer's pipeline. Optional: without
* them the app stays SDR. */
bool create_hdr()
{
/* the UI layer: the swapchain's format, so ImGui's pipeline (made for
* gfx.render_pass) draws in its pass as well */
if (!gfx_image(gfx.width, gfx.height, gfx.format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, &hdr.ui_image,
&hdr.ui_memory, &hdr.ui_view))
return false;
if (!gfx_image(gfx.width, gfx.height, HDR_FORMAT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, &hdr.image,
&hdr.memory, &hdr.view))
return false;
if (!make_pass(gfx.format, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_READ_BIT, &hdr.ui_pass) ||
!make_pass(HDR_FORMAT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT, &gfx.hdr_pass) ||
!make_framebuffer(hdr.ui_pass, hdr.ui_view, &hdr.ui_fb) ||
!make_framebuffer(gfx.hdr_pass, hdr.view, &hdr.fb))
return false;
VkSamplerCreateInfo si = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
si.magFilter = si.minFilter = VK_FILTER_NEAREST;
si.addressModeU = si.addressModeV = si.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
CHECK(vkCreateSampler(gfx.device, &si, nullptr, &hdr.sampler));
VkDescriptorSetLayoutBinding b = {};
b.binding = 0;
b.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
b.descriptorCount = 1;
b.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutCreateInfo li = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
li.bindingCount = 1;
li.pBindings = &b;
CHECK(vkCreateDescriptorSetLayout(gfx.device, &li, nullptr, &hdr.set_layout));
VkDescriptorPoolSize ps = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 };
VkDescriptorPoolCreateInfo pi = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
pi.maxSets = 1;
pi.poolSizeCount = 1;
pi.pPoolSizes = &ps;
CHECK(vkCreateDescriptorPool(gfx.device, &pi, nullptr, &hdr.pool));
VkDescriptorSetAllocateInfo ai = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
ai.descriptorPool = hdr.pool;
ai.descriptorSetCount = 1;
ai.pSetLayouts = &hdr.set_layout;
CHECK(vkAllocateDescriptorSets(gfx.device, &ai, &hdr.set));
VkDescriptorImageInfo ii = { hdr.sampler, hdr.ui_view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
VkWriteDescriptorSet w = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
w.dstSet = hdr.set;
w.dstBinding = 0;
w.descriptorCount = 1;
w.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
w.pImageInfo = &ii;
vkUpdateDescriptorSets(gfx.device, 1, &w, 0, nullptr);
VkPushConstantRange range = { VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float) };
VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.setLayoutCount = 1;
pl.pSetLayouts = &hdr.set_layout;
pl.pushConstantRangeCount = 1;
pl.pPushConstantRanges = &range;
CHECK(vkCreatePipelineLayout(gfx.device, &pl, nullptr, &hdr.layout));
VkShaderModule vs = gfx_shader(spv_fullscreen_vert, sizeof(spv_fullscreen_vert));
VkShaderModule fs = gfx_shader(spv_ui_pq_frag, sizeof(spv_ui_pq_frag));
VkPipelineShaderStageCreateInfo stages[2] = {};
stages[0] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
stages[0].module = vs;
stages[0].pName = "main";
stages[1] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
stages[1].module = fs;
stages[1].pName = "main";
VkPipelineVertexInputStateCreateInfo vi = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
VkPipelineInputAssemblyStateCreateInfo ia = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkPipelineViewportStateCreateInfo vp = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
vp.viewportCount = 1;
vp.scissorCount = 1;
VkPipelineRasterizationStateCreateInfo rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
rs.polygonMode = VK_POLYGON_MODE_FILL;
rs.cullMode = VK_CULL_MODE_NONE;
rs.lineWidth = 1.0f;
VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
/* premultiplied over */
VkPipelineColorBlendAttachmentState att = {};
att.blendEnable = VK_TRUE;
att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
att.colorBlendOp = VK_BLEND_OP_ADD;
att.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
att.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
att.alphaBlendOp = VK_BLEND_OP_ADD;
att.colorWriteMask = 0xf;
VkPipelineColorBlendStateCreateInfo cb = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
cb.attachmentCount = 1;
cb.pAttachments = &att;
VkDynamicState dyn[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo ds = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
ds.dynamicStateCount = 2;
ds.pDynamicStates = dyn;
VkGraphicsPipelineCreateInfo gp = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
gp.stageCount = 2;
gp.pStages = stages;
gp.pVertexInputState = &vi;
gp.pInputAssemblyState = &ia;
gp.pViewportState = &vp;
gp.pRasterizationState = &rs;
gp.pMultisampleState = &ms;
gp.pColorBlendState = &cb;
gp.pDynamicState = &ds;
gp.layout = hdr.layout;
gp.renderPass = gfx.hdr_pass;
VkResult r = vkCreateGraphicsPipelines(gfx.device, VK_NULL_HANDLE, 1, &gp, nullptr, &hdr.pipeline);
vkDestroyShaderModule(gfx.device, vs, nullptr);
vkDestroyShaderModule(gfx.device, fs, nullptr);
CHECK(r);
return true;
}
void begin(VkCommandBuffer cmd, VkRenderPass pass, VkFramebuffer fb, float alpha)
{
VkClearValue clear = {};
clear.color = { { 0.0f, 0.0f, 0.0f, alpha } };
VkRenderPassBeginInfo rb = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
rb.renderPass = pass;
rb.framebuffer = fb;
rb.renderArea.extent = { gfx.width, gfx.height };
rb.clearValueCount = 1;
rb.pClearValues = &clear;
vkCmdBeginRenderPass(cmd, &rb, VK_SUBPASS_CONTENTS_INLINE);
}
#ifdef VLCPS5_HOST
/* An HDR10 frame (10:10:10:2 PQ, BT.2020) in the offscreen image, made
* viewable for the PNG: light, SDR white at 203 nits, BT.709, gamma 2.4. */
void hdr_preview(std::vector<uint8_t> &rgb, const uint32_t *px, size_t n)
{
auto nits = [](float e) {
float p = powf(e, 1 / 78.84375f);
return 10000 * powf(fmaxf(p - 0.8359375f, 0) / (18.8515625f - 18.6875f * p), 1 / 0.1593017578125f);
};
for (size_t i = 0; i < n; i++) {
uint32_t v = px[i];
float b = nits((v & 1023) / 1023.0f) / UI_NITS, g = nits(((v >> 10) & 1023) / 1023.0f) / UI_NITS,
r = nits(((v >> 20) & 1023) / 1023.0f) / UI_NITS;
float o[3] = { 1.6605f * r - 0.5876f * g - 0.0728f * b, -0.1246f * r + 1.1329f * g - 0.0083f * b,
-0.0182f * r - 0.1006f * g + 1.1187f * b };
for (int c = 0; c < 3; c++)
rgb[i * 3 + c] = (uint8_t)(powf(fminf(fmaxf(o[c], 0), 1), 1 / 2.4f) * 255 + 0.5f);
}
}
#endif
#ifdef VLCPS5_HOST
/* The offscreen image (BGRA) as an RGB PNG. */
void save_png(const char *path)
@@ -301,7 +548,9 @@ void save_png(const char *path)
uint32_t w = gfx.width, h = gfx.height;
std::vector<uint8_t> rgb((size_t)w * h * 3);
const uint8_t *src = (const uint8_t *)readback_mapped;
for (size_t i = 0; i < (size_t)w * h; i++) {
if (gfx.hdr)
hdr_preview(rgb, (const uint32_t *)src, (size_t)w * h);
for (size_t i = 0; i < (size_t)w * h && !gfx.hdr; i++) {
rgb[i * 3] = src[i * 4 + 2];
rgb[i * 3 + 1] = src[i * 4 + 1];
rgb[i * 3 + 2] = src[i * 4];
@@ -334,7 +583,82 @@ bool gfx_init()
return false;
if (gfx.offscreen ? !create_offscreen() : !create_swapchain())
return false;
return create_targets();
if (!create_targets())
return false;
if (!create_hdr()) {
fprintf(stderr, "gfx: no HDR10 output (its targets couldn't be made)\n");
gfx.hdr_pass = VK_NULL_HANDLE;
}
gfx.display_range = vlcps5_wsi_videoout_dynamic_range ? vlcps5_wsi_videoout_dynamic_range() : -1;
fprintf(stderr, "gfx: output %s, HDR10 output %s\n",
gfx.display_range == 2 ? "HDR" : gfx.display_range == 1 ? "SDR" : "unknown",
gfx.hdr_pass && (vlcps5_wsi_videoout_set_hdr || gfx.offscreen) ? "possible" : "not possible");
return true;
}
bool gfx_set_hdr(bool on)
{
if (on == gfx.hdr)
return true;
if (on && !gfx.hdr_pass)
return false;
/* nothing drawn in one format may land after the switch */
vkDeviceWaitIdle(gfx.device);
int rc;
if (vlcps5_wsi_videoout_set_hdr)
rc = vlcps5_wsi_videoout_set_hdr(on ? 1 : 0);
else
rc = gfx.offscreen && getenv("VLCPS5_HDR_TEST") ? 0 : -1; /* host: the preview */
fprintf(stderr, "gfx: HDR10 output %s: %s (%#x)\n", on ? "on" : "off", rc == 0 ? "done" : "refused",
(unsigned)rc);
if (rc != 0 && on)
return false;
/* off even if refused: SDR pixels are what is drawn from here */
gfx.hdr = on;
return true;
}
bool gfx_set_refresh(int mode, int *period_us)
{
*period_us = 0;
if (!vlcps5_wsi_videoout_set_refresh)
return false;
/* nothing in flight while the output changes */
vkDeviceWaitIdle(gfx.device);
return vlcps5_wsi_videoout_set_refresh(mode, period_us) == 0;
}
int gfx_output_range()
{
if (vlcps5_wsi_videoout_dynamic_range)
return vlcps5_wsi_videoout_dynamic_range();
return gfx.offscreen && getenv("VLCPS5_HDR_TEST") ? atoi(getenv("VLCPS5_HDR_TEST")) : -1;
}
void gfx_begin_ui_pass(VkCommandBuffer cmd)
{
begin(cmd, hdr.ui_pass, hdr.ui_fb, 0.0f); /* clear: transparent */
pass_now = PASS_UI;
}
void gfx_begin_hdr_pass(VkCommandBuffer cmd)
{
if (pass_now != PASS_NONE)
vkCmdEndRenderPass(cmd);
begin(cmd, gfx.hdr_pass, hdr.fb, 1.0f);
pass_now = PASS_HDR;
}
void gfx_draw_ui_layer(VkCommandBuffer cmd)
{
VkViewport vp = { 0, 0, (float)gfx.width, (float)gfx.height, 0, 1 };
VkRect2D sc = { { 0, 0 }, { gfx.width, gfx.height } };
vkCmdSetViewport(cmd, 0, 1, &vp);
vkCmdSetScissor(cmd, 0, 1, &sc);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, hdr.pipeline);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, hdr.layout, 0, 1, &hdr.set, 0, nullptr);
vkCmdPushConstants(cmd, hdr.layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float), &UI_NITS);
vkCmdDraw(cmd, 3, 1, 0, 0);
}
void gfx_shutdown()
@@ -383,12 +707,32 @@ void gfx_begin_pass(VkCommandBuffer cmd)
rb.clearValueCount = 1;
rb.pClearValues = &clear;
vkCmdBeginRenderPass(cmd, &rb, VK_SUBPASS_CONTENTS_INLINE);
pass_now = PASS_MAIN;
}
void gfx_end_frame(VkCommandBuffer cmd)
{
Frame &f = frames[gfx.frame_slot];
vkCmdEndRenderPass(cmd);
if (pass_now == PASS_HDR) {
/* the 10-bit frame into the framebuffer: same 32-bit pixels and tiling */
VkImage dst = images[image_index];
gfx_barrier(cmd, dst, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
VkImageCopy region = {};
region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
region.extent = { gfx.width, gfx.height, 1 };
vkCmdCopyImage(cmd, hdr.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
gfx_barrier(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
gfx.offscreen ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_TRANSFER_READ_BIT);
}
pass_now = PASS_NONE;
#ifdef VLCPS5_HOST
const char *shot = plat_screenshot_path(gfx.frame_number);
if (shot) {
@@ -400,7 +744,8 @@ void gfx_end_frame(VkCommandBuffer cmd)
}
#endif
vkEndCommandBuffer(cmd);
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
/* (the HDR10 frame reaches the framebuffer by a copy) */
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
si.commandBufferCount = 1;
si.pCommandBuffers = &cmd;
@@ -490,7 +835,26 @@ bool gfx_image(uint32_t w, uint32_t h, VkFormat format, VkImageUsageFlags usage,
ai.memoryTypeIndex = gfx_memory_type(req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (ai.memoryTypeIndex == UINT32_MAX)
ai.memoryTypeIndex = gfx_memory_type(req.memoryTypeBits, 0);
CHECK(vkAllocateMemory(gfx.device, &ai, nullptr, memory));
VkResult r = vkAllocateMemory(gfx.device, &ai, nullptr, memory);
/* The video memory full (a 4K HDR film's decoder holds 840 MiB of it):
* any other kind the image can live in. Failing, a 4K video stayed
* black for the whole of its first open (2026-10-18). */
for (uint32_t t = 0; r != VK_SUCCESS && t < 32; t++) {
if (!(req.memoryTypeBits & (1u << t)) || t == ai.memoryTypeIndex)
continue;
VkMemoryAllocateInfo other = ai;
other.memoryTypeIndex = t;
r = vkAllocateMemory(gfx.device, &other, nullptr, memory);
if (r == VK_SUCCESS)
fprintf(stderr, "gfx: %ux%u image: video memory full, memory type %u instead\n", w, h, t);
}
if (r != VK_SUCCESS) {
fprintf(stderr, "gfx: no memory for a %ux%u image (%llu KiB): %d\n", w, h,
(unsigned long long)(req.size >> 10), r);
vkDestroyImage(gfx.device, *image, nullptr);
*image = VK_NULL_HANDLE;
return false;
}
CHECK(vkBindImageMemory(gfx.device, *image, *memory, 0));
VkImageViewCreateInfo vi = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
vi.image = *image;
+18
View File
@@ -26,6 +26,12 @@ struct Gfx {
bool offscreen; /* host test build */
uint32_t frame_slot; /* 0..GFX_FRAMES-1, the frame being recorded */
uint64_t frame_number; /* frames presented so far */
/* HDR10 output: the frame is drawn in a 10-bit image (video as PQ,
* BT.2020, the UI layer over it) and copied into the framebuffer, which
* VideoOut then shows as HDR10. */
VkRenderPass hdr_pass; /* the 10-bit frame's pass (null: no HDR output) */
bool hdr; /* HDR10 output on now */
int display_range; /* the output at start: 1 SDR, 2 HDR, other unknown */
};
extern Gfx gfx;
@@ -38,6 +44,18 @@ VkCommandBuffer gfx_begin_frame();
void gfx_begin_pass(VkCommandBuffer cmd);
/* Ends the pass, submits, presents (or saves the host screenshot). */
void gfx_end_frame(VkCommandBuffer cmd);
/* HDR10 output on or off (waits for the GPU); false if it couldn't change. */
bool gfx_set_hdr(bool on);
/* What the console sends to the TV now: 1 SDR, 2 HDR, other unknown. */
int gfx_output_range();
/* The output's refresh (VideoOut modes: 2 = 23.976 Hz, 3 = 24, 9 = 50,
* 1 = the default); the vblank period measured after, in microseconds. */
bool gfx_set_refresh(int mode, int *period_us);
/* With HDR10 output on, a frame is: the UI pass (ImGui into its own layer),
* then the HDR pass (the video, then gfx_draw_ui_layer), then gfx_end_frame. */
void gfx_begin_ui_pass(VkCommandBuffer cmd);
void gfx_begin_hdr_pass(VkCommandBuffer cmd); /* ends the UI pass */
void gfx_draw_ui_layer(VkCommandBuffer cmd);
/* The fence of the frame recorded in this slot has passed: its resources are free. */
uint64_t gfx_completed_frame();
+2
View File
@@ -664,6 +664,8 @@ void look_at(const Job &job)
libvlc_media_add_option(m, ":no-audio");
libvlc_media_add_option(m, ":no-spu");
libvlc_media_add_option(m, ":avcodec-threads=2");
/* the console's video decoder stays for the video being watched */
libvlc_media_add_option(m, ":no-ps5vdec");
Grab g;
g.frames = 0;
g.got = false;
+84 -4
View File
@@ -8,7 +8,9 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <math.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include "backends/imgui_impl_vulkan.h"
@@ -78,6 +80,9 @@ int main(void)
double t = plat_time();
float dt = (float)(t - last);
last = t;
/* the interface stood still: always in the log (a freeze report) */
if (dt > 0.5f && gfx.frame_number > 10)
fprintf(stderr, "ui: a frame took %.0f ms (the interface froze)\n", dt * 1000);
PadState pad;
plat_pad_read(&pad);
library_update();
@@ -92,16 +97,91 @@ int main(void)
ImGui::Render();
double t_ui = plat_time();
/* HDR10 output while an HDR video shows (once a refusal, not again
* until the wish changes) */
/* The wish has to hold a moment first: while a video starts (its
* picture set up, set up again) it came and went, and each switch
* blanks the screen (on, off, on, off in a second: a 2026-10-13 log). */
static bool hdr_refused;
static double wish_since;
static bool wish_last;
bool want_hdr = video_wants_hdr_output();
if (want_hdr != wish_last) {
wish_last = want_hdr;
wish_since = plat_time();
}
double hold = want_hdr ? 0.4 : 1.0;
if (want_hdr != gfx.hdr && !(want_hdr && hdr_refused) && plat_time() - wish_since >= hold)
hdr_refused = !gfx_set_hdr(want_hdr);
if (!want_hdr)
hdr_refused = false;
/* Match frame rate: the output's refresh follows the film playing
* (23.976 / 24 / 50 Hz), and goes back to the default after. Asked
* once a picture is up (the rate is known then); a mode the TV
* doesn't really run at (the vblanks say) is put back and not asked
* again for that video. */
{
static int mode_now = 1;
static std::string refused_for;
int want = 1;
const VideoInfo &vi = player_video_info();
if (player_match_rate() && player_active() && video_has_picture() && vi.fps > 0 &&
refused_for != player_current_path()) {
float f = vi.fps;
if (fabsf(f - 23.976f) < 0.01f)
want = 2;
else if (fabsf(f - 24.0f) < 0.01f)
want = 3;
else if (fabsf(f - 25.0f) < 0.05f || fabsf(f - 50.0f) < 0.1f)
want = 9;
}
if (want != mode_now) {
int period = 0;
bool ok = gfx_set_refresh(want, &period);
static const struct { int mode, us; } expect[] = { { 1, 16683 }, { 2, 41708 }, { 3, 41667 }, { 9, 20000 } };
int us = 0;
for (const auto &e : expect)
if (e.mode == want)
us = e.us;
if (ok && period > 0 && fabs(period - us) > us * 0.05) {
fprintf(stderr, "main: output mode %d taken but a vblank every %d us (not %d): default again\n",
want, period, us);
gfx_set_refresh(1, &period);
ok = false;
}
if (ok || want == 1) {
mode_now = ok ? want : 1;
} else {
refused_for = player_current_path();
if (mode_now != 1 && gfx_set_refresh(1, &period))
mode_now = 1;
}
fprintf(stderr, "main: refresh %s for %.3f fps\n", ok ? "matched" : "not matched", vi.fps);
}
}
VkCommandBuffer cmd = gfx_begin_frame();
if (!cmd)
continue;
double t_begin = plat_time();
video_upload(cmd);
gfx_begin_pass(cmd);
float vx, vy, vw, vh;
if (ui_video_rect(&vx, &vy, &vw, &vh))
video_draw(cmd, vx, vy, vw, vh);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
bool video = ui_video_rect(&vx, &vy, &vw, &vh);
if (gfx.hdr) {
/* the UI in its layer, then the video as PQ and the layer over it */
gfx_begin_ui_pass(cmd);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
gfx_begin_hdr_pass(cmd);
if (video)
video_draw(cmd, vx, vy, vw, vh);
gfx_draw_ui_layer(cmd);
} else {
gfx_begin_pass(cmd);
if (video)
video_draw(cmd, vx, vy, vw, vh);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
}
gfx_end_frame(cmd);
double t_end = plat_time();
+249
View File
@@ -15,6 +15,7 @@
#include <vlc/vlc.h>
#include "osub.h"
#include "platform.h"
#include "player.h"
@@ -391,6 +392,199 @@ bool list_menu(const std::string &url)
return true;
}
/* ---- search: every free TV channel and radio stations by name, fetched in
* the background while Search is typed into (not through Browse) ---- */
struct Fetch {
libvlc_media_t *m = nullptr;
bool loading = false;
std::string url;
std::vector<NetEntry> got;
};
Fetch radio_found;
int search_serial; /* changes when search results arrive */
/* Every free TV channel for Search: index.m3u downloaded and read here, as
* names, addresses and options only. Kept as VLC media (11,000 of them, each
* with its locks), it and the same list open in Browse ran the console out
* of mutexes: VLC aborts when it can't make one (crash, 2026-10-13). */
std::vector<NetEntry> tv_list; /* main thread */
std::mutex tv_lock;
std::vector<NetEntry> tv_arrived; /* from the download thread */
bool tv_has_arrived, tv_loading, tv_started;
std::thread tv_thread;
std::vector<NetEntry> parse_m3u(const std::string &text)
{
std::vector<NetEntry> out;
std::string name;
std::vector<std::string> opts;
size_t at = 0;
while (at < text.size()) {
size_t eol = text.find('\n', at);
if (eol == std::string::npos)
eol = text.size();
std::string line = text.substr(at, eol - at);
at = eol + 1;
while (!line.empty() && (line.back() == '\r' || line.back() == ' '))
line.pop_back();
if (line.empty())
continue;
if (line.compare(0, 8, "#EXTINF:") == 0) {
/* the name: after the first comma outside the attributes' quotes */
bool quoted = false;
size_t comma = std::string::npos;
for (size_t i = 8; i < line.size(); i++) {
if (line[i] == '"')
quoted = !quoted;
else if (line[i] == ',' && !quoted) {
comma = i;
break;
}
}
name = comma == std::string::npos ? "" : line.substr(comma + 1);
while (!name.empty() && name[0] == ' ')
name.erase(0, 1);
} else if (line.compare(0, 11, "#EXTVLCOPT:") == 0) {
opts.push_back(":" + line.substr(11));
} else if (line[0] != '#') {
NetEntry e;
e.url = line;
e.name = name.empty() ? line : name;
e.dir = false;
e.options.swap(opts);
out.push_back(std::move(e));
name.clear();
opts.clear();
}
}
return out;
}
void tv_start_download()
{
if (tv_started)
return;
tv_started = true;
tv_loading = true;
search_serial++;
std::string url = std::string(TV_LISTS) + "index.m3u";
fprintf(stderr, "net: search fetching %s\n", url.c_str());
tv_thread = std::thread([url] {
std::string body, error;
std::vector<NetEntry> got;
if (web_https_get(url, body, error))
got = parse_m3u(body);
fprintf(stderr, "net: search got %zu channels (%zu bytes)%s%s\n", got.size(), body.size(),
error.empty() ? "" : ": ", error.c_str());
std::lock_guard<std::mutex> g(tv_lock);
tv_arrived.swap(got);
tv_has_arrived = true;
});
}
std::string search_query, radio_query; /* typed; last asked of radio-browser */
double search_typed_at;
void fetch_clear(Fetch &f)
{
if (f.m) {
if (f.loading)
libvlc_media_parse_stop(f.m);
libvlc_media_release(f.m);
f.m = nullptr;
}
f.loading = false;
for (NetEntry &e : f.got)
if (e.media)
libvlc_media_release(e.media);
f.got.clear();
}
void fetch_start(Fetch &f, const std::string &url)
{
fetch_clear(f);
libvlc_instance_t *vlc = player_vlc();
f.url = url;
f.m = vlc ? libvlc_media_new_location(vlc, url.c_str()) : nullptr;
if (f.m && libvlc_media_parse_with_options(f.m, libvlc_media_parse_network, 20000) == 0) {
f.loading = true;
fprintf(stderr, "net: search fetching %s\n", url.c_str());
}
search_serial++;
}
void fetch_poll(Fetch &f)
{
if (!f.loading || libvlc_media_get_parsed_status(f.m) == 0)
return;
f.loading = false;
if (libvlc_media_list_t *subs = libvlc_media_subitems(f.m)) {
libvlc_media_list_lock(subs);
for (int i = 0; i < libvlc_media_list_count(subs); i++) {
libvlc_media_t *m = libvlc_media_list_item_at_index(subs, i);
if (!m)
continue;
char *mrl = libvlc_media_get_mrl(m), *title = libvlc_media_get_meta(m, libvlc_meta_Title);
if (mrl && libvlc_media_get_type(m) != libvlc_media_type_directory) {
NetEntry e;
e.url = mrl;
e.name = title ? title : e.url.substr(e.url.rfind('/') + 1);
e.dir = false;
e.media = m;
libvlc_media_retain(m);
f.got.push_back(e);
}
free(mrl);
free(title);
libvlc_media_release(m);
}
libvlc_media_list_unlock(subs);
libvlc_media_list_release(subs);
}
fprintf(stderr, "net: search got %zu from %s\n", f.got.size(), f.url.c_str());
search_serial++;
}
std::string url_encode(const std::string &s)
{
std::string out;
for (unsigned char c : s) {
if (isalnum(c) || c == '-' || c == '.' || c == '_') {
out += (char)c;
} else {
char h[4];
snprintf(h, sizeof(h), "%%%02X", c);
out += h;
}
}
return out;
}
void search_update()
{
{
std::lock_guard<std::mutex> g(tv_lock);
if (tv_has_arrived) {
tv_has_arrived = false;
tv_list.swap(tv_arrived);
tv_loading = false;
if (tv_list.empty())
tv_started = false; /* failed: asked again the next time Search is used */
search_serial++;
}
}
if (!tv_loading && tv_thread.joinable())
tv_thread.join();
fetch_poll(radio_found);
/* radio-browser is asked once the typing pauses */
if (search_query.size() >= 2 && search_query != radio_query && plat_time() - search_typed_at > 0.6) {
radio_query = search_query;
fetch_start(radio_found, std::string(RADIO_LISTS) + "byname/" + url_encode(search_query) +
"?limit=40&order=clickcount&reverse=true&hidebroken=true");
}
}
} // namespace
void net_init()
@@ -430,6 +624,10 @@ void net_shutdown()
upnp_starter.join();
net_list_stop();
clear_entries();
if (tv_thread.joinable())
tv_thread.join();
tv_list.clear();
fetch_clear(radio_found);
if (upnp) {
libvlc_media_discoverer_stop(upnp);
libvlc_media_discoverer_release(upnp);
@@ -455,6 +653,7 @@ void net_update()
libvlc_dialog_dismiss(id);
if (list_state == NET_LOADING && libvlc_media_get_parsed_status(listing) != 0)
finish_listing();
search_update();
}
std::vector<NetServer> net_servers()
@@ -497,6 +696,56 @@ void net_forget_server(const std::string &url)
store_saved();
}
void net_search_typed(const std::string &query)
{
std::string q = query;
while (!q.empty() && q.back() == ' ')
q.pop_back();
while (!q.empty() && q[0] == ' ')
q.erase(0, 1);
tv_start_download(); /* once a session (again if it failed) */
if (q != search_query) {
search_query = q;
search_typed_at = plat_time();
if (q.size() < 2) {
fetch_clear(radio_found);
radio_query.clear();
}
}
}
bool net_search_busy()
{
return tv_loading || radio_found.loading ||
(search_query.size() >= 2 && search_query != radio_query);
}
int net_search_serial()
{
return search_serial;
}
const std::vector<NetEntry> &net_search_tv()
{
return tv_list;
}
const std::vector<NetEntry> &net_search_radio()
{
return radio_found.got;
}
libvlc_media_t *net_search_media(const std::string &url)
{
for (NetEntry &e : radio_found.got)
if (e.url == url && e.media) {
libvlc_media_retain(e.media);
return e.media;
}
return nullptr;
}
bool net_is_saved_server(const std::string &url)
{
for (const Saved &s : saved)
+10
View File
@@ -23,6 +23,7 @@ struct NetEntry {
std::string url; /* no login in it: net_login_options() gives it */
bool dir;
libvlc_media_t *media = nullptr; /* VLC's own item (keeps a list's #EXTVLCOPT) */
std::vector<std::string> options; /* or a list's #EXTVLCOPT as media options (":http-referrer=...") */
};
enum NetListState { NET_IDLE, NET_LOADING, NET_READY, NET_FAILED };
@@ -60,6 +61,15 @@ libvlc_media_t *net_take_media(const std::string &url);
/* The media options that log in to an address's saved share (":smb-user=..."). */
std::vector<std::string> net_login_options(const std::string &url);
/* Search, as it's typed: every free TV channel (the whole list, fetched once a
* session) and radio stations by name (asked once the typing pauses). */
void net_search_typed(const std::string &query);
bool net_search_busy();
int net_search_serial(); /* changes when results arrive */
const std::vector<NetEntry> &net_search_tv();
const std::vector<NetEntry> &net_search_radio();
libvlc_media_t *net_search_media(const std::string &url); /* with a reference, or null */
/* What VLC is asking (login / question), answered from the interface. */
NetAsk net_ask();
void net_answer_login(const std::string &user, const std::string &password, bool remember);
+16
View File
@@ -584,6 +584,22 @@ bool start()
} // namespace
/* A plain HTTPS download (redirects followed), for other parts of the app. */
bool web_https_get(const std::string &url, std::string &body, std::string &error)
{
Reply r = https_get(url);
if (!r.error.empty()) {
error = r.error;
return false;
}
if (r.status != 200) {
error = "HTTP " + std::to_string(r.status);
return false;
}
body.swap(r.body);
return true;
}
bool osub_has_key()
{
return !pref_str("osub_key", "").empty();
+3
View File
@@ -34,3 +34,6 @@ OsubState osub_state();
std::vector<SubResult> osub_results();
std::string osub_message(); /* what went wrong, or "12 downloads left today" */
std::string osub_saved_path(); /* the file a download wrote, once */
/* A plain HTTPS GET (redirects followed; blocking: a background thread's). */
bool web_https_get(const std::string &url, std::string &body, std::string &error);
+1 -1
View File
@@ -23,7 +23,7 @@ extern "C" {
#endif
#define VLC_PS5_TITLE_ID "PPSA85300"
#define VLC_PS5_VERSION "0.3"
#define VLC_PS5_VERSION "0.4.5"
/* DualSense buttons (scePadRead's layout, as QUICK3 and PS5_vkQuake use it),
* plus the triggers past half as buttons. */
+21 -2
View File
@@ -10,6 +10,7 @@
* options touchpad)
* <frame> hold <button> <frames>
* <frame> shot <file.png> saves that frame
* <frame> type <text> the on-screen keyboard gets it (_ for a space)
* <frame> quit
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -23,11 +24,11 @@
#include <time.h>
#include <unistd.h>
#define MAX_STEPS 512
#define MAX_STEPS 20000 /* a long stress tour has thousands */
typedef struct {
uint64_t frame;
enum { STEP_HOLD, STEP_SHOT, STEP_QUIT, STEP_STICK } kind;
enum { STEP_HOLD, STEP_SHOT, STEP_QUIT, STEP_STICK, STEP_TYPE } kind;
uint32_t button;
float rx, ry; /* STEP_STICK: the right stick, held for frames */
uint64_t frames;
@@ -87,6 +88,11 @@ static void load_script(void)
s->frames = frames;
} else if (!strcmp(word, "shot") && sscanf(line, "%*u %*s %255s", s->path) == 1) {
s->kind = STEP_SHOT;
} else if (!strcmp(word, "type") && sscanf(line, "%*u %*s %255s", s->path) == 1) {
s->kind = STEP_TYPE;
for (char *c = s->path; *c; c++)
if (*c == '_')
*c = ' ';
} else if (!strcmp(word, "quit")) {
s->kind = STEP_QUIT;
quit_frame = frame;
@@ -255,3 +261,16 @@ bool plat_script_done(uint64_t frame)
{
return frame >= quit_frame;
}
/* Script "type" steps due by now, once (the interface's keyboard reads it). */
const char *plat_take_typed(void)
{
static int next;
for (; next < nsteps; next++) {
if (steps[next].frame > frame_now)
break;
if (steps[next].kind == STEP_TYPE)
return steps[next++].path;
}
return NULL;
}
+158 -5
View File
@@ -124,6 +124,14 @@ static void crash_handler(int sig, siginfo_t *info, void *context)
/* " name " of each import left unresolved: optional calls check it first. */
static char unresolved[2048] = " ";
/* the video decoder's import slots (imports.txt), checked once its library
* is loaded */
#define VDEC_SLOTS 16
static struct {
unsigned long offset;
char name[48];
} vdec_slots[VDEC_SLOTS];
static int vdec_slot_count;
static bool import_resolved(const char *name)
{
@@ -132,6 +140,69 @@ static bool import_resolved(const char *name)
return strstr(unresolved, key) == NULL;
}
/* settings.txt's "key=value" at start (read before full access: /app0 may
* be gone after it). */
static int boot_setting(const char *key, int fallback)
{
FILE *s = fopen(APP_DIR "/settings.txt", "r");
if (!s)
return fallback;
char line[128];
size_t n = strlen(key);
int value = fallback;
while (fgets(line, sizeof(line), s))
if (!strncmp(line, key, n) && line[n] == '=')
value = atoi(line + n + 1);
fclose(s);
return value;
}
/* The console's video decoder (ps5/modules/ps5vdec.c). Its library (sysmodule
* 207) and compute queue are made before the Helper's full access: after it
* the library is refused (0x80020063, console run 11) and the queue too
* (0x811D0111, run 12). Run 10's "no jailbreak daemon answered" with the
* library loaded first was the Helper not running then (run 12: it answered
* in 60 ms). settings.txt vdec_load=0 loads it after full access instead,
* hw_decode=0 not at all. */
int sceSysmoduleLoadModule(uint16_t id);
void vlc_ps5_vdec_prepare(void) __attribute__((weak)); /* ps5/modules/ps5vdec.c */
void vlc_ps5_vdec_probe(const char *when) __attribute__((weak));
#define SYSMODULE_VIDEODEC2 207
static bool vdec_ready;
static double jb_wait = 2.5; /* seconds the Helper has to answer */
static void load_video_decoder(void)
{
/* (the decoder's own functions only get their addresses with the
* library: they're checked after loading it, below) */
if (!import_resolved("sceSysmoduleLoadModule")) {
fprintf(stderr, "VLC-PS5: hardware decoding off: sceSysmoduleLoadModule unresolved\n");
return;
}
int rc = sceSysmoduleLoadModule(SYSMODULE_VIDEODEC2);
vdec_ready = rc == 0;
/* now its functions must have their addresses (imports.txt known): an
* empty one would be a jump to 0 */
for (int i = 0; vdec_ready && i < vdec_slot_count; i++) {
if (*(const uint64_t *)(EBOOT_BASE + vdec_slots[i].offset) == 0) {
fprintf(stderr, "VLC-PS5: %s still unresolved after loading the library\n", vdec_slots[i].name);
vdec_ready = false;
}
}
fprintf(stderr, "VLC-PS5: video decoder library %#x: hardware decoding %s (%d functions checked)\n",
(unsigned)rc, vdec_ready ? "on" : "off", vdec_slot_count);
/* its compute queue now too, while still in the sandbox */
if (vdec_ready && vlc_ps5_vdec_prepare)
vlc_ps5_vdec_prepare();
if (vdec_ready && vlc_ps5_vdec_probe)
vlc_ps5_vdec_probe(plat_full_access() ? "after full access" : "before full access");
}
int vlc_ps5_vdec_available(void)
{
return vdec_ready;
}
/* Every import the console left unresolved (a call would jump to 0), in one
* report: imports.txt lists each GOT slot's offset and symbol. */
static void report_unresolved_imports(void)
@@ -146,6 +217,16 @@ static void report_unresolved_imports(void)
int checked = 0, missing = 0;
while (fscanf(f, "%lx %127s", &offset, name) == 2) {
checked++;
/* the video decoder's are filled in when its library is loaded
* (load_video_decoder), not at start: looked at after that */
if (!strncmp(name, "sceVideodec2", 12)) {
if (vdec_slot_count < VDEC_SLOTS) {
vdec_slots[vdec_slot_count].offset = offset;
snprintf(vdec_slots[vdec_slot_count].name, sizeof(vdec_slots[0].name), "%s", name);
vdec_slot_count++;
}
continue;
}
if (*(const uint64_t *)(EBOOT_BASE + offset) == 0) {
fprintf(stderr, "VLC-PS5: unresolved import: %s\n", name);
if (strlen(unresolved) + strlen(name) + 2 < sizeof(unresolved)) {
@@ -176,11 +257,48 @@ static bool exists(const char *path)
* resolve; otherwise the sandbox's own copy of it (/mnt/sandbox/<title>_NNN/app0,
* the folder the daemon found our request in) or the folder
* ShadowMountPlus launched us from. */
/* Our folder is marked before full access (/app0 is gone after it), so the
* search below finds this launch's folder and not another: the first
* PPSA85300_ entry of /mnt/sandbox, as first done, could be an older launch's
* or another copy of the app, whose prefs.txt then came up (the look
* switching between Classic and Modern "by itself"). */
#define INSTANCE_FILE "/cache/instance.txt"
static char instance_mark[64];
static void mark_app_dir(void)
{
snprintf(instance_mark, sizeof(instance_mark), "%d-%.0f", (int)getpid(), plat_time() * 1000);
mkdir(APP_DIR "/cache", 0777);
FILE *f = fopen(APP_DIR INSTANCE_FILE, "w");
if (!f) {
instance_mark[0] = 0;
return;
}
fputs(instance_mark, f);
fclose(f);
}
static bool is_marked(const char *dir)
{
if (!instance_mark[0])
return false;
char path[300], got[64] = "";
snprintf(path, sizeof(path), "%s" INSTANCE_FILE, dir);
FILE *f = fopen(path, "r");
if (!f)
return false;
if (!fgets(got, sizeof(got), f))
got[0] = 0;
fclose(f);
return !strcmp(got, instance_mark);
}
static void find_app_dir(void)
{
if (exists(APP_DIR "/eboot.bin"))
return;
char path[256];
char path[256], first[256] = "";
int candidates = 0;
DIR *d = opendir("/mnt/sandbox");
if (d) {
struct dirent *e;
@@ -188,13 +306,27 @@ static void find_app_dir(void)
if (strncmp(e->d_name, VLC_PS5_TITLE_ID "_", sizeof(VLC_PS5_TITLE_ID)))
continue;
snprintf(path, sizeof(path), "/mnt/sandbox/%s/app0/eboot.bin", e->d_name);
if (exists(path)) {
snprintf(app_dir, sizeof(app_dir), "/mnt/sandbox/%s/app0", e->d_name);
if (!exists(path))
continue;
candidates++;
snprintf(path, sizeof(path), "/mnt/sandbox/%s/app0", e->d_name);
fprintf(stderr, "VLC-PS5: candidate folder %s%s\n", path, is_marked(path) ? " (ours)" : "");
if (!first[0])
snprintf(first, sizeof(first), "%s", path);
if (is_marked(path)) {
snprintf(app_dir, sizeof(app_dir), "%s", path);
break;
}
}
closedir(d);
}
/* no mark found: the first one, as before */
if (!strcmp(app_dir, APP_DIR) && first[0] && !(instance_mark[0] && candidates > 1))
snprintf(app_dir, sizeof(app_dir), "%s", first);
if (!strcmp(app_dir, APP_DIR) && is_marked("/data/homebrew/" VLC_PS5_TITLE_ID))
snprintf(app_dir, sizeof(app_dir), "/data/homebrew/" VLC_PS5_TITLE_ID);
if (!strcmp(app_dir, APP_DIR) && first[0])
snprintf(app_dir, sizeof(app_dir), "%s", first);
if (!strcmp(app_dir, APP_DIR) && exists("/data/homebrew/" VLC_PS5_TITLE_ID "/eboot.bin"))
snprintf(app_dir, sizeof(app_dir), "/data/homebrew/" VLC_PS5_TITLE_ID);
if (!strcmp(app_dir, APP_DIR))
@@ -224,6 +356,7 @@ static bool lifted(void)
static void request_full_access(void)
{
mark_app_dir();
if (lifted()) {
full_access = true;
fprintf(stderr, "VLC-PS5: full access already (euid %d)\n", (int)__real_geteuid());
@@ -268,12 +401,14 @@ static void request_full_access(void)
unlink(JB_STAGED);
return;
}
/* (2.5 s: a busy daemon took longer than the 1 s first allowed) */
double start = plat_time();
while (exists(JB_REQUEST) && plat_time() - start < 1.0)
while (exists(JB_REQUEST) && plat_time() - start < jb_wait)
usleep(20000);
if (exists(JB_REQUEST)) {
unlink(JB_REQUEST); /* nobody listening: don't leave it for a daemon started later */
fprintf(stderr, "VLC-PS5: sandboxed (no jailbreak daemon answered in 1 s)\n");
fprintf(stderr, "VLC-PS5: sandboxed (no jailbreak daemon answered in %.1f s): no phone/PC page, "
"no DLNA server; is etaHEN or the Helper running, PPSA85300 whitelisted?\n", jb_wait);
return;
}
/* Taken. Daemons set the effective uid (the real one can stay as it was)
@@ -310,6 +445,10 @@ static void use_app_dir(void)
snprintf(path, sizeof(path), "%s/cache/mesa", app_dir);
mkdir(path, 0777);
setenv("MESA_SHADER_CACHE_DIR", path, 1);
/* libbluray keeps its cache in $HOME/.cache/bluray and makes only the
* last folder ("Error creating directory" in every disc's log) */
snprintf(path, sizeof(path), "%s/.cache", app_dir);
mkdir(path, 0777);
fprintf(stderr, "VLC-PS5: shader caches in %s/cache\n", app_dir);
}
@@ -378,7 +517,21 @@ void plat_init(void)
signal(SIGPIPE, SIG_IGN);
report_unresolved_imports();
/* the decoder library and its compute queue first, then full access: the
* Helper answered in 60 ms with them loaded (console run 12), and both
* fail after full access (0x80020063, 0x811D0111). vdec_load=0: after. */
int hw_decode = boot_setting("hw_decode", 1), vdec_load = boot_setting("vdec_load", 1);
if (!hw_decode)
fprintf(stderr, "VLC-PS5: hardware decoding off (settings.txt): decoder library not loaded\n");
if (hw_decode && vdec_load == 1) {
load_video_decoder();
jb_wait = 6;
}
request_full_access();
if (hw_decode && vdec_load != 1)
load_video_decoder();
else if (vdec_ready && vlc_ps5_vdec_probe && plat_full_access())
vlc_ps5_vdec_probe("after full access");
use_app_dir();
}
+935 -96
View File
File diff suppressed because it is too large. Load diff
+17
View File
@@ -24,6 +24,8 @@ struct VideoInfo {
uint32_t width, height; /* visible size */
float aspect; /* display aspect, sample aspect applied */
bool ten_bit;
int hdr; /* 0 SDR, 1 HDR10 (PQ), 2 HLG */
bool hardware; /* on the console's video decoder */
float fps; /* 0 if the file doesn't say */
std::string codec, audio_codec;
unsigned audio_channels;
@@ -88,7 +90,18 @@ void player_spectrum(float *bands, int n);
/* Render thread, every frame: */
void video_upload(VkCommandBuffer cmd); /* before the render pass */
bool video_has_picture();
/* seconds since the video was opened */
double player_open_age();
/* An HDR video is showing and HDR10 output is wanted for it (settings.txt
* hdr_output, the console's output). */
bool video_wants_hdr_output();
/* Match frame rate: films at 23.976 / 24 / 25 / 50 fps switch the TV to that
* refresh while they play (saved; Off by default: some TVs blank a moment). */
bool player_match_rate();
const std::string &player_current_path(); /* what plays (or was last opened) */
void player_set_match_rate(bool on);
void video_draw(VkCommandBuffer cmd, float x, float y, float w, float h); /* in the pass */
float video_picture_aspect(); /* the pictures VLC sends now: width / height (0: none yet) */
void video_forget_picture(); /* back to the library */
/* One line about the player in the log (state, time, picture slots, sound queue,
* pictures decoded/shown/lost since the last line). */
@@ -173,6 +186,10 @@ void player_set_debug_log(bool on);
DecodeMode player_decode_mode();
void player_set_decode_mode(DecodeMode mode); /* saved; applies from the next file */
bool player_fast_decoding(); /* the current file decodes fast */
/* Hardware decoding (the console's video decoder) or FFmpeg on the CPU:
* saved; applies from the next video. */
bool player_hw_decoding();
void player_set_hw_decoding(bool on);
/* Main thread, every frame while playing: watches for lost pictures. */
enum PlayerEvent { PLAYER_EVENT_NONE, PLAYER_EVENT_WENT_FAST, PLAYER_EVENT_TOO_SLOW };
PlayerEvent player_tick();
+218 -39
View File
@@ -171,9 +171,11 @@ std::string vlc_message(const std::string &m)
}
if (m.compare(0, 14, "Please provide") == 0)
return "A Windows PC takes its own account; a NAS, the user you made on it.";
/* libbluray without a JVM (none runs on the console): not "install Java" */
/* libbluray without a JVM (none runs on the console): not "install Java".
* Said plainly: "it plays without them" promised a film that often
* didn't come (the user, 2026-10-18). */
if (m.compare(0, 30, "This Blu-ray disc requires Java") == 0)
return "This Blu-ray's menus are made in Java, which the PS5 can't run: it plays without them";
return "Java Blu-ray discs (BD-J) aren't supported on the PS5";
if (m.compare(0, 6, "Track ") == 0 && m.size() > 6 && isdigit((unsigned char)m[6]))
return trf("Track %d", atoi(m.c_str() + 6));
return m;
@@ -544,6 +546,15 @@ void ci_add(float cx, float cy, float s)
rect(cx + s * 0.278f, cy + s * 0.17f, s * 0.045f, s * 0.18f, IM_COL32(255, 255, 255, 255));
}
void icon_link(float cx, float cy, float s, ImU32 col);
/* Open a network link: a blue disc with a chain link */
void ci_link(float cx, float cy, float s)
{
circle(cx, cy, s * 0.38f, IM_COL32(52, 120, 214, 255));
icon_link(cx, cy, s * 0.46f, IM_COL32(255, 255, 255, 255));
}
/* ---- icons, drawn so they stay sharp at any size ----------------------------------- */
void icon_play(float cx, float cy, float s, ImU32 col)
@@ -1020,7 +1031,7 @@ void rebuild_lists()
/* Network places in Browse: a server (saved SMB share or DLNA server), a
* folder or file on it, and "Add a network share". */
enum { NET_NONE, NET_SERVER, NET_DIR, NET_FILE, NET_ADD, NET_ONLINE };
enum { NET_NONE, NET_SERVER, NET_DIR, NET_FILE, NET_ADD, NET_ONLINE, NET_LINK };
struct BrowseEntry {
std::string name, path;
@@ -1122,6 +1133,7 @@ void rebuild_browse()
for (const NetServer &sv : net_servers())
browse_entries.push_back({ sv.name, sv.url, true, -1, false, NET_SERVER });
browse_entries.push_back({ "Add a network share", "", false, -1, false, NET_ADD });
browse_entries.push_back({ "Open a network link", "", false, -1, false, NET_LINK });
browse_entries.push_back({ "Free TV channels", "tv:", true, -1, false, NET_ONLINE });
browse_entries.push_back({ "Internet radio", "radio:", true, -1, false, NET_ONLINE });
return;
@@ -1253,8 +1265,11 @@ void save_position(bool finished)
{
if (playing_path.empty() || is_link(playing_path))
return;
int64_t t = finished ? 0 : player_time();
library_set_resume(playing_path, t, player_length());
int64_t t = finished ? 0 : player_time(), len = player_length();
/* nothing known (the player busy stopping): the saved spot stays */
if (!finished && len <= 0)
return;
library_set_resume(playing_path, t, len);
}
void leave_player(bool finished)
@@ -2446,6 +2461,7 @@ std::vector<std::pair<uint32_t, const char *>> playlist_hints()
void start_stream(const std::string &url, const std::vector<std::string> &options = {}, bool remember = true,
const std::string &name = "", libvlc_media_t *media = nullptr);
void open_add_share();
void open_link();
void spinner(float cx, float cy, float r);
@@ -2603,7 +2619,7 @@ void classic_label(const BrowseEntry &e, std::string *name, std::string *type, i
if (e.net == NET_SERVER) {
*type = net_is_saved_server(e.path) ? "Network share (SMB)" : "Media server (DLNA)";
*group = 1;
} else if (e.net == NET_ADD) {
} else if (e.net == NET_ADD || e.net == NET_LINK) {
*type = "";
*group = 1;
} else if (e.net == NET_ONLINE) {
@@ -2669,6 +2685,8 @@ void classic_icon(const BrowseEntry &e, float cx, float cy, float s)
ci_server(cx, cy, s);
else if (e.net == NET_ADD)
ci_add(cx, cy, s);
else if (e.net == NET_LINK)
ci_link(cx, cy, s);
else if (e.net == NET_ONLINE)
e.path == "tv:" ? ci_tv(cx, cy, s) : ci_radio(cx, cy, s);
else if (e.net == NET_FILE)
@@ -2908,6 +2926,8 @@ void mini_player()
text(f_reg, 17, kx + 46, y + 17, C_DIM, "Open");
}
void open_search(const std::string &text = "");
void tab_browse()
{
/* The network listing or the servers found changed: rebuild. */
@@ -2976,6 +2996,8 @@ void tab_browse()
BrowseEntry e = browse_entries[browse_focus];
if (e.net == NET_ADD) {
open_add_share();
} else if (e.net == NET_LINK) {
open_link();
} else if (e.net == NET_SERVER || e.net == NET_DIR || e.net == NET_ONLINE) {
net_enter(e.path, e.name);
} else {
@@ -3084,6 +3106,8 @@ void tab_browse()
icon_radio(146, y + 33, 34, mix(C_DIM, C_ORANGE, f));
else if (e.net == NET_ADD)
icon_plus_circle(146, y + 33, 32, mix(C_DIM, C_ORANGE, f));
else if (e.net == NET_LINK)
icon_link(146, y + 33, 30, mix(C_DIM, C_ORANGE, f));
else if (e.net == NET_FILE) {
int k = name_kind(e.name);
if (k == 1)
@@ -3322,8 +3346,16 @@ void kb_backspace()
/* Draws the keyboard at (x, y), w wide; handles the buttons when it has the
* focus. Returns true on Done. *leave_up: ↑ was pressed on the top row. */
#ifdef VLCPS5_HOST
extern "C" const char *plat_take_typed(void); /* the test script's "type" steps */
#endif
bool kb_frame(float x, float y, float w, bool focused, float a, bool *leave_up)
{
#ifdef VLCPS5_HOST
if (const char *typed = plat_take_typed())
kb.text += typed;
#endif
const float gap = 10, kh = 62;
float kw = (w - 9 * gap) / 10;
std::vector<int> bottom = kb_bottom();
@@ -3474,15 +3506,24 @@ void text_box(float x, float y, float w, const char *placeholder, float a, bool
/* ---- Search and Open a network link -------------------------------------------- */
enum FoundKind { F_ITEM, F_PLAYLIST, F_BROWSE, F_SERVER, F_LINK, F_TV, F_STATION, F_BUSY };
struct Found {
int item; /* library index, or -1 */
int playlist; /* playlist index, or -1 */
std::string link;
int kind;
int index = -1; /* library item, playlist or Browse entry */
std::string link; /* a server's or a recent link's address */
};
std::vector<Found> found;
int found_focus;
bool in_list; /* focus on the list (above the keyboard) */
std::string found_for = "\x01";
int found_serial = -1; /* the Browse network listing searched */
int found_online = -1; /* the online results searched (net_search_serial) */
/* Searching from inside a network list (a channel list, a share): its entries too. */
bool search_in_browse()
{
return screen == LIBRARY && tab == BROWSE && !net_path.empty() && !sub_pick;
}
std::string lower_ascii(std::string s)
{
@@ -3491,26 +3532,78 @@ std::string lower_ascii(std::string s)
return s;
}
std::vector<std::string> recent_links();
std::string link_name(const std::string &url);
/* Everything the app knows by name: the list open in Browse (channels, a
* share's folder), playlists, videos and songs, saved shares and servers,
* recent links, and the online lists (every free TV channel, radio stations
* by name). */
void update_search()
{
if (found_for == kb.text)
int serial = search_in_browse() ? net_list_serial() : -1;
net_search_typed(kb.text);
int online = net_search_serial() * 2 + (net_search_busy() ? 1 : 0);
if (found_for == kb.text && found_serial == serial && found_online == online)
return;
bool typed = found_for != kb.text;
found_for = kb.text;
found_serial = serial;
found_online = online;
found.clear();
if (typed)
found_focus = 0;
std::string q = lower_ascii(kb.text);
while (!q.empty() && q.back() == ' ')
q.pop_back();
while (!q.empty() && q[0] == ' ')
q.erase(0, 1);
if (q.empty())
return;
auto has = [&](const std::string &name) { return lower_ascii(name).find(q) != std::string::npos; };
if (serial >= 0) {
/* The list open in Browse first: that's what is being looked through. */
int got = 0;
for (int i = 0; i < (int)browse_entries.size() && got < 200; i++)
if (browse_entries[i].net != NET_NONE && browse_entries[i].net != NET_ADD && browse_entries[i].net != NET_LINK && has(browse_entries[i].name)) {
found.push_back({ F_BROWSE, i });
got++;
}
}
auto &pls = library_playlists();
for (int i = 0; i < (int)pls.size(); i++)
if (lower_ascii(pls[i].name).find(q) != std::string::npos)
found.push_back({ -1, i, "" });
for (int i = 0; i < (int)L().size() && found.size() < 60; i++)
if (lower_ascii(L()[i].name).find(q) != std::string::npos ||
lower_ascii(L()[i].folder.substr(L()[i].folder.rfind('/') + 1)).find(q) != std::string::npos)
found.push_back({ i, -1, "" });
found_focus = 0;
if (has(pls[i].name))
found.push_back({ F_PLAYLIST, i });
int items = 0;
for (int i = 0; i < (int)L().size() && items < 100; i++)
if (has(L()[i].name) || has(L()[i].folder.substr(L()[i].folder.rfind('/') + 1))) {
found.push_back({ F_ITEM, i });
items++;
}
for (const NetServer &sv : net_servers())
if (has(sv.name) || has(sv.url))
found.push_back({ F_SERVER, -1, sv.url });
for (const std::string &l : recent_links())
if (has(link_name(l)) || has(l))
found.push_back({ F_LINK, -1, l });
/* Online, as it comes: free TV channels and radio stations, played
* straight from here */
if (q.size() >= 2) {
const std::vector<NetEntry> &tv = net_search_tv();
int got = 0;
for (int i = 0; i < (int)tv.size() && got < 60; i++)
if (has(tv[i].name)) {
found.push_back({ F_TV, i });
got++;
}
const std::vector<NetEntry> &radio = net_search_radio();
for (int i = 0; i < (int)radio.size() && i < 40; i++)
found.push_back({ F_STATION, i });
if (net_search_busy())
found.push_back({ F_BUSY });
}
if (found_focus >= (int)found.size())
found_focus = found.empty() ? 0 : (int)found.size() - 1;
}
/* Recent links, newest first: cache/links.txt. */
@@ -3626,9 +3719,9 @@ void start_stream(const std::string &url, const std::vector<std::string> &option
was_active = false;
}
void open_search()
void open_search(const std::string &text)
{
kb_open("", false);
kb_open(text, false);
found_for = "\x01";
in_list = false;
modal = SEARCH;
@@ -4424,12 +4517,46 @@ void modal_text_screen()
std::string title, sub;
if (search) {
const Found &r = found[i];
if (r.playlist >= 0) {
if (r.kind == F_TV) {
icon_tv(x + 22, ry + 26, 28, alpha(C_DIM, a));
title = net_search_tv()[r.index].name;
sub = tr("Free TV channels");
} else if (r.kind == F_STATION) {
icon_radio(x + 22, ry + 26, 28, alpha(C_DIM, a));
title = net_search_radio()[r.index].name;
sub = tr("Internet radio");
} else if (r.kind == F_BUSY) {
spinner(x + 22, ry + 26, 12);
title = tr("Looking for channels and stations\xE2\x80\xA6");
} else if (r.kind == F_SERVER) {
icon_server(x + 22, ry + 26, 28, alpha(C_DIM, a));
title = r.link;
for (const NetServer &sv : net_servers())
if (sv.url == r.link)
title = sv.name;
sub = tr("Network");
} else if (r.kind == F_LINK) {
icon_link(x + 22, ry + 26, 28, alpha(C_DIM, a));
title = link_name(r.link);
sub = r.link;
} else if (r.kind == F_BROWSE) {
const BrowseEntry &b = browse_entries[r.index];
if (b.dir)
icon_folder(x + 22, ry + 26, 28, alpha(C_DIM, a));
else if (net_path[0].first.compare(0, 3, "tv:") == 0)
icon_tv(x + 22, ry + 26, 28, alpha(C_DIM, a));
else if (net_path[0].first.compare(0, 6, "radio:") == 0)
icon_radio(x + 22, ry + 26, 28, alpha(C_DIM, a));
else
icon_film(x + 22, ry + 26, 30, alpha(C_DIM, a));
title = b.name;
sub = net_path.back().second;
} else if (r.kind == F_PLAYLIST) {
icon_list(x + 22, ry + 26, 28, alpha(C_DIM, a));
title = library_playlists()[r.playlist].name;
title = library_playlists()[r.index].name;
sub = "Playlist";
} else {
const MediaItem &m = L()[r.item];
const MediaItem &m = L()[r.index];
if (m.audio)
icon_note(x + 22, ry + 26, 26, alpha(C_DIM, a));
else
@@ -4456,14 +4583,41 @@ void modal_text_screen()
if (search) {
Found r = found[found_focus];
modal = NONE;
if (r.playlist >= 0) {
play_playlist(library_playlists()[r.playlist].path);
if (r.kind == F_BUSY) {
modal = SEARCH; /* nothing to open yet: stay */
} else if (r.kind == F_TV || r.kind == F_STATION) {
const NetEntry e = (r.kind == F_TV ? net_search_tv() : net_search_radio())[r.index];
start_stream(e.url, e.options, false, e.name, net_search_media(e.url));
} else if (r.kind == F_SERVER) {
/* a place of Browse, opened from its top (○ walks back up) */
screen = LIBRARY;
screen_fade = 0;
tab = BROWSE;
net_path.clear();
browse_dir.clear();
std::string name = r.link;
for (const NetServer &sv : net_servers())
if (sv.url == r.link)
name = sv.name;
net_enter(r.link, name);
} else if (r.kind == F_LINK) {
start_stream(r.link);
} else if (r.kind == F_BROWSE) {
/* as ✕ on that row of Browse */
BrowseEntry e = browse_entries[r.index];
browse_focus = r.index;
if (e.dir)
net_enter(e.path, e.name);
else
start_stream(e.path, net_login_options(e.path), false, e.name, net_take_media(e.path));
} else if (r.kind == F_PLAYLIST) {
play_playlist(library_playlists()[r.index].path);
} else {
std::vector<int> list;
for (const Found &x2 : found)
if (x2.item >= 0 && (!L()[x2.item].other || x2.item == r.item))
list.push_back(x2.item);
open_item(r.item, list);
if (x2.kind == F_ITEM && (!L()[x2.index].other || x2.index == r.index))
list.push_back(x2.index);
open_item(r.index, list);
}
} else {
std::string url = links[found_focus];
@@ -4621,10 +4775,10 @@ void modal_options()
};
std::vector<Item> items;
if (in_player)
items = { { "Resume", OI_RESUME }, { "Audio, subtitles and more", OI_TRACKS },
items = { { "Resume", OI_RESUME }, { "Audio, subtitles and more", OI_TRACKS }, { "Search", OI_SEARCH },
{ "Send files from a phone or PC", OI_PHONE }, { "Settings", OI_SETTINGS }, { "Stop playback", OI_STOP } };
else
items = { { "Search", OI_SEARCH }, { "Open a network link", OI_LINK },
items = { { "Search", OI_SEARCH },
{ "Send files from a phone or PC", OI_PHONE }, { "Settings", OI_SETTINGS },
{ "Rescan media", OI_RESCAN } };
/* the file in front of you: into a playlist */
@@ -4759,13 +4913,14 @@ void setup_begin(bool with_logo);
enum {
ST_DECODING, ST_ALANG, ST_SLANG, ST_SOUND, ST_NIGHT, ST_SPEAKERS, ST_THEME, ST_HAPTICS,
ST_SWIPES, ST_REPEAT, ST_SHUFFLE, ST_DEBUG, ST_STORAGE, ST_VERSION, ST_RELOAD, ST_ABOUT,
ST_WEB, ST_LOOK, ST_OSUB, ST_UILANG, ST_SETUP, ST_BDREGION, ST_COUNT
ST_WEB, ST_LOOK, ST_OSUB, ST_UILANG, ST_SETUP, ST_BDREGION, ST_HWDEC, ST_MATCH, ST_COUNT
};
const char *const st_labels[ST_COUNT] = {
"Decoding", "Audio language", "Subtitle language", "Sound output", "Night mode",
"Speaker test", "Theme", "Controller vibration", "Touchpad swipes", "Repeat the list", "Shuffle",
"Detailed log", "Storage", "Version", "Reload drives", "About VLC", "Phone access", "Look",
"Subtitle downloads", "Language", "Run setup again", "Blu-ray region",
"Subtitle downloads", "Language", "Run setup again", "Blu-ray region", "Hardware decoding",
"Match frame rate",
};
/* One line under the focused setting: what it does. */
const char *const st_help[ST_COUNT] = {
@@ -4791,6 +4946,8 @@ const char *const st_help[ST_COUNT] = {
"The language of VLC's menus",
"Language, look and playback, chosen again",
"A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India",
"The console's video chip. Off: the processor decodes, slower for 4K",
"Films play at their own 24, 25 or 50 Hz: smoother pans. Some TVs go black a moment",
};
/* Categories: an icon, a name, and their settings. */
@@ -4799,15 +4956,17 @@ struct SettingsCat {
int icon;
std::vector<int> rows;
};
enum { SI_PLAY, SI_SOUND, SI_THEME, SI_LIST, SI_GEAR };
enum { SI_PLAY, SI_SOUND, SI_THEME, SI_LIST, SI_GEAR, SI_VIDEO };
const SettingsCat settings_cats[] = {
{ "Playback", SI_PLAY, { ST_DECODING, ST_ALANG, ST_SLANG, ST_OSUB, ST_BDREGION } },
{ "Playback", SI_PLAY, { ST_ALANG, ST_SLANG, ST_OSUB, ST_BDREGION } },
{ "Video", SI_VIDEO, { ST_HWDEC, ST_MATCH, ST_DECODING } },
{ "Sound", SI_SOUND, { ST_SOUND, ST_NIGHT, ST_SPEAKERS } },
{ "Interface", SI_THEME, { ST_UILANG, ST_LOOK, ST_THEME, ST_SWIPES } },
{ "Playlists", SI_LIST, { ST_REPEAT, ST_SHUFFLE } },
{ "System", SI_GEAR, { ST_WEB, ST_STORAGE, ST_RELOAD, ST_SETUP, ST_DEBUG, ST_ABOUT } },
/* (no "Log details" row: the detailed log is for test builds, settings.txt debug=1) */
{ "System", SI_GEAR, { ST_WEB, ST_STORAGE, ST_RELOAD, ST_SETUP, ST_ABOUT } },
};
const int SETTINGS_CATS = 5;
const int SETTINGS_CATS = 6;
/* ---- settings icons: thin outlines, like the tab bar's ---------------------- */
@@ -4916,6 +5075,7 @@ void category_icon(int icon, float cx, float cy, float s, ImU32 col)
case SI_SOUND: icon_speaker(cx, cy, s * 0.9f, col); break;
case SI_THEME: si_palette(cx, cy, s, col); break;
case SI_LIST: icon_list(cx, cy, s * 0.9f, col); break;
case SI_VIDEO: icon_film(cx, cy, s * 0.9f, col); break;
default: icon_gear(cx, cy, s * 0.8f, col); break;
}
}
@@ -4923,7 +5083,8 @@ void category_icon(int icon, float cx, float cy, float s, ImU32 col)
void setting_icon(int id, float cx, float cy, float s, ImU32 col)
{
switch (id) {
case ST_DECODING: si_chip(cx, cy, s, col); break;
case ST_DECODING: case ST_HWDEC: si_chip(cx, cy, s, col); break;
case ST_MATCH: icon_speed(cx, cy, s * 0.8f, col); break;
case ST_ALANG: case ST_UILANG: si_globe(cx, cy, s, col); break;
case ST_SLANG: case ST_OSUB: icon_cc(cx, cy, s * 0.9f, col); break;
case ST_BDREGION: si_globe(cx, cy, s, col); break;
@@ -4970,6 +5131,8 @@ std::string st_value(int id)
static const char *const dec[] = { "Auto (fast when needed)", "Always fast", "Full quality" };
switch (id) {
case ST_DECODING: return dec[player_decode_mode()];
case ST_HWDEC: return player_hw_decoding() ? "On" : "Off";
case ST_MATCH: return player_match_rate() ? "On" : "Off";
case ST_ALANG: return lang_name(player_audio_language(), false);
case ST_SLANG: return lang_name(player_sub_language(), true);
case ST_SOUND: return player_audio_output() ? "Surround 5.1 / 7.1" : "Stereo";
@@ -5009,6 +5172,12 @@ void st_change(int id, int step)
case ST_DECODING:
player_set_decode_mode((DecodeMode)((player_decode_mode() + 3 + dir) % 3));
break;
case ST_MATCH: player_set_match_rate(!player_match_rate()); break;
case ST_HWDEC:
player_set_hw_decoding(!player_hw_decoding());
if (player_active())
toast("Hardware decoding: from the next video", 2.5);
break;
case ST_ALANG: cycle_language(false, dir); break;
case ST_SLANG: cycle_language(true, dir); break;
case ST_BDREGION: {
@@ -5282,7 +5451,7 @@ void modal_speakers()
if (hit(PAD_CIRCLE)) {
player_speaker_test(-1);
modal = SETTINGS;
settings_cat = 1;
settings_cat = 2; /* Sound */
settings_inside = true;
modal_focus = 2;
return;
@@ -6115,7 +6284,12 @@ void compute_video_rect()
vid_rect[3] = sh;
return;
}
float aspect = v.aspect > 0 ? v.aspect : 16.0f / 9;
/* until the video's info is read (a frame or two after its first
* picture), the picture's own shape: 16:9 there stretched a portrait
* video over the whole screen for its first frames (it looked like
* another video flashing by) */
float pic_aspect = video_picture_aspect();
float aspect = v.aspect > 0 ? v.aspect : pic_aspect > 0 ? pic_aspect : 16.0f / 9;
if (aspect_mode == PIC_16_9)
aspect = 16.0f / 9;
else if (aspect_mode == PIC_4_3)
@@ -7117,6 +7291,10 @@ void player_screen()
meta += " \xC2\xB7 " + v.codec;
if (v.ten_bit)
meta += " \xC2\xB7 10-bit";
if (v.hdr)
meta += v.hdr == 2 ? " \xC2\xB7 HLG" : " \xC2\xB7 HDR10";
if (v.hardware)
meta += " \xC2\xB7 HW";
}
if (!v.audio_codec.empty()) {
meta += (meta.empty() ? "" : " \xC2\xB7 ") + v.audio_codec;
@@ -7872,7 +8050,8 @@ void ui_frame(const PadState &pad, float frame_dt)
mini_player();
if (modal == NONE) {
bool open_kind = tab == BROWSE && browse_focus < (int)browse_entries.size() &&
(browse_entries[browse_focus].dir || browse_entries[browse_focus].net == NET_ADD);
(browse_entries[browse_focus].dir || browse_entries[browse_focus].net == NET_ADD ||
browse_entries[browse_focus].net == NET_LINK);
std::vector<std::pair<uint32_t, const char *>> h = { { PAD_CROSS, open_kind ? "Open" : "Play" } };
int fi = focused_item();
if (fi >= 0 && L()[fi].other) {
+6
View File
@@ -462,6 +462,12 @@ void web_start()
a.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listen_fd, (sockaddr *)&a, sizeof(a)) == 0)
break;
if (errno == EACCES) {
/* the sandbox: no port will do */
fprintf(stderr, "web: not allowed to listen (sandboxed: the page needs full access)\n");
p = LAST_PORT + 1;
break;
}
fprintf(stderr, "web: port %d taken (errno %d)\n", p, errno);
}
if (p > LAST_PORT || listen(listen_fd, 8) != 0) {