Modérateurs: Modération Forum Home-Cinéma, Le Bureau de l’Association HCFR • Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 88 invités

Tout ce qui concerne les logiciels lié au HC sur ordinateur (PC, Mac, Linux...)
Règles du forum
Avant de poster, merci de prendre connaissance des règles du forum : à lire avant de poster

PCHC avec Avisynth+ & pixel shaders

Message » 03 Avr 2022 17:18

Bonjour.

Après le petit teaser ds le post dédié à madVR (en réponse à un post de Polopretress concernant Avisynth 64), voici donc mon nouveau "work in progress" côté PCHC.

Le contexte :

J'utilise depuis 12 ans un PCHC basé sur un i7 930 oc à 3.33 GHz qui tourne sous Windows XP. La CG est une radeon 4770. La CS est une Lynx2B (6 voies analogiques) sur slot ISA.

Du côté des petits tracas hardware : 1 alim et 2 CG (modèles 4650 puis 4770) HS en 12 ans. J'ai réussi à remplacer la 4770 HS par une autre 4770 d'occaz qui fonctionne tjrs.

Côté HC : salle dédiée de 60 m2 - Audio en 5.1 sur des moniteurs actifs - base écran de 5m40 au format 2.35:1 - Projo laser professionnel (5800 lumens) : tri-matrices LCOS 1920 × 1200 (compatible HDR10) avec CR on:off natif max de 4000:1 (si iris fixe fermé au max).

Côté soft sous XP x86 : Lecture des BRD HD via MPC-HC + ffdshow + Avisynth + pixel shaders DX9 + EVR CP.
Les algos de post-traitements sont des scripts Avisynth et pixel shaders que j'ai écris.
Audio en Kernel streaming via Reclock (bit perfect).
Tout ça est le produit d'une autre époque ;)

Bilan : bcp de bonheur ces 8 dernières années et des centaines de films visionnés sans que je ne touche à quoi que ce soit. Le côté vétuste du PC n'est pas un pb car machine dédiée qui n'évolue plus.

J'ai décidé de me construire un nouveau PCHC pour 2 raisons :

(1) futur passage de l'audio en 7.1 et mise en place de voix de graves dédiées pour chaque enceinte. J'ai donc besoin de pouvoir gérer (au maxi) un total de 14+1 voies avec filtrage numérique fait par le PC. Ca m'oblige à changer de CS et par ricochet de PC. Cet aspect des choses sera présenté plus tard qd je l'aurais terminé (CS commandée).

(2) être compatible UHD+HDR et pouvoir faire du tone mapping si besoin.

Concernant l'UHD, je dois vivre sans vu que mon diffuseur n'est que fullHD (mais néanmoins compatible HDR10). Je n'ai que qq galettes UHD et qq fichiers UHD sur DD. Bien qu'étant "seulement" en fullHD, la qualité de post-traitement que j'obtiens avec les BRD donne un excellent piqué sur ma grande base. Il est probable que je doive me contenter d'un diffuseur fullHD pendant encore très très longtemps car les gammes pro laser en UHD sont pour l'instant à des prix stratosphériques. Par ailleurs le gain que j'obtiendrai par rapport à ce que j'ai actuellement en post-traitant les BRD HD et UHD sur un diffuseur fullHD ne sera pas proportionnel aux milliers d'€ d'écart qu'il faudrait que je débourse ... Autrement dit, le jeu n'en vaut pas la chandelle en gamme pro.

Il y aurait bcp à dire sur la qualité des encodages vidéo en UHD. J'avais montré il y a pas mal d'années avec des analyses fréquentielles par FFT2D que le vrai potentiel de la 4K (qui est absolument énorme) est complètement sous-exploité dans le contexte cinéma :

https://www.homecinema-fr.com/forum/videoprojecteurs-full-hd/analyse-frequentielle-des-images-t30045822.html


