[Thomson] Vidéo avec son en streaming

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

Voici les tout derniers clips: http://dl.free.fr/fMImBINbz

La plupart ont un radio video très proche de 1:1, ce qui signifie qu'une frame ne déborde quasiment pas de son temps imparti: on est à 10fps ce qui est suffisamment fluide. La video qui n'arrive pas à atteindre 10fps est "come into my wold" qui avec 1:0.52 a besoin d'un peu moins de 0.2s par image ce qui n'est pas surprenant quand on voit que ce clip est un long panotage de 4mins.

Code : Tout sélectionner

$ for i in *.mp4 *.flv; do perl conv_sd.pl "$i"; done                           Amiga Trackmo  Arte _ Sanity (1993) HQ.mp4 : 450x360 -> 192x140
0:09:21 (1x) v=1:0.983 a=1:-25
Amiga Trackmo  Enigma _ Phenomena (1991) HQ.mp4 : 450x360 -> 192x140
0:10:12 (1x) v=1:1 a=2:-43
Amiga Trackmo  World of Commodore 92 _ Sanity (1992) HQ.mp4 : 450x360 -> 192x140
0:09:48 (1x) v=1:0.939 a=1:-18
Daft Hands - Harder, Better, Faster, Stronger.mp4 : 540x360 -> 192x140
0:03:44 (1x) v=1:0.999 a=1:0
Daft Punk - Harder Better Faster Stronger.mp4 : 640x360 -> 224x128
0:03:43 (1x) v=1:0.887 a=1:0
Dire Straits - Calling Elvis.mp4 : 480x360 -> 192x140
0:04:45 (1x) v=1:0.904 a=2:-69
Dire Straits - Money For Nothing.mp4 : 480x360 -> 192x140
0:04:59 (1x) v=1:0.933 a=2:-69
Dire Straits - Private Investigations.mp4 : 480x360 -> 192x140
0:05:46 (1x) v=1:0.964 a=4:-99
Dire Straits - Sultans Of Swing.mp4 : 480x360 -> 192x140
0:04:26 (1x) v=1:0.948 a=5:-103
Eric Prydz - Call on me.mp4 : 640x360 -> 224x128
0:03:01 (1x) v=1:0.83 a=1:0
Eric Prydz - Pjanoo.mp4 : 640x358 -> 224x128
0:03:08 (1x) v=1:0.894 a=1:-29
Indiana Jones Boulder Scene.mp4 : 640x278 -> 224x128
0:00:28 (1x) v=1:0.921 a=1:-24
Junior Senior - Move Your Feet (Official music video, HD).mp4 : 450x360 -> 192x140
0:03:18 (1x) v=1:0.904 a=1:-15
Kiss Kill - Candy Says.mp4 : 480x360 -> 192x140
0:02:59 (1x) v=1:0.958 a=1:0
Kylie Minogue - Can't Get You Out Of My Head.mp4 : 554x360 -> 192x140
0:03:47 (1x) v=1:0.819 a=3:-88
Kylie Minogue - Come Into My World [HD].mp4 : 640x360 -> 224x128
0:04:18 (1x) v=1:0.52 a=1:0
Kylie Minogue - In Your Eyes.mp4 : 626x360 -> 224x128
0:03:17 (1x) v=1:0.671 a=4:-92
Kylie Minogue - Love At First Sight.mp4 : 496x360 -> 192x140
0:03:56 (1x) v=1:0.88 a=3:-84
Kylie Minogue - Spinning Around.mp4 : 640x360 -> 224x128
0:03:31 (1x) v=1:0.718 a=1:-38
Lemon - Groovy! - Amiga Demo.mp4 : 640x360 -> 224x128
0:05:53 (0.8x) v=1:0.996 a=2:-74
Masoud feat. Aneym - No More (Music video))).mp4 : 640x360 -> 224x128
0:04:06 (0.7x) v=1:0.991 a=1:0
Michael Gray - The Weekend (Official Video).mp4 : 640x360 -> 224x128
0:03:10 (0.7x) v=1:0.798 a=2:-73
Sanity Interference demo (Amiga).mp4 : 450x360 -> 192x140
0:06:27 (0.8x) v=1:0.95 a=1:-30
Shadow of The Beast Gameplay Amiga 500.mp4 : 640x360 -> 224x128
0:08:08 (1x) v=1:0.992 a=1:0
Spaceballs - 9 Fingers - Amiga Demo (HD 50fps).mp4 : 640x360 -> 224x128
0:03:02 (1x) v=1:0.948 a=1:-28
Spaceballs - State Of The Art - Amiga Demo.mp4 : 640x360 -> 224x128
0:04:07 (1x) v=1:0.797 a=2:-41
Star Trek Genesis.mp4 : 480x360 -> 192x140
0:01:05 (1x) v=1:0.997 a=8:-123
Star Wars A New Hope 1977 Trailer.mp4 : 640x360 -> 224x128
0:02:45 (1x) v=1:0.852 a=1:-12
Star Wars Episode V - The Empire Strikes Back Trailer.mp4 : 540x360 -> 192x140
0:03:15 (1x) v=1:0.978 a=1:0
Star Wars- Return Of The Jedi Trailer (HD).mp4 : 640x360 -> 224x128
0:02:11 (1x) v=1:0.926 a=1:-12
Star Wars The Force Awakens Special Extended Trailer.mp4 : 1280x720 -> 224x128
0:02:28 (1x) v=1:0.955 a=1:0
THE ABYSS - Trailer ( 1989 ).mp4 : 540x360 -> 192x140
0:02:57 (1x) v=1:0.986 a=1:0
ZZ Top - Gimme All Your Lovin' (OFFICIAL MUSIC VIDEO).mp4 : 640x360 -> 224x128
0:04:47 (1x) v=1:0.948 a=2:-52
Georges Brassens Bobino 1972 08 Les amours d'antan.flv : 318x240 -> 192x140
0:03:18 (1x) v=1:0.999 a=1:-1
JACQUES BREL - Live Olympia 1966 COMPLET.flv : 294x240 -> 192x140
1:01:27 (1x) v=1:0.996 a=1:0
Joan Baez - Farewell Angelina (France,1966).flv : 320x240 -> 192x140
0:03:14 (1x) v=1:0.798 a=3:-81
J'ai découvert un truc curieux avec image-magick. Suivant sa version, l'espace de couleur RGB est linéaire ou non. Ici il n'est pas linéaire ce qui fait que les contrastes sont moins prononcés et que l'image est globalement plus lumineuse pour les basses intensités. Néanmoins je trouve que le rendu n'est pas mal quand même. <URL d'une version linéaire à venir pour pouvoir comparer>
[EDIT] voilà http://dl.free.fr/iM6YENu4x