La situation n'a guère évoluée. Par rapport aux bons BRD HD, les bons BRD UHD apportent un contenu fréquentiel supplémentaire essentiellement restreint à la plage 1.5K - 2.5K. C'est peu mais cependant suffisant pour qu'on ressente visuellement un gain (sans post-traitements) car l'oeil est sensible aux fréquences autour du 2K. Les mauvais BRD UHD ne sont que du gonflage de 2K par upsampling avec du sharpen et il n'y a pas d'info supplémentaire au delà de 2K (c'est un peu comme à l'époque de l'argentique où on gonflait les petits films 16mm en 35mm ...). Peut être que la raison de cette sous-exploitation de capacité du format UHD est avant tout un pb de coût de prod. Les bits exédentaires coûtent chers... Je soupçonne aussi une certaine "culture de l'image" propre au cinéma qui a peu cherché à produire des images ultra piquées au cours de son histoire pour des tas de raisons induites par la technique ou les directeurs artistiques (flou de bougé très présent, profondeur de champ souvent hyper réduite etc.).

Reste le HDR qui reste timide au cinéma et qui peut avoir un intérêt quand c'est bien fait et correctement adapté à une projection sur un grand écran. Il est de ce fait intéressant de s'intéresser à la question de la diffusion de ce type de source pour se faire ensuite son opinion sur la différence entre un BRD 2K SDR correctement post-traité, un BRD UHD en SDR (tone mapping) et un BRD UHD en HDR.

Les contraintes à respecter :

- concerver la fluidité parfaite de mon rendu actuel (merci Powerstrip sous XP pour les custom timings et merci à mes différents projos qui ont tous avalés sans broncher et de manière fluide le 23.976p, le 24p et le 25p),

- Porter en x64 ma chaîne de post-traitements actuelle pour les sources HD et post-traiter les sources UHD HDR,

- trouver un substitut à madVR car ce dernier ne me permet pas d'exploiter mes propres pixels shaders. Par ailleurs, la qualité de son tone mapping est (à mes yeux) questionnable car complexe a ajuster au niveau de l'équililibre entre les tons sombres, les tons moyens, les tons clairs et les hautes lumières. Ayant fait des milliers de photos numériques dans ma vie au format raw et les ayant toutes développées, j'ai de l'expérience en mapping de luminance car la première chose qu'on fait quand on développe une photo RAW, c'est définir le mapping entre la dynamique de l'APN et celle bcp plus réduite de l'écran SDR. On fait donc un mapping pour définir la réponse tonale. Les softs de développement (Lightroom etc.) fournissent des aides (basées sur des algos non-linéaires) qui permettent de régler facilement l'équilibre entre les tons sombres, les tons moyens, les tons clairs et les highlights. Chaque photo aura son réglage propre. Et selon l'agilité du développeur, la dynamique SDR restreinte obtenue sera capable ou pas de donner l'illusion de la dynamique shootée. De ce fait, un bon étalonneur en post-prod cinéma arrivera à donner l'illusion en SDR de fortes dynamiques en dilatant + ou - ou en compressant + ou - certaines plages tonales, notamment en utilisant le fait que l'oeil travaille en relatif. Par contre, ça demande du savoir faire. Arriver à faire la même chose avec un algo peut conduire à un résultat médiocre qui pourra choquer par rapport au contexte associée à la scène shootée, surtout si on cherche un effet "whaou" ...

- avoir des chaînes de traitement x86 et x64 complètement opérationnelles et équivalentes. Perso j'utilise encore Reclock en x86 pour corriger le pal speedup de certains petits films art & essai qui ne sortent hélas qu'en DVD (il suffit pour ça de diffuser en 24p/48 kHz et de faire rééchantillonner à la volée l'audio à 46080 Hz par reclock pour obtenir à la fois la correction de tonalité et de vitesse). Il faut "s'accrocher" aujourd'hui pour regarder des DVD mais je le fais encore en réduisant fortement la taille de l'image projetée ... Donc je dédierai la chaine x86 aux quelques DVD que je regarde avec Reclock et tout le reste sera rendu en x64.

Le noeud du pb : arriver à établir un graph DirectShow capable de mettre en oeuvre des scripts de post-traitements CPU pour les sources HD et UHD en x64.
Dernière édition par Emmanuel Piat le 04 Avr 2022 11:59, édité 3 fois.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:20

Quelques mots sur le choix du matos :

Le CPU étant la pierre angulaire des traitements, ça permet d'économiser sur le prix du GPU. Si on a un bon GPU, ça laisse aussi de la place aux approches hybrides CPU/GPU qui sont intéressantes. En 12 ans, il y a eu un gain perf/prix significatif pour les CPU et globalement une baisse du prix par coeur physique/logique.

La 12e géné d'intel est vraiment hyper performante et le i5-12600K me tentait bcp mais le combo CM+CPU reste cher chez intel et j'ai décidé d'essayer la gamme en dessous en 6C/12T qui a bcp baissé en prix. Il fallait donc que je choisisse entre le i5-12400 et le Ryzen 5600X. J'ai pris le Ryzen qui a un gros potentiel d'oc avec des CM moins chères que pour les CPU intel. C'était aussi l'occasion de changer de crêmerie vu que j'ai tjrs eu des CPU intel.

Pour le GPU, vu les prix délirants du moment, j'ai acheté une Radeon RX 550 d'occaz (90 €).

RAM : 2x8 Go en DDR4 3200 16-20-20-38 avec un potentiel d'oc. Vu l'écart de prix ridicule, j'ai regretté ensuite de ne pas avoir pris de la DDR4 3600 en 16-18-18-38 ... Je suis un peu rouillé car je n'en pas monté de PC depuis plus de 10 ans ...

SSD : 512 Go (un très classique Samsung 970 EVO Plus)

Ventirad : 120mm avec 4 caléoducs (dimensionné pour 150W de TDP donc suffisant).

Boitier : chassis de CM ouvert acheté en chine (21€) que j'ai adapté (ajout de pieds et d'équerres pour fixer en dessous de la plaque support le lecteur BRD et 2 racks de DD amovibles).

1er test du 5600X sous w10 en activant juste le profil XMP ds le bios pour la DDR : je suis hyper déçu. C'est vraiment mou du genoux ... On sent que Windows est devenu pachydermique avec le temps, même quand on l'optimise (j'ai globalement suivi les settings de CAPET sous YT).

Retour dans le bios où je passe directement le CPU à 4.7 Ghz et ou j'active la gestion de la tension CPU ds un mode auto baptisé "overcloking AMD". La manip prend 2 sec. Je laisse tout le reste en auto (donc DDR à 3200).

On change littéralement de monde. Ca devient sympa avec l'impression de piloter une petite sportive bien nerveuse. Après pas mal de torture tests du CPU et de la mémoire, je décide de rester sur une freq "raisonnable" de 4.725 Ghz avec la DDR oc à 3466 Mhz en 16-18-18-38 et une tension CPU un peu augmentée. J'ai diminué la latence de W10 ou jouant sur la gestion des timers (0.5 ms) avec l'appli ISLC de Wagnardsoft. W10 est hyper réactif. Le CPU consomme un peu plus de 100W avec les 12T à 100%. En usage léger de tous les jours, on est en moyenne à 25W. C'est pas mal pour un 6C/12T cadencé à cette fréquence qui s'affiche autour de 200€ en ce moment.

Pour info, le CPU atteint sans pb 4.8 Ghz et passe avec succès le bench de CB r15 (score de 2070 à comparer aux autres 6C/12T) mais j'ai des erreurs lors des 10 passes de CB r23. Essayer de le stabiliser à cette fréq. demanderait une approche d'oc bien plus rigoureuse sans garantie d'y arriver.
Dernière édition par Emmanuel Piat le 03 Avr 2022 23:58, édité 1 fois.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:23

Chaine de décodage/post-traitements vidéo x86/x64 :

On arrive au coeur du pb ;)

Pour mettre en oeuvre la chaine de décodage vidéo, je dois remplacer l'ancien combo ffdshow/Avisynth 2.6.0 MT (version SEt) par autre chose qui reste compatible avec Avisynth. Ca ne peut être que le nouvel environnement Avisynth+ qui peut fonctionner nativement en x86 et en x64 et est compatible avec tous les nouveaux formats vidéo (y compris metadata).

Il faut donc trouver le moyen d'intégrer Avisynth+ dans un graph DirectShow. Après qq recherches, je finis par découvrir que c'est possible avec le filtre Avisynth Filter (AVSF) dont le développement par CrendKing a démarré début 2020 :
https://forum.doom9.org/showthread.php?t=180424

Pour récupérer les binaries, il suffit de cliquer sur "Releases" à droite ici :
https://github.com/CrendKing/avisynth_filter

Sauf que si on prend la mauvaise version, ça merde car par exemple le chroma du tone mapping part en sucette du fait que le placement des bits de chroma du signal TV YCrCr est mal interprété entre les différents protagonistes de la chaine DirectShow ...

Ds la situation actuelle il faut donc absolument prendre la version 1.3.1 qui va transformer en 16 bits les sources UHD 10 bits en faisant un bourrage de 6 zéros ds les bits de poids faibles, ce qui revient à multiplier chaque valeurs 10 bits par 2^6 = 64. Dans cette nouvelle échelle sur 16 bits (0 -> 65535), le noir se trouve à 4096 et le blanc à 60160.

En sortie du filtre on se retrouve alors avec un conteneur P16 pour les sources UHD et après, oh miracle, tout se passe bien au niveau des éléments avals, car le P16 est correctement traité.

Mise a jour du 24 Janvier (voir page 11)

La démarche est la même mais avec les nouvelles versions des scripts qui ont un peu évolué pour tenir compte de l'utilisation du P010 en lieu et place du forçage en P016 qui était imposé auparavant pour des raisons de compatibilité de format entre MPC-HC, Avisynth+ et MPC-VR ...


Voici la dernière version de mes scripts pour Avisynth+ :
https://www.mediafire.com/file/ygympzex ... v2.7z/file

Désormais, le post-traitement des BRD UHD se fait en 10 bits natifs. Il n'y a donc plus besoin de se restreindre au combo AVSF v1.3.1 et Avisynth+ 3.7.0 qui travaillaient en P16. Pour rappel, AVSF (AviSynth Filter) est à mettre ds les Filtres Externes de MPC-HC. Dans ses propriétés, il faut bien vérifier qu'à minima tous les Input Formats 4:2:0 sont cochés et notamment YV12 et P010 pour les BRD FHD et UHD. Le fait de travailler en P010 rend avisynth+ vraiment bcp moins consommateur de ressources CPU.

Les dernières versions d'Avisynth+, de AVSF et de MPC Video Renderer sont à récupérer ici :

https://github.com/AviSynth/AviSynthPlus/releases
https://github.com/CrendKing/avisynth_filter/releases
https://github.com/Aleksoid1978/VideoRenderer/releases

A part ça, la procédure d'installation reste identique à celle en page 1.

Dans HTPC.avs qui est lancé par AVSF, on peut maintenant :

- activer ou pas le boost du DTM via le boolean boostTM,
- fixer la valeurs de ce boost via TMgain (Si >1 on aura une expansion de dyn, si <1, une compression),
- activer ou pas un boost de la saturation,
- fixer la valeur de ce boost via TMsat (1.0 correspond à une absence de changt).

Attention, le boost de la sat s'applique aux sources FHD et UHD.

Le paramètre mire est désormais un nombre. Il vaut 0 si on ne veut pas afficher de mire et 1,2,3 etc. pour afficher différentes mires dont le chemin peut être prédéfini ds Mire2K.avsi et Mire4K.avsi. Les mires s'affichent désormais au centre de l'image et dans les 4 coins.

Par rapport à la version précédente, le downscaling UHD->FHD a gagné en précision. Je rappelle que j'ai uniquement un projo FHD et que mes scripts sont adaptés à cette situation.

Trucs inachevés : le post-traitement des DVD se contente du minimum syndical et reste à terminer ... Les sources 720p sont traitées comme du FHD (pas de post-traitement spécifique) pour l'instant.


Téléchargez la v1.3.1 puis Dézippez le fichier SynthFilters.zip dans un dossier de votre choix puis enregistrez les filtres en mode admin avec install.cmd ou avec le fichier register.bat suivant que je préfère :

Code: Tout sélectionner
@cd /d "%~dp0"
@regsvr32.exe avisynth_filter_32.ax /u /s
@REM regsvr32.exe vapoursynth_filter_32.ax /u /s
@if not errorlevel 0 goto error
@if not exist "%SystemRoot%\SysWOW64\cmd.exe" goto success
@regsvr32.exe avisynth_filter_64.ax /u /s
@REM @regsvr32.exe vapoursynth_filter_64.ax /u /s
:success
@echo.
@echo    Uninstallation succeeded.
@goto done
:error
@echo.
@echo    Uninstallation failed.
@echo    You need to right click "unregister.bat" and choose "run as admin".
:done
@pause


Au passage install.cmd essaye aussi d'enregistrer un filtre pour lire les scripts de VapourSynth (autre environnement de traitements vidéos basé sur python), ce qui ne fonctionnera pas si vous n'avez pas installé cet environnement ...

Pour désenregistrer les filtres, vous pouvez utiliser le fichier unregister.bat :

Code: Tout sélectionner
@cd /d "%~dp0"
@regsvr32.exe avisynth_filter_32.ax /u /s
@REM regsvr32.exe vapoursynth_filter_32.ax /u /s
@if not errorlevel 0 goto error
@if not exist "%SystemRoot%\SysWOW64\cmd.exe" goto success
@regsvr32.exe avisynth_filter_64.ax /u /s
@REM @regsvr32.exe vapoursynth_filter_64.ax /u /s
:success
@echo.
@echo    Uninstallation succeeded.
@goto done
:error
@echo.
@echo    Uninstallation failed.
@echo    You need to right click "unregister.bat" and choose "run as admin".
:done
@pause


Ensuite, avant d'installer Avisynth+, assurez-vous que vous avez bien désinstallé toute version précédente de Avisynth avec un bon nettoyage de toutes les ref. ds la base de registre (via Revo uninstaller ou le freeware BCUninstaller qui est très puissant).

Sauf que ;) à cause de ce problème référencé avec MPC-HC/BE :
https://github.com/CrendKing/avisynth_filter/issues/66