J'aime assez l'idée qu'un THOMSON soit capable d'afficher des effets de démo d'amiga. C'est de la triche, mais c'est marrant. Il manque juste la couleur... :roll:

Parmi ces 37 vidéos, laquelle préférez vous ? (Sultan Of Swing passe très bien, mais je suis peut-être piégé par le son).
Dernière modification par __sam__ le 11 juin 2015 22:59, modifié 2 fois.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] Vidéo avec son en streaming

Message par Daniel »

L'amélioration la plus spectaculaire est la fluidité. D'un autre côté, on perd le plein écran, mais l'impression globale est bien meilleure.
Je connais particulièrement bien la vidéo de Jacques Brel à l'Olympia, pour l'avoir utilisée dans de nombreux essais de noir et blanc, de tramage ordonné et de diffusion d'erreur. Je pense qu'on peut encore l'améliorer en jouant sur les niveaux, ou le contraste, pour éviter les points blancs dans l'arrière plan. Finalement c'est assez gênant, et pas seulement dans cette vidéo.

Je n'ai pas encore tout visionné, mais le résultat est nettement mieux que dans la première version, en particulier dans les films (Indiana Jones, Star Wars). Et les traitements audio rendent le son exceptionnel. Avec un téléviseur c'est déjà pas mal, mais avec une bonne chaîne audio le son est remarquable, au moins pour mes oreilles pratiquement insensibles au delà de 10 kHz.

Et comme toi, j'ai un petit faible pour Sultan Of Swing. Enlève juste quelques points blancs dans le fond et ce sera parfait.
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