on ne peut pas prendre n'importe quelle version d'Avisynth+. Dans l'état actuel des choses, on est obligé de prendre une version située entre la v3.5.1 et la v3.7.0 sans quoi la lecture bloque à la frame 0 :
https://github.com/AviSynth/AviSynthPlu ... ses?page=1

L'installation se fait facilement avec l'installateur dédié (exécutable) qu'on obtient en cliquant sur "Assets" une fois qu'on a choisi une version. Pdt l'install, cochez l'option qui permet d'associer les scripts .avsi et .avs au notepad. Après installation, vous aurez 4 dossiers de plugins dans le dossier C:\Program Files (x86)\AviSynth+ :

Un pour les anciennes versions x86 <= 2.6.0 :
(1) C:\Program Files (x86)\AviSynth+\plugins

Un pour avisynth+ x86 :
(2) C:\Program Files (x86)\AviSynth+\plugins+

Un pour les anciennes versions x64 <= 2.6.0 :
(3) C:\Program Files (x86)\AviSynth+\plugins64

Un pour avisynth+ x64 :
(4) C:\Program Files (x86)\AviSynth+\plugins64+

C'est dans (2) et (4) qu'il va falloir installer les fonctions .avsi et les dll Avisynth+ pour chaque chaine de décodage x86 et x64 respectivement. Dans mon install, les fonctions .avsi que j'utilise sont les mêmes ds (2) et (4), c'est donc juste une duplication. Les dll x86 et x64 par contre sont spécifiques et elles doivent respecter le dispaching ds les bons dossiers. Je vous conseille fortement de changer les droits de (2) et (4) pour que vous puissiez y avoir accès en lecture/écriture.
Dernière édition par Emmanuel Piat le 03 Avr 2022 19:04, édité 2 fois.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:23

Player : perso, j'utilise MPC-HC x86 et x64 de clsid2 :
https://github.com/clsid2/mpc-hc/releases

Si le passage MPC-BE vers MPC-HC vous pose un pb, voici quelques arguments :

- tout comme MPC-BE, MPC-HC a maintenant un thème sombre avec un rendu moderne (clic droit/Affichage/thème sombre)

- il y a aussi une option pour voir les vignettes vidéo qd on seek dans la barre de temps (l'option est automatiquement désactivée si on lit une galette physique pour éviter les pb de temps d'accès)

- depuis la v1.9.19, on peut enfin déplacer verticalement ts les ST (même les overlay BRD, ce qui est du bonheur) avec des raccourcis clavier :

- Added hotkeys to move subtitles vertically. Defaults are set to: Ctrl+Shift+Add/Substract

- Même si ça n'apparait pas dans le menu contextuel (contrairement à MPC-BE), via un raccourci clavier, on peut browser vers un fichier pour aller lire un ST externe (pratique qd on veut redimensionner le texte d'un ST d'une galette ou éviter des ST de BRD qui ont des couleurs affreuses). On peut aussi mettre classiquement des ST externes avec le même nom que le fichier vidéo.

- contrairement à MPC-BE, la compilation des shaders est automatique sous MPC-HC dès qu'on modifie le code. C'est vraiment hyper pratique qd on modifie les param des shaders : on voit tout de suite le résultat sur l'image alors qu'il faut redémarrer MPC-BE pour voir le résultat.

- contrairement à MPC-BE, MPC-HC permet une gestion des enchainements de shaders (ces enchainements sont appelés "Effets") sous la forme de bibliothèques qu'on peut nommer puis sélectionner. Ceci permet de gérer plein de configuration différentes de shaders afin de les comparer entre elles.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:28

On passe maintenant au video Renderer qui va, entre autre, gérer le tone mapping.

J'utilise MPC Video Renderer en Direct3D 11 (0.5.6.1807) :
https://github.com/Aleksoid1978/VideoRenderer/releases

Les Nightly builds sont là :
https://github.com/Aleksoid1978/VideoRenderer

Nota : pour ceux qui ne le savent pas, le rendu de MPC VR D3D11 a une meilleure acutance que MPC VR D3D9 et EVR CP (les 2 derniers sont strictement équivalents car basés sur la même chaine D3D de rendering). C'est vérifiable sur mire. Donc il faut s'assurer que D3D11 est activé ds les settings de MPC VR.

MPC Video Renderer me permet d'utiliser mes propres pixel shaders (alors qu'ils sont inactifs sous madVR). Son algo de tone mapping fonctionne bien sans avoir rien à régler (à condition de choisir la bonne version de AVSF). Autrement dit, son tone mapping fournit une image dont la tonalité est dans "l'esprit du SDR" tel qu'on le trouve sur les BRD HD 2K. Néanmoins, si vous trouvez que ça ne "pête pas assez", on peut facilement corriger le rendu du mapping avec Avisynth+ via la fonction Levels(). Ce point est intégré dans mes scripts (voir plus loin).
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:29

Config de AVSF ds MPC-HC :

On intègre classiquement AVSF dans les filtres externes de MPC-HC. Dans le panneau de config du filtre, il suffit d'indiquer le chemin vers le script .avs qui fera les traitements Avisynth+. Je conseille de mettre ce script dans un dossier à part car il sera appelé à la fois par MPC-HC+AVSF x86 et par MPC-HC+AVSF x64. Il n'est pas possible d'avoir des settings différents pour AVSF x86 et x64...

Si vous êtes par exemple dans une chaine de lecture x64, MPC-HC+AVSF x64 va lire automatiquement le script .avs indiqué par AVSF et les dll et les fonctions .avsi de Avisynth+ appelées par ce script sont celles situées dans (4).

Alors que si vous êtes dans une une chaine de lecture x86, MPC-HC+AVSF x86 va lire automatiquement le script .avs indiqué par AVSF et les dll et les fonctions .avsi de Avisynth+ appelées par ce script sont celles situées dans (2).

Au final, le tout est très logique et très simple.

Il ne reste plus qu'à écrire le script .avs et les fonctions .avsi qu'il utilise, le tout en mode MT. Pour la gestion du MT, les choses sont un peu différentes de Avisynth 2.6.0 MT (version SEt). Sans rentrer dans les détails, chaque fonction de Avisynth+ utilisée dans un script peut avoir un mode de gestion MT différent, et il faut préciser tout ça au départ dans le script .avs. La doc est ici :
http://avisynth.nl/index.php/AviSynth%2 ... T.29_Notes

Avant de rentrer dans la description des scripts/fonctions Avisynth+, il reste à installer les anciennes dll Avisynth de ffdshow x86 et x64 car j'utilise un filtre de ffdshow dans le post-traitement des BRD HD.

Pour ça il faut installer par exemple les versions clsid de ffdshow x86 et x64 :
https://sourceforge.net/projects/ffdsho ... %20builds/
https://sourceforge.net/projects/ffdsho ... %20builds/
en cochant les options qui se rapportent à Avisynth pdt l'installation.

Après installation, il y aura dans les dossiers (1) et (3) 2 fichiers :
ffavisynth.avsi
ffavisynth.dll

Il faut recopier ces fichiers dans (2) et (4) :
(1) -> (2)
(3) -> (4)

ffavisynth.avsi est un "autoload script" que Avisynth+ va automatiquement charger pour intégrer la dll correspondante. On peut donc utiliser toutes les fcts présentes ds ffavisynth.dll dans le script .avs ou ds une fonction .avsi. Nota : il n'y a pas besoin d'intégrer les filtres de ffdshow dans les filtres externes de MPC-HC puisque le script Avisynth+ fait directement appel à la ddl.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:30

Vous avez maintenant un nouvel espace de liberté que vous pouvez utiliser à votre guise pour scripter vos propres post-traitements Avisynth+ et vos pixels shaders DX11. Concernant Avisynth+, la doc complète est là : ;)
http://avisynth.nl/index.php/Main_Page

La suite de ce post n'est donc qu'une simple suggestion de traitements possibles. Le post-traitement que je fournis est très "old-school" puisque je l'utilise depuis presque une décénie. Il fonctionne bien et convient à mes exigences en exploitant à fond une matrice fullHD. Il a été testé et optimisé avec des diffuseurs SDR ayant un gamut REC709. Tout le monde peut donc le tester en condition fullHD pour voir ce que ça donne. L'évaluer dans un autre contexte est un non-sens COMPLET. J'indiquerai sur quels paramêtres il faut jouer pour adapter le rendu à un autre diffuseur fullHD. Ca se ramène essentiellement à deux paramètres.

Ce qui est bien avec AVSF, c'est que ça ouvre de nouvelles perspectives intéressantes à explorer comme par exemple le upsampling x2 par IA (qui peut utiliser le GPU), lequel permet de lever le compromis entre AA et acutance dont je parle plus loin :
https://github.com/Alexkral/AviSynthAiUpscale
https://forum.doom9.org/showthread.php?t=181665
https://forum.doom9.org/showthread.php? ... ost1919165

Bref, ça offre tout un univers à explorer, notamment pour ceux qui ont des diffuseurs UHD. Mes scripts sont aussi adaptables à un contexte UHD si on a un gros CPU.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:32

Tous les scripts Avisynth+ sont récupérables ici :
https://www.mediafire.com/file/e05q2wweusrmaqk/Scripts_Avisynth%252B_HTPC_FullHD.7z/file


Voici le script HTPC.avs que j'utilise avec AVSF :

Code: Tout sélectionner
####################################################
# Avisynth Filter Script for x86/x64 HTPC decoding #
####################################################
# Avisynth Filter is made by CrendKing:            #
# https://github.com/CrendKing/avisynth_filter     #
####################################################

# x86 & x64 ffavisynth.dll and ffavisynth.avsi autoload script must be present
# in plugins+ & plugins64+ directories of aviSynth+ in order to use ffdshowSWScaler()

# MT Configuration
SetFilterMTMode("AvsFilterSource",3)
SetFilterMTMode("MT_MULTI_INSTANCE",3) # second parameter can be 2 or 3

# Source of aviSynth Filter
AvsFilterSource()

# Show info on input frames
#Info()

HTPCVideoProcessing(boostAcutance = 65,     /* to boost acutance (BRD HD only): 125 | 65 | 25 | 0     */
 \                  boostTM = true,         /* to boost tone mapping (BRD UHD only)                   */
 \                  cropPreset = 0,         /* -1 (manual) | 0 (no crop) | 1 (1.85:1) | 2 (2.35:1)    */
 \                  cropOffset = 0,         /* additive offset for fine adjustment of cropping limits */
 \                  cropBorderHeight = 0,   /* for manual adjustment of cropping limits               */
 \                  cropShowLine = false,   /* to visualize top and bottom cropping limits            */
 \                  mire = false,           /* to display a geometric pattern                         */
 \                  OSD = false             /* to display information about current post-processing   */
 \)

# Preset adjustment to Show Y' Histogram:
# for mkv or cropped video set preset = -1 and borderHeight = 15 else for Blu-ray HD or UHD:
# 1.77:1 ratio => set preset = 0
# 1.85:1 ratio => set preset = 1
# 2.35:1 ratio => set preset = 2
# and adjust with positive or negative offset.
# showline = true to visualize with red lines the top and bottom limits of the area taken
#            into account to compute the histogram (should be a little inside the picture)
# UHD = true if UHD frame, else false

#HistogramY(preset=2, offset=15, borderHeight=15, UHD=false, showline=true)

# Show info on output frames
#Info()

Prefetch(13) # if not 6C/12T, remplace 13 by the number of threads available + 1.


La valeur de Prefech() à la fin du script doit être adaptée à votre CPU (c'est le nombre total de threads +1)

Tout se fait ds la fonction HTPCVideoProcessing() qui a 8 paramètres :

- boostAcutance : pour booster l'accutance que bcp d'algo de sharpen réduisent ds les hautes fréquences spatiales. La fonction utilisée pour ça est swscaler de ffdshow. C'est utilisé que pour les BRD HD standards et pas pour les BRD UHD. Pour un moniteur, 0 peut suffire. Ce choix produira l'image la + soft. Pour un projo, on peut monter jusqu'à 125. Aller au-delà n'a aucun intérêt.

- boostTM : pour booster le tone mapping des BRD UHD.

- cropPreset, cropOffset, cropBorderHeight, cropShowLine : pour gérer le cropping des bandes noires ou de l'image

Avec cropShowLine on peut prévisualiser ou le cropping va se faire en activant l'affichage de 2 lignes rouges hozizontales. Pour que le cropping se fasse réellement, il faut mettre showline à false. Pour faciliter le positionnement des lignes rouges, on peut utiliser le paramètre cropPreset (0,1 ou 2) qui correspond à des formats d'image standards (0 -> pas de cropping, 1-> 1.85:1, 2 -> 2.35:1). Pour affiner un peu les choses on peut ajouter un offset positif ou négatif avec cropOffset, et enfin si on met preset =-1, on peut régler soi-même la position de la ligne rouge avec cropBorderHeight. Dans ce cas, offset n'est pas pris en compte. Pour un mkv sans bande noire, il faut choisir preset = 0 pour désactiver le cropping. Nota : offset et cropBorderHeight sont à définir pour une frame au format fullHD. Si la frame est UHD, un facteur d'échelle x2 sera automatiquement appliqué.

Faire du cropping permet de diminuer la charge CPU ;)

- mire : pour afficher une petite mire en overlay sur l'image. Deux mires qu'il faut impérativement mettre ds "C:\Program Files (x86)\AviSynth+\plugins64+" sont utilisées : une pour les BRD HD, l'autre pour les BRD UHD.

Vous pouvez récupérer ces 2 mires ici :
https://www.mediafire.com/file/qm5ge9dqxajvoek/Mires.7z/file


- OSD : pour afficher pdt 4 sec un OSD avec qq infos dans le coin en haut à droite de l'image. Nota : chaque fois qu'on seek dans la barre du temps, l'OSD se réaffichera ...

La chaîne de post-traitements a été volontairement réglée pour respecter certaines structures hautes fréquences de l'image, notamment les mires 1-2-3-... pixels. Le respect de ce point (qui est corrélé au piqué de l'image) me permet d'exploiter au maximum les possiblités d'une matrice fulHD. Néanmoins, c'est un challenge qui n'est pas simple à réussir lorsqu'on utilise des algos d'upsampling/downsampling pour faire du "supersampling" et processer l'image à une résolution différente de la réso native de la source ...

Pour les BRD, la mire 2K permet notamment de voir l'effet de boostAcutance sur la fréquence maximale (traits horizontaux, verticaux et damier de 1 pixel de large) grâce à des motifs ayant 2 pixels de périodicité : 0 1 0 1 0 1 etc. Dans ce cas, plus le blanc est grisé, plus on réduit l'acutance à la fréquence maxi que le diffuseur peut afficher.

Le non respect des mires "1 pixel ON-1 pixel OFF" signifie qu'il y a un effet d'anti-aliasing (AA) qui est ajouté par le traitement, ce qui atténue forcément l'amplitude des hautes fréquences présentes dans l'image (ou les détruit carrément). BoostAcutance = 125 permet d'avoir un respect total des mires 2-pixels. Mais co par ailleurs, d'autres mécanismes de renforcement opèrent sur l'image (via des overshoots/undershoots etc.), le crénelage associé à la nature numérique de l'image peut devenir trop visible si on minimise l'AA en renforcant l'acutance de l'image après un sharpening. Il y a donc un compromis à trouver qui dépendra du diffuseur (qui a aussi sa propre acutance ...) et des goûts de l'utilisateur en matière d'image. En absence de renfort de l'acutance (BoostAcutance = 0), on obtient déjà une image à la fois sharpée et "naturelle" sur un moniteur LCD (qui a une bonne acutance). Ma valeur favorite pour les moniteurs fullHD est BoostAcutance = 25. Pour un vidéoproj qui a forcément une acutance plus limitée qu'un moniteur, on pourra augmenter BoostAcutance. Un excellent vidéoprojecteur (monoDLP de bonne facture) pourra peut être se contenter de BoostAcutance = 25. BoostAcutance = 65 conviendra sans doute à la plupart des vidéoproj qui ont une bonne optique.