Je pense qu'on peut gagner peut-être 1/3 (au pif) de bande passante avec un format de donnée de la forme: <decalage> <video1> <video2> <son>. L'idée est que l'on aurait 2 octets videos par échantillon audio (soit 12khz, largement de quoi être content). Mais du coup avec 2 échantillons video on rempli plus vite les lignes ce qui accélèrera les changements "de masse" qui sont ceux qui font effondrer le fps. Les sauts seraient aussi doublés: 2*<décalalge> (2 ABX) ce qui veut dire que les grosses zones sans changements seraient parcourues plus vite (environ 13 lignes d'un coup contre 6 auparavant), laissant plus de bande passante pour les zones avec changement. Seuls les changements isolés seraient un peu perdant, mais ils sont rares. (la vitesse de compression ferait aussi un x2: l'écran ne contient moralement plus que 4000 short au lieu de 8000 char)

Avec 1/3 de puissance en plus, on peut soit faire passer à 13fps (mouais...) soit augmenter la réso écran de 70% à 90% (super!).

Parmi les clips avec des défauts à voir le "Come into my world" bénéficierait de cet encodage.

Ca nécessiterait un player adapté. A experimenter.

Pour les points blancs dans les couleurs sombres, je pense que c'est justement lié au gamma non linéaire. Le sombre devrait être plus sombre si le gamma était corrigé.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] Vidéo avec son en streaming

Message par Daniel »

Un petit détail, pour lequel je n'ai pas de vraie solution : les pixels d'un moniteur Thomson ne sont pas carrés. Toutes les images paraissent tassées dans le sens de la largeur. A l'inverse, avec un téléviseur 16/9, les images paraissent tassées dans le sens de la hauteur. Elles ne sont bonnes qu'avec dcmoto en appliquant le même facteur de zoom en hauteur et en largeur.

Je me bats avec ce problème depuis 1984 (31 ans déjà !). Pour représenter des cercles à l'écran du MO5, je calculais des ellipses. Plus tard, avec l'émulation, tous les cercles parfaits de mes programmes se sont retrouvés aplatis. Pour bien visualiser le phénomène il suffit d'aller à cette page : http://dcmoto.free.fr/programmes/sdplay/index.html
Les miniatures sont affichées comme sur un écran Thomson. Elles paraissent compressées en largeur. Quand on passe la souris dessus, elles s'agrandissent avec des pixels carrés et donc les bonnes proportions, mais en fait ce n'est pas ce que l'on voit sur Thomson. Je ne sais pas ce qu'il faut faire...
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

Tiens c'est curieux ca. Sur la TV 16:9 qui est connectée au TO8 j'ai ce soucis qu'il est possible de corriger en jouant sur les paramètres de zoom Y de la TV (mais ca ne corrige pas suffisamment et ca ne reste pas en mémoire). J'ai toujours mis ca sur le dos des TV modernes, car il me semble que sur mon TO9 le monitor thomson 4:3 puis la TV crt 4:3 qui l'équipent les cercles sont bien ronds.

Cependant, avec les moniteurs thomson, il y a une pièce spéciale en plastique/nylon que j'ai utilisée pour régler les potentiomètres permettant de modifier l'aspect-ratio (http://dcmoto.free.fr/documentation/mc9 ... 0-036.djvu, page 5). Le moniteur thomson a aussi longtemps équipé mon Amiga et affichait des cercles ronds avec les mêmes réglages que le thomson. (Dommage qui le marche plus, je l'aimais bien ce moniteur.) En outre pour la TV crt qui le remplace je n'ai touché à aucun réglage et les cercles sont ok dans mon souvenir (il faudrait que je mesure).

Je pense que la convention des pixels carrés utilisés par DCMoto est la bonne car c'est ce que tous les écrans actuels affichent. Ainsi sur mon portable dell à l'écran 16:10 (et pas 16:9) le plein-écran de DCMOTO serait parfait si l'on pouvait réduire à la zone de tour à 0 pixels. Par contre il est vrai que sur le CRT 4:3 le plein écran est totalement allongé dans le sens des Y: il faudrait des bords plus gros en haut et en bas pour compenser l'étalement en Y.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

Je viens d'éditer l'un des message ci-dessus pour y mettre comme promis l'url avec un gamma corrigé pour avoir des intensités linéaire. Je trouve le resultat bien mieux au niveau des basses intensités, et globalement le contraste me semble bien meilleur.

A noter:
1) dans mes videos précédentes, il y a avait un bug dans la création de la matrice de void-and-cluster qui faisait que 10% des pixels avaient la valeur 1, c'est à dire que 10% des pixels s'allumaient trop tôt dans les basses intensités. Combiné au gamma non corrigé cela devait faire apparaitre trop de pixels allumés aux basses intensités.

2) Je n'arrive à corriger le gamma que sur une vieille machine lente avec une vieille version de Image Magick. C'est pour ca qu'il n'y a pas toutes les vidéos. Je pense que pour rendre la sortie indépendante de la version du convertisseur d'image je vais faire un convertisseur en C qui gérera la correction gamma. Ainsi je maitriserais toute la chaine de production.

3) la taille de la vidéo est réduite à 70% pour tenir dans la bande passante. Mais du coup il y a une grosse bande noir en haut. Cette bande fait 36 lignes soit 1440 octets qu'il faut systématiquement sauter juste après réception du code $00. Cela gaspille 6 triplets audio-video. On pourrait les économiser en disant que l'octet qui suit $00 n'indique pas un octet vidéo, mais un numéro de ligne. Ainsi en fin d'image on peut directement sauter par dessus le cadre noir. Mais est-ce que gagner 6 triplet augmentera le framerate? Pas évident qu'on remarque un grand changement. Bon ce n'était qu'une idée comme ca.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] Vidéo avec son en streaming

Message par Daniel »

La nouvelle version est nettement mieux. Elle supprime une partie des points blancs qui me gênaient dans la précédente. Personnellement j'irai encore plus loin, en augmentant un peu le contraste ou en jouant sur les niveaux. Je trouve préférable de saturer les blancs et les noirs, plutôt que d'avoir des points isolés dans des zones d'une même couleur. Mais c'est une question de goût, on peut avoir d'autres avis.

Dans le programme C de génération du fichier .sd, il y a deux constantes YDEB et YFIN, prévues dans le cas de bandes noires en haut et en bas de l'image. Si on les utilise, il faut aussi adapter le player pour initialiser le registre X à la valeur YDEB à chaque nouvel écran.
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

Pour tester l'idée de sauter par dessus la bande noire, je viens de simplement caler la vidéo en haut pour voir si la compression était meilleure. Et bien ca ne change pas grand chose au final. Le jeu n'en vaut pas la chandelle.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] Vidéo avec son en streaming

Message par Daniel »

En remontant l'image on ne perd plus d'octets en haut, mais il faut aussi supprimer le balayage du bas de l'écran. Je suppose que tu as modifié le script pour en tenir compte ?
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

oui sitôt arrivé en bas dans la zone noire ($pos>=$y2 dans le code), on ecrit $0 pour les octets video jusqu'à la fin du buffer (en fait on sort juste de la boucle de scan car le buffer est initalisé à 0 à l'entrée de la fonction). Il y a un peu de gaspillage de bande passante là. Il fadurait que je mesure ca pour voir si on ne peut pas en déduire une augmentation possible du FPS et/ou du zoom.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