La mire 4K qui s'affiche pour les BRD UHD possède des patterns tout grisés lorsqu'on utilise un diffuseur fullHD : c'est normal car bcp de hautes fréquences en 4K ne peuvent pas être affichées sur un diffuseur fullHD. Un post-traitement qui respecte au mieux l'acutance de la source devra alors respecter une alternance "2 pixels on/2 pixels off" sur une mire 4K. En fait c'est un peu plus compliqué, parce que si on décale la mire 4K de UN pixel ds l'image 4K, le downsampling peut totalement altérer ou détruire certains patterns "2 pixels on/2 pixels off" ... C'est dû au fait que ce décalage de 1 pixel correspond à une très haute fréquence spatiale (>2K) qui ne peut pas être respectée lors du downsampling. cela induit aussi que les mires avec un nombre impair de pixels (3 on/3 off par exemple) sont très dures à restituer ... Nota : lorsqu'on voit un tramage léger qui apparait sur un pattern grisé, c'est un artefact qui est la conséquence du repliement fréquentiel pendant le downsampling. Il convient normalement de le minimiser. En pratique, c'est en général négligeable si le downsampling est bien choisit.

Après l'appel de HTPCVideoProcessing(), on obtient une image fullHD et on peut afficher en haut à gauche un histogramme temps réel de la luminance avec un petit effet de transparence (pour ça il faut décommenter la fonction HistogramY()). Par exemple, on peut voir le Blacker than black (BTB) et le whiter than white (WTW) qui sont matérialisés sur la droite et la gauche de l'histogramme (normalement ces zones sont vides mais ce n'est pas tjrs le cas ...). On peut aussi voir les BRD avec un noir mal positionné etc. On a parfois des mauvaises surprises que ce soit pour les BRD HD ou les BRD UHD ... Je reviendrai là-dessus plus tard avec un exemple de BRD HD/UHD mal encodé (gros massacre) qu'on corrigera (film Premier contact de D. Villeneuve) pour lui redonner toute sa qualité.

Pour HistogramY(), en mettant showline = true, on matérialise à l'aide de 2 lignes rouges horizontales la zone qui sera prise en compte pour déterminer l'histogramme. En effet, si la frame a des bandes noires qui sont encodées, il est important de ne pas en tenir compte pour calculer l'histogramme car sinon, il sera faussé. Dans tous les cas, il faut tjrs positionner les lignes rouges "un poil à l'intérieur de l'image" pour être ok.

Pour faciliter le positionnement des lignes rouges, là encore on peut utiliser le paramètre preset (0,1 ou 2) qui correspond à des formats d'image standards (1.77, 1.85 ou 2.35). Pour affiner un peu les choses on peut ajouter un offset positif ou négatif, et enfin si on met preset =-1, on peut régler soi-même la position de la ligne rouge avec borderHeight. Dans ce cas, offset n'est pas pris en compte. Pour un mkv qui a déjà été croppé, il faut choisir preset = -1 et borderHeight = 15 pour être certain de se positionner dans l'image. Offset et borderHeight sont à définir pour une frame au format fullHD. Si la frame est UHD, un facteur d'échelle x2 sera automatiquement appliqué si on met le paramètre UHD à true.

Voici la fonction HistogramY() qui est à mettre ds le fichier HistogramY.avsi :

Code: Tout sélectionner
# Display an histogram of Y' inside the frame (overlay on top left corner).

# Top and bottom black borders need to be cropped to have a correct scale on the Y' histogram.
# This cropping can be done by specifying either ratio or bbHeight parameters.

# if defined, preset specifies a predefined value for bbHeight
# preset =-1: no preset and borderHeight is taken into account
# preset = 0: borderHeight set for a 1.77:1 format movie
# preset = 1: borderHeight set for a 1.85:1 format movie
# preset = 2: borderHeight set for a 2.35:1 format movie
 
# borderHeight: if defined, gives the top and bottom black borders height that will be cropped.

# offset: value added to borderHeight to define the number of lines to crop.
#         Usefull if ratio is used with a movie that don't exactly respect the predefined format.

# UHD: set to true if UHD frame, false if FHD frame

# showline: set to true to visualize with red lines the top and bottom limits  of the area used
#           to compute the histogram. The Y' histogram is plotted at the top left of this area.
# The returned frame is the complete original frame (no cropping).

function HistogramY(clip clp, int "preset", int "offset", int "borderHeight", bool "UHD", bool "showline")
{
preset = default( preset, -1)
UHD = default(UHD, false)
ss = UHD==true ? 2:1
offset = default( offset, 0)/2*2
showline = default( showline, false)
borderHeight = default( borderHeight, 0)/2*2

borderHeight = preset==0 ? offset : preset==1 ? offset+22 : preset==2 ? offset+132 : borderHeight
borderHeight = (borderHeight < 0 || borderHeight > clp.height/2) ? 0 : borderHeight

borderHeight > 0 ? Crop(clp,0,borderHeight*ss,0,-borderHeight*ss) : clp
cWidth=last.width
cHeight=last.Height
Histogram("Levels")
histo=Crop(cWidth,0,0,66-cHeight)
Overlay(clp,histo,x=4*ss,y=(borderHeight+5)*ss,mode="blend",opacity=0.55)

(showline && borderHeight > 0) ? Eval("""
Crop(0,borderHeight*ss,0,-borderHeight*ss).AddBorders(0,2*ss,0,2*ss,$800000)
Overlay(clp,last,x=0,y=(borderHeight-2)*ss,mode="blend")
""") : last
return last
}
Dernière édition par Emmanuel Piat le 03 Avr 2022 18:32, édité 3 fois.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:33

Voici la fonction HTPCVideoProcessing() qui est à mettre ds le fichier HTPCVideoProcessing.avsi :

Code: Tout sélectionner
function HTPCVideoProcessing(clip clp,
 \     int "boostAcutance",     /* to boost acutance (BRD HD only): 125 | 65 | 25 | 0     */
 \     bool "boostTM",          /* to boost tone mapping (BRD UHD only)                   */
 \     int "cropPreset",        /* -1 (manual) | 0 (no crop) | 1 (1.85:1) | 2 (2.35:1)    */
 \     int "cropOffset",        /* additive offset for fine adjustment of cropping limits */
 \     int "cropBorderHeight",  /* for manual adjustment of cropping limits               */
 \     bool "cropShowLine",     /* to visualize top and bottom cropping limits            */
 \     bool "mire",             /* to display a geometric pattern                         */
 \     bool "OSD")              /* to display information about current post-processing   */
{
   boostAcutance = default( boostAcutance, 0)
   boostTM = default( boostTM, false)
   cropPreset = default( cropPreset,0)
   cropOffset = default( cropOffset,0)
   cropBorderHeight = default( cropBorderHeight, 200)
   cropShowLine = default( cropShowLine,false)
   mire = default(mire, false)
   OSD = default(OSD, false)

   # SD, HD or UHD source?
   if (clp.height < 720 && clp.IsYV12) {  # SD YV12 8bpp source like DVD
                                          ##############################

   mire ? Mire2K(clp,pattern = "C:\Program Files (x86)\AviSynth+\plugins64+\reso2K.png") : clp
   BlackmanResize(taps=4,clp.height*16/9,clp.height) # frame Desanamorphosis
   boostAcutance > 0 ? ffdshowSWScaler(lsharp=boostAcutance,csharp=0) : last
   convertToRGB32(matrix = "Rec601",interlaced=false,chromaresample = "blackman")
   
   } else if (clp.height <= 1080 && clp.IsYV12) { # HD YV12 8bpp source like BRD
                                                  ##############################

   mire ? Mire2K(clp,pattern = "C:\Program Files (x86)\AviSynth+\plugins64+\reso2K.png") : clp
   cropPreset == 0 ? last :
 \ VerticalCrop(preset=cropPreset,offset=cropOffset,borderHeight=cropBorderHeight,UHD=false,showline=cropShowLine)
 
   NaturalSharpen2K(LSFstr=21.25,usHQstr=0.23)
   boostAcutance > 0 ? ffdshowSWScaler(lsharp=boostAcutance,csharp=0) : last
   
   } else {  # UHD YUV420P10 (or more) source like BRD UHD
             #############################################

   # Remark: avisynth Filter version 1.3.1 converts all P10/12 sources in P16
   # using zero padding. This gives a correct tone mapping under MPC VR

   mire ? Mire4K(clp,pattern = "C:\Program Files (x86)\AviSynth+\plugins64+\reso4K.png") : clp
   cropPreset == 0 ? last :
 \ VerticalCrop(preset=cropPreset,offset=cropOffset,borderHeight=cropBorderHeight,UHD=true,showline=cropShowLine)

   # Image preprocessing to boost the TM (1.114 seems a good gain value and 1.12 a maximal value)
   boostTM ? Levels(4096, 1.0, 60160, 4096, 60160*1.114, false, false) : last
 
   NaturalSharpen4K(LSFstr=18.25,usHQstr=0.18)     
   }
   
   OSD ?
 \ Subtitle(String(clp.height < 720 ? "SD source processing" :
 \          clp.height <= 1080 ? "HD source processing" :
 \                               "UHD source processing")
 \ + "\nOutput frame: " + String(last.width) +"x"+ String(last.height)
 \ + "\nPixel format: " +String(last.pixelType)
 \ + "\nCropping: " + String(cropPreset != 0) 
 \ + "\nBoostAccutance: " + String(clp.width <= 1920 ? boostAcutance : "none")
 \ + "\nBoost tone mapping: " + String(clp.width > 1920 ? boostTM : "none")
 \ , lsp = 0, x = last.width-210, y = 30, last_frame = 96, text_color=color_white) : last

   return last
}


En fonction de la hauteur de la frame, cette fonction opère un traitement différent pour les sources SD, les sources HD et les sources UHD.

DVD :

Encore en work in progress ...
J'ai donc juste mis à titre illustratif la désanamorphose d'un DVD Z2 PAL (720x576 -> 1024x576) ou NTSC puis un boost ou pas de l'acutance (65 à 125 recommandé) puis la conversion YV12 -> RGB en BT601. Dans ce cas, pour regarder le DVD à sa réso "native" (petite image ...) il faut choisir dans MPC/HC :

clic droit/Fenêtre vidéo/100%
clic droit/Fenêtre vidéo/Ratio d'affichage/16:9 à la place de "Par défaut (DAR)" ...

Le dernier setting est dû au fait que le DAR (Display Aspect Ratio) encodé sur les sources DVD PAL anamorphosée est 720/576 = 1,25 et qu'il faut le mettre en 1.77 si on a désanamorphosé par soft ...

BRD HD :

- affichage ou pas de la mire en overlay pour vérifier l'effet du post-traitement sur l'acutance (fonction mire2K()),
- éventuel cropping des bandes noires (pour gagner en temps CPU ou pour modifier le format de l'image qui s'affiche (fonction VerticalCrop()),
- post-traitement avec la fonction NaturalSharpen2K().
- boost ou pas de l'acutance

BRD UHD :

idem sauf que les fonctions utilisées sont mire4K() et NaturalSharpen4K(). Il y a également un boost du (futur) toneMapping en préprocessant l'image avec la fonction Levels() qui va repousser le blanc un peu au delà de 60160 tout en laissant le noir à sa position d'origine qui est 4096.

Nota : en HDR, le risque de perte d'information est nul qd on repousse le point blanc au delà de 235*256 = 60160, tout simplement parce qu'un signal HDR est toujours encodé très en deça du point blanc (c'est facile à contrôler avec l'histogramme). Donc comme on fait cette manip AVANT le TM, on ne risque rien en pratique.

Ce script utilise pour les BRD HD la fonction ffdshowSWScaler() ds ffdshowSWScaler.avsi qui permet d'avoir accès au sharpen swscaler de ffdshow :

Code: Tout sélectionner
# ffdshowSWScaler()
# A function that provides easy access to ffdshow's swscaler sharpener
#
# Requirements: - loading of ffavisynth.dll with LoadCPlugin()
#               - YV12/YUY2/RGB colorspace
# Parameters:   - lsharp (integer): swscaler luma sharpening strength (0-400)
#               - csharp (integer): swscaler chroma sharpening strength (0-400)

function ffdShowSWScaler(clip c, int "lsharp", int "csharp") {
   
    lsharp = Default(lsharp,32)
    csharp = Default(csharp,0)
   
    c.ffdshow(options="xsharpen=1,sharpenMethod=5,mplayerSharpLuma="+String(lsharp)+",mplayerSharpChroma="+String(csharp))   
    return last
}


et aussi 2 fonctions pour afficher les mires en overlay au centre de l'image :

Mire2K.avsi

Code: Tout sélectionner
function Mire2K(clip clp, string "pattern")
{
pattern = default( pattern, "D:\reso.png")
mire=ImageSource(pattern).ConvertToYV12()
Overlay(clp,mire,x=(clp.width-mire.width)/2,y=(clp.height-mire.height)/2,mode="blend")
}


Mire4K.avsi

Code: Tout sélectionner
function Mire4K(clip clp, string "pattern")
{
pattern = default( pattern, "D:\reso.png")
mire=ImageSource(pattern).ConvertToYUV420().ConvertBits(bits=16)
Overlay(clp,mire,x=(clp.width-mire.width)/2,y=(clp.height-mire.height)/2,mode="blend")
}


et une fonction pour cropper l'image si c'est demandé :

VerticalCrop.avsi

Code: Tout sélectionner
# Crop the black borders of a FHD or UHD Blu-ray disc

# if defined, preset specifies a predefined value for the image ratio
# preset =-1: no preset and borderHeight is taken into account
# preset = 0: borderHeight set for a 1.77:1 format movie
# preset = 1: borderHeight set for a 1.85:1 format movie
# preset = 2: borderHeight set for a 2.35:1 format movie
 
# borderHeight: if defined, gives the top and bottom black borders height that will be cropped.

# offset: value added to borderHeight to define the number of lines to crop.
#          Usefull if ratio is used with a movie that don't exactly respect the predefined format.

# UHD: set to true if UHD Blu-ray disk, false if FHD
# showline: set to true to visualize the crop limits with a red line (cropping not achieved in this case)

function VerticalCrop(clip clp, int "preset", int "offset", int "borderHeight", bool "UHD", bool "showline")
{
preset = default(preset, -1)
UHD = default(UHD, false)
ss = UHD==true ? 2:1
offset = default(offset, 0)/2*2
showline = default( showline, false)
borderHeight = default( borderHeight, 0)/2*2

borderHeight = preset==0 ? offset : preset==1 ? offset+22 : preset==2 ? offset+132 : borderHeight
borderHeight = (borderHeight < 0 || borderHeight > clp.height/2) ? 0 : borderHeight

borderHeight > 0 ? Crop(clp,0,borderHeight*ss,0,-borderHeight*ss) : clp
showline ? Eval("""
last.AddBorders(0,2*ss,0,2*ss,$800000)
borderHeight > 0 ? Overlay(clp,last,x=0,y=(borderHeight-2)*ss,mode="blend") : last
""") : last
return last
}
Dernière édition par Emmanuel Piat le 03 Avr 2022 18:09, édité 2 fois.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:35

Voici la fonction NaturalSharpen2K() dans le fichier NaturalSharpen2K.avsi pour traiter les sources HD :

Code: Tout sélectionner
# "Natural" post-treatment for FHD monitor/projector and fullHD source

# ss is the upsampling factor. A correct value to respect 1,2,3 pixels patterns is 1.333
# LSFstr is LSFHC strength setting
# usHQstr is UnsharpHQ strength setting
# usHQth is unsharpHQ threshold setting

# Add "swscaler" sharpen in ffdshow with luminance sharpening set to 0.08 (if monitor display)

function NaturalSharpen2K(clip clp, float "ss", float "LSFstr", float "usHQstr", int "usHQth")
{
ss = default( ss, 1.333)
LSFstr = default( LSFstr, 21.25)
usHQstr = default( usHQstr, 0.23)
usHQth = default( usHQth, 28)

# Gestion Upscaling / sharpening / downscaling
ox = clp.width
oy = clp.height
ss_x = round(ss * ox /8)*8
ss_y = round(ss * oy /8)*8
BlackmanResize(clp,taps=4,ss_x,oy)
BlackmanResize(taps=4,last.width,ss_y)
UnsharpHQ(THRESHOLD=usHQth,SHARPSTR=usHQstr,sMOOTH=0.0,SHOW=false,MODE=0,OPT=2)
LSFMode3_2K(strength=LSFstr)
Sharpen(0,0.1045)
BlackmanResize(taps=4,last.width,oy)
BlackmanResize(taps=4,ox,last.height)
Sharpen(0.25,0) # 0.1,0.225
return last
}


Elle opère un upsampling avec un ratio x(4/3) (->2560x1440). Le resize utilisé est blackman car il permet de respecter la géométrie des mires 1-2-3-... pixels avec ce ratio (la plupart des resize ne le permettent pas ... Blackman est un lanczos avec un ringing minimisé), suivi d'un ensemble d'algos de sharpen, puis d'un downsampling en fullHD puis de nouveau d'un sharpen. Le ringing est réduit par un choix approprié des sharpens et de leur direction d'application.

Voici la fonction NaturalSharpen4K() pour traiter les sources UHD :

NaturalSharpen4K.avsi

Code: Tout sélectionner
# "Natural" post-treatment for FHD monitor/projector and UHD source

# ss is the downsampling factor. A correct value to respect 1,2,3 pixels patterns is 1.333
# LSFstr is LSFHC strength setting
# usHQstr is UnsharpHQ strength setting
# usHQth is unsharpHQ threshold setting

# Add "swscaler" sharpen in ffdshow with luminance sharpening set to 0.08 (if monitor display)

function NaturalSharpen4K(clip clp, float "ss", float "LSFstr", float "usHQstr", int "usHQth", bool "natural")
{
ss = default( ss, 1.333)
LSFstr = default( LSFstr, 18.25)
usHQstr = default( usHQstr, 0.18)
usHQth = default( usHQth, 28)
# Gestion downscaling / sharpening / downscaling
ox = clp.width/2   # réso x finale
oy = clp.height/2  # réso y finale
ss_x = round(clp.width/ss/8)*8
ss_y = round(clp.height/ss)
BlackmanResize(clp,taps=4,ss_x,clp.height)
BlackmanResize(taps=4,last.width,ss_y)
UnsharpHQ(THRESHOLD=usHQth,SHARPSTR=usHQstr,sMOOTH=0.0,SHOW=false,MODE=0,OPT=2)
LSFMode3_4K(strength=LSFstr)
Sharpen(0,0.1045)
BlackmanResize(taps=4,last.width,oy)
BlackmanResize(taps=4,ox,last.height)
Sharpen(0.12,0)
return last
}


Elle opère d'emblée un downsampling avec un ratio /(4/3) (->2880x1620). Il n'y a pas de perte d'information car le contenu haute fréquence des BRD UHD est tjrs nul au-delà de cette réso. Cette manière de faire permet de soulager le CPU en sharpenisant une image de dimension plus petite que l'UHD. Ensuite sharpen, puis nouveau downsampling en fullHD puis sharpen.

Ces fonctions utilisent les 2 scripts suivants qui ne sont que la réécriture de LimitedSharpenFaster lorsque SMode = 3 (d'où une grosse simplication du code) :

LSFMode3_2K.avsi :

Code: Tout sélectionner
    # LimitedSharpenFaster()
    ## - MODIFIED version for YV12 (8 bits) using MaskTools 2.0
    ## - Only mode 3

    function LSFMode3_2K( clip clp, float "strength")
    {
    ox = clp.width
    oy = clp.height

    strength  = default( strength,  40 )
    overshoot = 1
    undershoot= 1

    clp.isYV12() ? clp : clp.converttoyv12()

    tmp = last

    dark_limit   = tmp.mt_inpand()
    bright_limit = tmp.mt_expand()

    minmaxavg     = mt_average(dark_limit, bright_limit)
 
    Str=string(strength/100.0)
    normsharp = mt_lutxy(tmp,minmaxavg,yexpr="x x y - "+Str+" * +")

    OS = string(overshoot)
    US = string(undershoot)
    mt_lutxy( bright_limit, normsharp, yexpr="y x "+OS+" + < y x y x - "+OS+" - 1 2 / ^ + "+OS+" + ?")
    mt_lutxy( dark_limit, last, yexpr="y x "+US+" - > y x x y - "+US+" - 1 2 / ^ - "+US+" - ?")

    mt_clamp(normsharp, bright_limit, dark_limit, overshoot, undershoot)

    AMNT  = string(0)
    AMNT2 = string(100)
    sharpdiff=mt_makediff(tmp,last)
    sharpdiff2=mt_lutxy(sharpdiff,sharpdiff.removegrain(19,-1),
    \           "x 128 - abs y 128 - abs > y "+AMNT+" * x "+AMNT2+" * + 100 / x ?")     

    clp.isYV12() ? clp.mergeluma(last) : clp.mergeluma(last.converttoyuy2())
   
    return last
    }


LSFMode3_4K.avsi :

Code: Tout sélectionner
    # LimitedSharpenFaster()
    ## - MODIFIED version for YUV420 (10-12-16 bits) using MaskTools 2.0
    ## - Only mode 3

    function LSFMode3_4K( clip clp, float "strength")
    {
    ox = clp.width
    oy = clp.height

    strength  = default( strength,  40 )
    overshoot = 1
    undershoot= 1

    clp.is420() ? clp : clp.ConvertToYUV420()

    tmp = last

    dark_limit   = tmp.mt_inpand()
    bright_limit = tmp.mt_expand()

    minmaxavg     = mt_average(dark_limit, bright_limit)
 
    Str=string(strength/100.0)
    normsharp = mt_lutxy(tmp,minmaxavg,yexpr="x x y - "+Str+" * +")

    OS = string(overshoot)
    US = string(undershoot)
    mt_lutxy( bright_limit, normsharp, yexpr="y x "+OS+" + < y x y x - "+OS+" - 1 2 / ^ + "+OS+" + ?")
    mt_lutxy( dark_limit, last, yexpr="y x "+US+" - > y x x y - "+US+" - 1 2 / ^ - "+US+" - ?")

    mt_clamp(normsharp, bright_limit, dark_limit, overshoot, undershoot)

    AMNT  = string(0)
    AMNT2 = string(100)
    sharpdiff=mt_makediff(tmp,last)
    sharpdiff2=mt_lutxy(sharpdiff,sharpdiff.removegrain(19,-1),
    \           "x 128 - abs y 128 - abs > y "+AMNT+" * x "+AMNT2+" * + 100 / x ?")     

    clp.is420() ? clp.mergeluma(last) : clp.mergeluma(last.ConvertToYUV422())
   
    return last
    }


Ce dernier script qui va opérer en P16 est malheureusement très consommateur de ressources CPU ...

Voici les liens pour récupérer les DLL x86 à mettre ds (2) et x64 à mettre ds (4) :
http://avisynth.nl/index.php/UnsharpHQ
http://avisynth.nl/index.php/MaskTools2
http://avisynth.nl/index.php/RgTools

Ce qui donne au final les fichiers suivants (j'espère n'avoir rien oublié) à ajouter dans (2) et (4) :

ffavisynth.avsi
ffavisynth.dll
ffdshowSWScaler.avsi
HistogramY.avsi
HTPCVideoProcessing.avsi
LSFMode3_2K.avsi
LSFMode3_4K.avsi
masktools2.dll
Mire2K.avsi
Mire4K.avsi
NaturalSharpen2K.avsi
NaturalSharpen4K.avsi
reso2K.png
reso4K.png
RgTools.dll
UnsharpHQmod.dll
VerticalCrop.avsi
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:42

Il reste ensuite à ajouter ds MPC-HC les traitements des pixels shaders qui vont ajouter la "final touch" :
https://www.mediafire.com/file/0z46v100zvrsneu/Pixel_shaders_HTPC.7z/file


Il sont à mettre en post-redimensionnement et ds l'ordre suivant :

- DX11 Super Acutance.hlsl

Code: Tout sélectionner
// $MinimumShaderProfile: ps_4_0

#define FinesseRendu 0 // 0: très fin, 1: fin, 2: moyen, 3: grossier

#define diff 0.51 // 0.4988 // 0.49864 // 0.497 // 0.493  // influe sur le rendu "3D-Like", typ :
               // 0.49 => 3D-Like + présent
               // 0.50 => 3D-Like présent
               // 0.51 => 3D-Like - présent

#define ICG 3.9 // 2.11 //0.88 0.95      // Intensité de la correction gamma, de 0 à 5 typ
                                    // 0: faible, 5: forte

#define show_area 0   // 0 ou 1 pour visualiser en rouge la zone ou opère le filtre

Texture2D tex : register(t0);
SamplerState samp : register(s0);

cbuffer PS_CONSTANTS : register(b0)
{
   float  px;
   float  py;
   float2 wh;
   uint   counter;
   float  clock;
};

float4 main(float4 pos : SV_POSITION, float2 coord : TEXCOORD) : SV_Target
{
   // Pixels definition: original, blurred, corrected, final
   float4 orig = tex.Sample(samp, coord);
   float4 blurred;
   float4 corrected;
   float4 final;
  float seuil = 0.82 + FinesseRendu/100;

   // Get neighbor points
   // [ 1,    2, 3 ]
   // [ 4, orig, 5 ]
   // [ 6,    7, 8 ]

   float4 c1 = tex.Sample(samp, coord + float2(-px, -py));
   float4 c2 = tex.Sample(samp, coord + float2(  0, -py));
   float4 c3 = tex.Sample(samp, coord + float2( px, -py));
   float4 c4 = tex.Sample(samp, coord + float2(-px,   0));
   float4 c5 = tex.Sample(samp, coord + float2( px,   0));
   float4 c6 = tex.Sample(samp, coord + float2(-px,  py));
   float4 c7 = tex.Sample(samp, coord + float2(  0,  py));
   float4 c8 = tex.Sample(samp, coord + float2( px,  py));

   corrected = orig;

   // edge detection
   float delta1;
   float delta2;
   float value;

   // using Sobel filter
   // horizontal gradient
   // [ -1, 0, 1 ]
   // [ -2, 0, 2 ]
   // [ -1, 0, 1 ]
   // delta1 = (c3 + 2 * c5 + c8) - (c1 + 2 * c4 + c6);
       delta1 = dot((c3 + 2*c5 + c8)-(c1 + 2*c4 + c6),float4(0.2126,0.7152,0.0722,0));

   // vertical gradient
   // [ -1, -2, -1 ]
   // [  0,  0,  0 ]
   // [  1,  2,  1 ]
   // delta2 = (c6 + 2 * c7 + c8) - (c1 + 2 * c2 + c3);
      delta2 = dot((c6 + 2*c7 + c8)-(c1 + 2*c2 + c3),float4(0.2126,0.7152,0.0722,0));

   // computation
   value = sqrt(mul(delta1, delta1) + mul(delta2, delta2));

  // Gamma adaptatif à proximité d'une transition

   if (show_area) { if ((value >= seuil-diff*1.15)&&(value <= seuil)) corrected = float4(1,0,0,0); }
   else if ((value >= seuil-diff*1.15)&&(value <= seuil)) corrected = pow(orig,1./(1-value/(10.5-ICG/10)));

   return corrected;
}


- DX11 Gamma.hlsl

Code: Tout sélectionner
// $MinimumShaderProfile: ps_4_0
// Gamma linéaire pour DX11

Texture2D tex : register(t0);
SamplerState samp : register(s0);

#define g 1.0

float4 main(float4 pos : SV_POSITION, float2 coord : TEXCOORD) : SV_Target
{
   return pow(tex.Sample(samp, coord),g);
}


Ces traitements qui opèrent sur la réso finale ne doivent surtout pas altérer la structure fréquentielle des mires 1-2-3-... pixels, et donc celle de l'image. L'idée exploitée par le shader "DX11 Super Acutance.hlsl" consiste à s'intéresser à des zones autour des "edges" de l'image et à faire une modification adaptative du gamma dans ces zones pour renforcer localement le contraste. Ce faisant, comme on ne touche localement que le gamma, on respecte forcément la structure de l'image et donc son piqué induit par ses fréquences spatiales. L'effet est subtil mais bien visible sur des mires "naturelles" telles que des visages (cf. par exemple la mire faite par Kaz que j'aime bien avec le visage d'Olivia Wilde et une machine robotique futuriste ...). Ce traitement permet de renforcer localement la dynamique de l'image et donc le contraste intra en rendant l'image un poil plus "vivante". Le pixel shader "DX11 Gamma.hlsl" est là au cas où il faudrait faire un petit ajustement final du gamma de l'image (c'est tjrs pratique d'avoir ça sous la main).

Paramètres pouvant être ajustés :

- pour "DX11 Super Acutance.hlsl" -> diff, ICG, show_area (voir commentaires dans le code source)
- pour "DX11 Gamma.hlsl" -> g

Dès l'instant ou un fichier .hlsl d'un shader actif est modifié et sauvegardé, MPC-HC le compile à la volée et le shader est mis-à-jour ds la CG. Par exemple, si vous mettez le paramètre show_area à 1 et que vous sauvegardez le fichier pendant la lecture d'une vidéo, les zones ou le pixel shader sera actif apparaitront en rouge. Comme les shaders par défaut DX9 et DX11 de MPC-HC sont dans des dossiers protégés, le plus simple est de mettre ces nouveaux shaders ds un dossier à part, puis de les ajouter à la liste par défaut des shaders déjà disponibles. Pour ça, il faut faire clic droit/Effets vidéos/sélectionner les effets... La liste qui s'affiche par défaut correspond aux pixels shaders DX9 installés avec MPC-HC. Vous pouvez vider cette liste qui ne sert à rien puisqu'on est en DX11. En cliquant sur "Ajouter un fichier d'effet" vous pouvez ajouter les nouveaux shaders DX11 (et également les shaders DX11 présents dans le dossier de MPC-HC). Ensuite il faut mettre les shaders ds "Effets post-redimensionnement actifs" (en mettant la correction de gamma en 2e) puis sauvegarder l'effet créé en lui donnant un nom spécifique dans "Présélections d'effets" et en cliquant sur "Sauvegarder". Cet effet apparaitra alors ds le menu contextuel "Effets vidéo" et vous pourrez le sélectionner pour rendre actifs les pixel shaders correspondants.
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 17:43

Les settings que j'ai donné maximisent bien le piqué sur un moniteur ou un projo fullHD avec une très bonne acutance comme un monoDLP avec une puce 0.95". Pour les autres diffuseurs fullHD, on peut en général obtenir un bon résultat en augmentant un peu le param LSFstr de NaturalSharpen2K() ou NaturalSharpen4K() ainsi que boostAcutance. Je vous conseille d'augmenter doucement LSFstr pour voir si les changements sont perceptibles ou pas (21.35 au lieu de 21.25, etc.) et de contrôler avec les mires que vos changements n'altèrent pas leur géométrie (point très important).

Côté conso CPU voici ce que j'ai sur mon 5600X@4.725 GHz :

BRD HD full frame traité en YV12 : 6% en moyenne
BRD UHD full frame traité en P16 : 36% en moyenne (mais un coeur est chargé à 90%, néanmoins ça passe ...)
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline

Message » 03 Avr 2022 18:10

Merci pour ce tuto qui est un peu ce à quoi je m'attendais pour certains cotés :bravo:
-Lyam-
 
Messages: 166
Inscription Forum: 21 Aoû 2020 19:58
  • offline

Message » 03 Avr 2022 18:22

Pfff :o
Un grand merci pour la démarche et le partage
Goldfinger67
 
Messages: 6931
Inscription Forum: 18 Nov 2008 15:34
Localisation: Aveyron
  • offline

Message » 03 Avr 2022 18:51

Merci ;)

Je précise qu'en utilisation normale une fois qu'on a réglé la puissance du post-traitement une bonne fois pour toute, les seuls paramètres à modifier sont ceux de HTPC.avs.

En pratique, ça se résume juste à cropper les bandes noires des sources UHD (lorsqu'elles sont présentes) pour soulager le CPU. Pour les BRD, la conso est tellement faible qu'il n'y a rien à faire.

Et puis lorsqu'on a un rendu qu'on trouve vraiment foireux (heureusement c'est exceptionnel), on peut jeter un oeil sur l'histogramme. C'est comme ça que j'ai immédiatement compris le pb qu'avait le BRD "Premier contact" de Villeneuve. Je l'ai corrigée pour pouvoir retrouver l'image magnifique et le ressenti émotionnel que j'avais vécu en salle de ciné. Je vous montrerai ça plus tard. Dans ce cas, la correction n'opère bien que sur le BRD UHD pour une raison que j'expliquerai aussi ...
Emmanuel Piat
Contributeur HCFR 2016
 
Messages: 10411
Inscription Forum: 10 Oct 2000 2:00
Localisation: Besançon, FRANCE
  • offline


Retourner vers Logiciel PC Home-cinéma

 
  • Articles en relation
    Dernier message