__sam__ a écrit :oui sitôt arrivé en bas dans la zone noire ($pos>=$y2 dans le code), on ecrit $0 pour les octets video jusqu'à la fin du buffer (en fait on sort juste de la boucle de scan car le buffer est initalisé à 0 à l'entrée de la fonction). Il y a un peu de gaspillage de bande passante là. Il fadurait que je mesure ca pour voir si on ne peut pas en déduire une augmentation possible du FPS et/ou du zoom.
Je me suis beaucoup questionné sur ce dernier point. En effet dans l'algo précédent le zoom est fixé à 70% de façon heuristique: c'est ce que j'ai trouvé de mieux en compromis taille/bande passante. Mais il est évident que pour les vidéos relativement fixe c'est un énorme gaspillage de bande passante. Ces vidéos devraient être capable de tourner à plein image. Le soucis c'est que c'est variable d'une vidéo à l'autre.

Du coup, j'ai imaginé hier un algo adaptatif assez intéressant. L'idée est d'échantillonner la vidéo plein écran et mesurer combien il faudrait d'octets en moyenne pour stocker une image+son (avec un buffer arbitrairement grand). Oublions la partie son qui ne se compresse pas, et appelons cette quantité IMG_MOYENNE. Normalement ca doit tenir dans BUFFERSIZE = 3*freq_audio/fps (freq_audio = 16125Hz, fps=10 chez moi mais on peut s'amuser avec 25 ce qui divise BUFFERSIZE par plus que 2). On a alors 2 cas possibles:
  • cas 1: IMG_MOYENNE<BUFFERSIZE. C'est super, tout tient dans la taille du buffer. La video est facilement comprimable et il y a de la bande passante en surplus. Que faire de ce surplus ? On ne peut pas agrandir l'image puisque l'on est déjà à plein échelle. En revanche on peut augmenter le framerate pour ammener BUFFERSIZE à être sensiblement de la taille de IMG_MOYENNE. Une simple règle de 3 montre que l'on peut faire passer le fps à 3*freq_audio/IMG_MOYENNE, ce qui revient à multiplier le framerate d'origine par BUFFERSIZE/IMG_MOYENNE. Cool! :D
  • cas 2: IMG_MOYENNE>BUFFERSIZE. L'image ne se compresse pas dans le buffer imparti. Que faire ? Réduire le FPS? Non c'est moche. En effet dans le cas 2, IMG_MOYENNE est typiquement de l'ordre de 15ko alors que BUFFERSIZE est à 4.8ko quand on joue à 10FPS. Donc il faut réduire le FPS d'un facteur 3-4 pour que les 15ko tiennent dans BUFFERSIZE, ce qui nous fait une vidéo entre 2 et 3 fps plein écran. C'est archi lent.

    En revanche on peut réduire la taille de l'image (paramètre ZOOM dans mon code). Et là le gain est bien plus spectaculaire car songez que si on divise la taille de l'image par 2, il y a environ 4fois moins d'information à compresser et IMG_MOYENNE est divisé par 4. Nos 15ko/4 tiennent impec dans le BUFFERSIZE de 10fps. Le buffer est même trop gros du coup. On peut calculer exactement le meilleur zoom qui nous amène IMG_MOYENNE dans BUFFERSIZE. En 1ere approximation, la taille de l'image est donnée par la formule IMG_MOYENNE(zoom=1) * zoom^2, donc ca signifie qu'on peut réduire l'image plein écran d'un facteur sqrt(BUFFERSIZE/IMG_MOYENNE). Dans le cas typique ou BUFFERSIZE=5ko et IMG_MOYENNE=15ko, ca nous fait sqrt(1/3) = 0.577. On est tout proche des 70% empirique que j'ai trouvé, mais ici c'est calculé.
En pratique pour être plus sur es estimation, j'augmente IMG_MOYENNE de 10-15% histoire 'avoir un peu de marge pour les cas extrèmes (car le calcul n'est valable que pour la moyenne. Si je prends 10-15% autour je couvre un peu plus la variance.
Daniel a écrit :La nouvelle version est nettement mieux. Elle supprime une partie des points blancs qui me gênaient dans la précédente. Personnellement j'irai encore plus loin, en augmentant un peu le contraste ou en jouant sur les niveaux. Je trouve préférable de saturer les blancs et les noirs, plutôt que d'avoir des points isolés dans des zones d'une même couleur. Mais c'est une question de goût, on peut avoir d'autres avis.
Je me suis aussi penché sur cette question. Ce que tu veux Daniel est un contraste sigmoidal. C-a-d que la courbe de contraste fait un S. Autour d'une valeure centrale la pente n'est plus de 1:1 mais plus prononcée ce qui a pour effet d'augmenter le contraste. Cependant contrairement au contraste classique ou du coup on saturerait les blanc et les noirs, le contrast sigmoidal rattrape le point 0 et le point 255 avec une belle courbe bien lisse, ce qui évite l'impression qu'on a brutalement noirci ou blanchis les pixels. C'est plus doux.

A priori, on pourrait se dire que le point milieux est autour du gris 50% et que la pente est de l'ordre de 6:1 ou 10:1. 10:1 c'est trop pentu, ca fait apparaitre trop vite des pixels cramés. A 3:1 en revanche la pente n'est pas assez forte et les gris entrainant des pixels isolés sont toujours trop visibles. Experimentalement j'ai trouvé qu'une pente 4:1 à 6:1 est bien. Le 6:1 aurait tendance a faire un contraste trop fort, mais vu que tu as dis que tu préférais cela c'est ce que j'ai mis dans l'algo.

Reste le point milieu. 50% c'est trop haut quand l'image est essentiellement sombre et cela a pour effet de réhausser les gris sombres. A l'inverse c'est trop bas quand l'image est blanche. La plupart des pixels clairs sont écrasés vers la valeur 255. Ce qu'il semble évident après réflexion c'est que cela dépend de l'image.

Une solution initiale est de prendre comme point milieu la moyenne de l'intensité de l'image. C'est bien mais en pratique sur les vidéo de démos amiga ou il n'y a que la partie centrale de l'écran qui contient de l'information, la moyenne est très basse (20% de l'intensité max), ce qui a pour effet de pousser tous les pixels de l'effet central vers le blanc. Pas génial. Aussi j'ai eu une drôle d'idée qui marche plutôt bien: diviser l'image en 3x3 et calculer la valeur moyenne dans chacun de ces 9 rectangles. Je prends alors comme point-milieu la moyenne la plus haute de ces 9 rectangle. Cela revient à mettre le point moyen dans la zone écran contenant probablement de l'info importante et pour laquelle in ne vaut pas trop assombrir ou cramer les pixels. Quand on fait ca ca marche bien, trop bien même, et les corrections de contraste à chaque image font apparaitre une sorte de papillonage des intensité. En fait ce qu'il manque pour que ca marche bien est un amortisseur pour eviter de faire bouger le point milieu de trop à chaque image intercalaire hors-norme (ce qui est très fréquent dans les démos ou les vidéo-clips flashy ont une image brillante se glisse transitoirement au mileu d'une scène sombre). Aussi j'ai ajouté au calcul du point milieu un filtre passe-bas du 1er-ordre pour qu'il ne bouge pas trop vite. Sa constante de temps est sensiblement 10images, ce qui veut dire qu'il prend en quelque sorte le point-milieu sur la dernière seconde vidéo. Ca marche pas trop mal.

Toutes ces idées sont implémentées dans l'algo suivant qui ma valu de passer quasiment une nuit blanche hier soir (je me suis couché quand le soleil commençait à poindre son nez). Ca ne m'était pas arrivé depuis longtemps, mais c'est ce qu'il se passe quand le cerveau est stimulé par plein de nouvelles idées. Impossible de se résigner à se coucher, la fatigue n'est pas là et il y a toujours quelque chose de plus à tester. Ca m'a fait rajeunir de 20-25ans d'avoir ainsi l'esprit hyper actif. Bref voici le code:

Code : Tout sélectionner

#/bin/perl

##############################################################################
# Conversion de fichier video en fichier SD fonctionnant avec le
# player SDANIM3 de Daniel Coulom pour THOMSON.
#
#        (http://dcmoto.free.fr/programmes/sdanim3-brassens/)
#
# par Samuel Devulder.
#
# Historique:
# ===========
# 09/06/2015 - version initiale. Portage semi direct du code C.
#
# 10/06/2015 - utilisation de la matrice vac-8 qui donne une image plus 
#              fine que le h4x4a
#            - fps et zoom revu pour avoir une vitesse et une qualité 
#              très correcte (10fps et zoom 70%)
#            - optimisation de la vitesse de compression:
#                - les bords noirs supérieur et inférieurs de l'écran 
#                  sont ignores
#                - la boucle while cherchant les différences ne lit à
#                  présent qu'un seul des deux tablraux puisque la lecture 
#                  nous fournit en cible le delta avec l'image actuelle.
#              du coup la vitesse d'encodage passe de x0.4 à x1.
#            - meilleure synchro video quand une image est compressée en 
#              moins de BUFFSIZE octets: on retourne simplement en haut
#              de l'écran sans re-encoder la même image de sorte qu'au
#              changement d'écran on redémarre en haut de la nouvelle image. 
#              On ne voit quasiment plus des demi-images et la vidéo est
#              très fluide
#            - mise en place d'une correction sonnore auto-adaptative. 
#              Donne d'excellents resultats pour Dire Straits (sultan of
#              swing est fort et clair avec une bonne dynamique à présent).
#            - stockage des images temporaires dans un sous-dossier tmp/
#              pour ne opas polluer le répertoire courant.
#                  
# 12/06/2015 - mise en place d'un algo pour calculer le meilleur zoom
#              ou framerate. Dans un 1er temps la vidéo est échantillonnée
#              à 1 image /sec (pour aller vite) avec un zoom de 1. Puis
#              compressée sans limite de taille de buffer. A la fin de la 
#              vidéo on obtient le nombre d'octets moyen par image (LEN_BY_IMG). 
#
#              si LEN_BY_IMG est inférieur au BUFFERSIZE associé au framerate
#              choisi (FPS), ca veut dire que le framerate est un peu petit
#              et que l'on gaspille des octets puisque BUFFERSIZE n'est pas
#              complètement rempli. On peut alors augmenter le framerate de
#              la même proportion d'écart entre BUFFERSIZE et LEN_BY_IMG:
#                       FPS <- FPS*(BUFFERSIZE/LEN_BY_IMG)
#              C'est ce qu'il se passe avec les video facilement compressibles
#              l'outil va en profiter pour augmenter le FPS afin d'occuper
#              tout le buffer alloué à une image. Cependant le cas le plus
#              fréquent est le suivant:
#
#              Si LEN_BY_IMG est supérieur à BUFFERSIZE, c'est que ce dernier
#              est trop petit pour contenir une image compressée. On peut alors
#              jouer sur le facteur de zoom pour que l'image compressée tienne
#              dans BUFFERSIZE. En première approximation si on réduit l'image
#              d'un facteur r<1, le nombre de pixel à compresser est réduit
#              d'un facteur r*r. La taille compressée est elle aussi sensiblement
#              réduite du même facteur (imaginez diviser une image par 2, il y a
#              4x fois moins d'information à compresser, et la compression sera
#              aussi 4x plus petite). Du coup cela veut dire que r*r peut valoir
#              LEN_BY_IMG/BUFFERSIZE plus une petite marge (que je fixe à 10%).
#              Cela signifie que l'on peut utiliser un zoom de
#                       SQRT(BUFFERSIZE/(LEN_BY_IMG + 10%))
#              pour avoisiner le taux d'occupation idéal de BUFFERSIZE.
#
#            - mise en place d'un contraste sigmoidal qui tasse les intensités
#              sombre et lumineuses afin d'avoir des image très contrastée qui
#              apparaissent dès lors un peu moins bruitées. Cependant je 
#              les trouve alors moins riche au niveau des dégradés.
# 
##############################################################################

#use Graphics::Magick;

$file = $ARGV[0];

# params par defaut
mkdir("tmp");
$img_pattern = "tmp/img%05d.bmp";
($w, $h) = (320, 180); # 16:9
$hz  = 16125;
$fps = 10;
$zoom = .7;
$dith = "h4x4a";
#$dith = "h8x8a";
$dith = "vac-8";
#$dith = "8x8";

$BUFFERSIZE = int((3*$hz+$fps-1)/$fps);

# recherche la taille de l'image
($x,$y, $aspect_ratio) = (320,200,"16:9");
open(IN, "./ffmpeg -i \"$file\" 2>&1 |");
while(<IN>) {
	if(/, (\d+)x(\d+)/) {
		($x,$y) = ($1, $2);
		# 4:3
		if(abs($x - 4/3*$y) < abs($x - 16/9*$y)) {
			($w,$h,$aspect_ratio) = (266,200,"4:3");
		}
	}
}
close(IN);
print $file," : ${x}x${y} ($aspect_ratio)\n";

# AUDIO: unsigned 8bits, mono, 16125hz
open(AUDIO, "./ffmpeg -i \"$file\" -v 0 -f u8 -ac 1 -ar $hz -acodec pcm_u8 - |");
binmode(AUDIO);

# tuyau vers ffmpeg pour images
open(FFMPEG,'| (read line; $line)');#  -vf format=gray
binmode(FFMPEG);

# fichier video (entree)
open(IN, "<$file");
binmode(IN);

# determination du zoom optimal
$zoom = &guess_zoom($w, $h);
$fps = int($fps * ($zoom>1?$zoom:1));
$BUFFERSIZE = int((3*$hz+$fps-1)/$fps);
$w = int($w*($zoom>1?1:$zoom));
$h = int($h*($zoom>1?1:$zoom));
print sprintf("zoom = %.2g -> %dx%d @ %dfps\n", $zoom, $w, $h, $fps);
$cmd = "./ffmpeg -i - -v 0 -r $fps -s ${w}x${h} -an $img_pattern\n";
syswrite(FFMPEG, $cmd, length($cmd));

# nettoyage
unlink(<tmp/img*.bmp>);

# fichier sd (sortie)
$name = $file; $name =~ s/\.[^\.]*$//; $name .= ".sd";
open(OUT, ">$name");
binmode(OUT);

# multiplicateur audio
@audio_cor = (8, 255);

# compteur image
$cpt = 1;

# ecran courant
@ecran = ((0) x 8000, 1);

# position dans ecran
$pos = 7999;

# compression
$time = 0; $start = time; $realimg = 0; $pause = 60;
while(&next_image(*IN,*FFMPEG,$w,$h) && &compresse()) {
	if($cpt%$fps == 0) {
		++$time;
		my($d) = time-$start+.0001;
		print STDERR sprintf("%d:%02d:%02d (%gx) v=1:%.3g a=(x%+d)*%.1g        \r",
			int($time/3600), int($time/60)%60, $time%60,
			int(10*$time/$d)/10, $realimg/$cpt, -$audio_cor[1], $audio_cor[0]);
		# pour ne pas trop chauffer
		if($d>$pause) {
			$pause = $d+60;
			sleep(10);
		}
	}
	
	#last if $time>30;
}

# fin fichier
print OUT pack('C*', (0x00,0x00,0xFF) x int($BUFFERSIZE/3));

# nettoyage et fermetue flux
print STDERR "\n";
unlink(<tmp/img*.bmp>);
close(OUT);
close(IN);
close(FFMPEG);
close(AUDIO);

# Lit l'image suivante. Retourne 1 si ok, 0 si fin fichier
sub next_image {
	my($IN, $OUT, $w, $h) = @_;
	# nom du fichier BMP
	my $name = sprintf($img_pattern, $cpt++);
	
	# taille fichier BMP
	my $expected_size = $h*(($w*3 + 3)&~3) + 54; # couleur

	#print "$w, $h, $expected_size\n";

	# on nourrit ffmpeg jusqu'a obtenir un fichier BMP fini
	while($expected_size != -s $name) {
		my $buf;
		my $read = read($IN,$buf,8192);
		last unless $read;
		syswrite $OUT, $buf, $read;
	} 
	
	# lecture image
	my $tmp = Image::Magick->new();
	my $z = $tmp->Read($name);
	return 0 if $z; # si erreur => fin fichier
	unlink $name;

	# dither
	$tmp->Set(depth=>16);
	#$tmp->Set(colorspace=>"RGB");
	#$tmp->Gamma(gamma=>0.55);
	
	$tmp->Set(type=>"grayscale");
	if(1) { # marche pas
		my $z = $tmp->Clone();
		$z->Resize(geometry=>"3x3!");
		my(@t) = $z->GetPixels(map=>"RGB", normalize=>"True", height=>3);
		my($max) = 0;
		for my $v (@t) {$max = $v if $v>$max;}
		$last_m = $max if $cpt==2;
		$last_m = $max = $last_m*.9 + $max*.1;
		#print $max, "    \n";
		$z = "6x".int($max*100)."%";
		$tmp->SigmoidalContrast($z);
	} elsif(0) {
		$tmp->Normalize(channel=>"RGB");
	} else {
		$tmp->SigmoidalContrast("6.5x70%");
	}
	$tmp->Set(colorspace=>"RGB");
	# $tmp->Gamma(gamma=>0.65);
	
	#$tmp->Set(monochrome=>"True");
	
	$tmp->OrderedDither(threshold=>"$dith,2");
	#$tmp->Write($name) if $cpt<100;

	
	# centrage dans image 320x20
	my $img = Image::Magick->new(size=>"320x200");
	$img->Read("canvas:black");
	$img->Composite(image=>$tmp,compose=>"Over",
	                x=>(320-$w)>>1,y=>(200-$h)>>1);
	
	# remplissage variable globale @cible
	my(@p) = $img->GetPixels(map=>"RGB", height=>200, width=>320, normalize=>"True");
	
	@cible = ();
	for(my $i=-3; $i<191997;) {
		my $v = 0;
		for my $j (0..7) {$v <<= 1; $v |= 1 if $p[$i+=3];}
		push(@cible, $v ^ $ecran[int($i/24)]);
	}
	return 1;
}

# compresse @cible dans $BUFFERSIZE
sub compresse {
	my(@buf) = (0)x$BUFFERSIZE;
	my($ok) = 1;
	my($k);
	my($img_complete) = 0;
	
	my $y1 = (200-$h)>>1 - 255;
	my $y2 = 200-((200-$h)>>1);
	my $max = $y2*40; #8000;
	
	# video
	for(my $i=0; $i<$BUFFERSIZE; $i+=3) {
		$k = 1;
		$pos += ($k=255) if $pos<$y1;
		while($k<255 && !$cible[$pos]) {++$pos;++$k;}
		if($pos>=$max) {
			$img_complete = 1;
			$k = $pos = 0;			
			last;
		}
		$buf[$i+0] = $k;
		$buf[$i+1] = ($ecran[$pos] ^= $cible[$pos]);
		++$pos;
	}
	++$realimg if $img_complete;
	
	# audio
	for(my $i=0; $i<$BUFFERSIZE; $i+=3) {
		if(!@AUDIO) {
			my($buf);
			if(!read(AUDIO,$buf,8192)) {
				$buf[$i+2] = 0xff; # EOF
				$ok = 0;
				last
			}
			push(@AUDIO, unpack('C*', $buf));
		}
		my $v = shift(@AUDIO);
		# volume auto
		$audio_cor[1] = $v if $v<$audio_cor[1];
		$v-=$audio_cor[1];
		$audio_cor[0] = 255/$v if $v*$audio_cor[0]>255;
		$v *= $audio_cor[0];
		# dither audio
		$v += int(rand(3)); $v=255 if $v>255;
		$buf[$i+2] = ($v>>2) | 0x40;
	}
	
	# write
	print OUT pack('C*', @buf);
	
	return $ok;
}

sub guess_zoom {
	my($w, $h) = @_;
	
	# tuyau vers ffmpeg pour images
	open(GOUT,"| ./ffmpeg -i - -v 0 -r 1 -s ${w}x${h} -an $img_pattern");#  -vf format=gray
	binmode(GOUT);

	# fichier video (entree)
	open(GIN, "<$file");
	binmode(GIN);
	unlink(<tmp/img*.bmp>);
	
	# chargement image-magick la 1ere fois
	eval 'use Image::Magick;';

	@ecran = ((0)x8000, 1);
	local $cpt = 1;
	my $size = 0;
	while(&next_image(\*GIN, \*GOUT,$w,$h)) {
		my $pos = 0;
		while(1) {
			my $k = 1;
			while($k<255 && !$cible[$pos]) {++$pos;++$k;}
			last if $pos>=8000;
			$ecran[$pos] ^= $cible[$pos];
			++$pos;
			$size += 3;
		}
		$size += 3;
		print STDERR sprintf("avg %dx%d frame length = %d bytes (%d%%) @ %ds                 \r", $w, $h, int($size/$cpt), int(100*$size/($cpt*$BUFFERSIZE)), $cpt-1);
	}
	unlink(<tmp/img*.bmp>);
	print STDERR "\n";
	my $len_per_img = $size/$cpt * (1.1); # 10% extra
	close(GIN);
	close(GOUT);
	my $zoom = sqrt($BUFFERSIZE/$len_per_img);
	return $zoom;
}
Que donne ce nouvel algo ? Question FPS le fps choisi est toujours respecté a minima et la plupart des vidéo on été automatiquement réduites pour le respecter (10 dans mon cas). Comme prévu par la théorie le facteur zoom trouvé tourne souvent autour de 60% du plein écran ce qui fait des images encore assez lisible. Il faudra que je teste 25fps ce qui va sans doute demander un réduction à plus petit que 50% je pense. Grace à la reduction, la plupart des images sont compressées dans le temps imparti et les vidéos sont très fluides à quelques passages non signifiants pour la moyenne. Certaines vidéos atteignent le FPS désirées en plein écran. C'est typiquement le cas des démos amiga, et pour l'une d'entre-elle (PHENOMENA) le framerate a pu être augmenté de 40% tout en gardant l'image plein-écran. Super! :D

J'ai aussi découvert que quand une image déborde quand même BUFFERSIZE, à cause de l'encodage que j'ai choisi, seule la fin de l'image suivante est rendu, même s'il restait assez de place dans le buffer. Il faudrait qu'au lieu de sortir de la boucle de remplissage quand on atteint le bas de l'image suivante on poursuive par le haut. Il faudra que je ré-écrive cette partie de la compression et comparer le résultat obtenu car du coup la 3eme image ne débutera plus non plus en haut de l'écran. Bref avec cette compression revisitée, un débordement de BUFFERSIZE sur une image n peut entrainer le fait que plusieurs images qui suivent ne démarrent plus en haut de l'écran ce qui fera peut-être très moche. C'est peut-être un cas ou le mieux est l'ennemi du bien. Il faudra expérimenter pour trancher.

Au niveau du contraste sigmoidal adaptatif, je suis perplexe. Le résultat est intéressant et correspond sans doute à ce que tu souhaitais Daniel, mais j'aime pas trop l'écrasement (à défaut de saturation) des blancs et des noirs sur certaines vidéos. Mais ce n'est pas le cas pour toutes. Brassens n'a pas ce phénomène et le traitement éclairci de façon très correcte l'image faisant apparaitre des trucs que je ne voyais pas auparavant (rideau arrière). Ca correspond à avoir un point milieu très bas. Pour les démos amiga il apparait parfois un phénomène d'oscillation dans le contraste. De façon synchro avec l'animation au 1er plan, l'arrière plan s'assombri ou s'éclairci. Peut-être que le filtre passe pas ne coupe pas assez bas. Je ne sais pas trop. Ce qui m'ennuie aussi avec cet algo c'est qu'il va être difficile de coder en C faute de primitives de traitement d'image. J'aurais voulu garder l'algo le plus simple possible.

Vidéo de la version d'image-magick avec un gamma linéaire pour voir le résultat sur 21 vidéos: http://dl.free.fr/n5Go0kavp

A noter: j'ai une matrice void-and-cluster 8x8 qui donne de très bon résultats. Meilleurs que la matrice de Bayer à mon avis. Pour en profiter, copier le fichier thresholds.xml dans ~/.magick sous linux ou cygwin. Les curieux verront aussi que j'ai une matrice 128x128 (plusieurs plombes à générer) qui lorsqu'elle est utilisée ne fait plus apparaitre de motif régulier car l'oeuil n'arrive pas à analyser deux tuiles 128x128 cote à cotes. Cette matrice ressemble beaucoup à un tramage par dispersion d'erreur, mais sans ses défauts (rapide, pas d'apparition de vers, parallélisable).

Au fait quand je parlais de trucs à tester... je me suis couché avec l'idée que la vidéo en couleur est faisable (ce que l'on savait avec les gifs animé précédents), mais avec une résolution meilleure que 80x50. Enfin en théorie. Il faudra expérimenter.... plus tard.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [Thomson] Vidéo avec son en streaming

Message par 6502man »

J'adore les explications de Sam, c'est clair et bien expliquées :D
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] Vidéo avec son en streaming

Message par __sam__ »

Clair je sais pas, mais je viens de me relire et ya plein de fautes de frappe (le '', paron, pardon le 'd' du clavier fatigue). :roll:
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] Vidéo avec son en streaming

Message par Daniel »

Il y a deux façons de prendre le problème : Choisir des vidéos qui passent bien, comme Simon's Cat ou Brel à l'Olympia en noir et blanc sans trames. C'est la méthode du paresseux, que j'ai adoptée sans hésiter.
Ou alors prendre toutes les vidéos possibles et trouver le moyen de les rendre fluides tout en conservant le maximum de nuances. C'est la méthode du perfectionniste choisie par __sam__.
Je m'incline, devant sa ténacité et la qualité du résultat obtenu : sans avoir encore tout visionné je peux déjà dire que la dernière fournée est encore meilleure que la précédente. Et la prochaine, avec la couleur, est attendue avec impatience :wink:
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
LeGrapyl
Messages : 1228
Inscription : 15 déc. 2013 23:38
Localisation : 34 mais parfois 71...

Re: [Thomson] Vidéo avec son en streaming

Message par LeGrapyl »

Daniel a écrit :C'est la méthode du perfectionniste choisie par __sam__.
+100
Bravo Sam...entre ce boulot de dingue et la recherche intensive de TO8, je te tire mon chapeau :lol: :wink:
Tom la Riboulle, l'homme qui roule en boule !
Répondre