[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__ »

Une curiosité, j'ai utilisé la matrice de tramage void-and-cluster 8x8 suivante

Code : Tout sélectionner

       <threshold map="vac-8">
                <description>void and cluster 65 niveaux</description>
                <levels width="8" height="8" divisor="65">
			62 23 51 26 7 58 10 19
			8 35 14 61 41 20 36 46
			28 53 39 4 30 49 2 60
			42 11 22 56 15 55 25 17
			6 63 47 34 45 9 33 52
			38 27 16 5 24 64 43 21
			13 54 32 59 37 18 1 57
			40 3 44 12 48 29 50 31
                </levels>
        </threshold>
Ca donne ceci
Image
qui se rapproche d'une dispersion tout en gardant une régularité par bloc 8x8. La régularité se voir bien sur les basses intensités.

Sur un film ca peut rendre pas mal
Image
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 »

Dans les années 80, qui aurait imaginé qu'on puisse afficher une vidéo plein écran sur Thomson, à 25 images par seconde, avec le son numérique en cerise sur le gâteau...

Pour la suite, comment fait-on ?
- Les .bmp sont uploadés à OVH (voir le lien quelques posts plus haut)
- Sam, si tu veux, je peux te passer la piste audio et le programme de génération du fichier .sd
- Je peux aussi faire moi-même une nouvelle version de la vidéo si tu m'envoie les images toutes prêtes
- Les fichiers .sd peuvent être testés avec dcmoto
- Quand ils seront finis, je les testerai sur les vraies machines (MO et TO)
- Je publierai bientôt la version finale de mon bricolage arduino, réalisable par un enfant de 10 ans sans aucune soudure

Quand tout sera au point, il restera à choisir les bons films pour en faire une version Thomson :wink:
Et n'oublions pas qu'il reste à faire la même chose en couleur...
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__ »

Vu le volume, pour l'instant je ne vais pas pouvoir les récupérer tout de suite. Le script que je bricole s'arrange justement pour produire les images à la volée et n'utilise que quelques Ko sur disk (il utilise ffmpeg et des pipes, l'équivalent de la fonction popen() en C posix), et avec tes explications je pense pouvoir maquetter la compression assez rapidement.
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 »

Ci-dessous le programme de génération du fichier .sd à partir du son et des images :

Code : Tout sélectionner

//=============================================================================
// SDANIM3.C - Conversion fichiers bmp et raw en sequence video pour sdanim3
//             Daniel Coulom - Juin 2015
//=============================================================================

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define YDEB 0          //premier octet de l'image
#define YFIN 8000       //dernier octet de l'image + 1

//Pour 25 images par seconde
//645 echantillons de son 16125Hz pour chaque image
//3 * 645 = 1935 (2 octets video et un octet son) pour 645 echantillons par image

#define BUFFERSIZE 1935

FILE *fcf;
FILE *fbmp;
FILE *fraw;
int buffer[BUFFERSIZE];  //buffer pour une image
int ecran[8000];         //image telle qu'affichée a l'ecran
int cible[8000];         //image reelle lue dans le fichier
int y;                   //pointeur dans l'image

/*
PRINCIPE:
Dans chaque bloc de BUFFERSIZE octets du fichier .sd on stocke les differences
entre l'image actuelle et l'image precedente, avec un echantillon son entre
deux différences. Chaque difference est codee sur deux octets:
deplacement par rapport a la difference precedente (1-255) et nouvel octet
remplacant celui de l'image precedente. S'il y a plus de 255 octets entre deux
differences, de fausses differences intermediaires sont generees.
S'il y a plus de BUFFERSIZE / 3 differences les suivantes sont ignorees. Le
rattrapage sera effectue dans les images suivantes. Pour cela, il faut stocker
a chaque etape l'image obtenue, car elle peut être differente de l'image reelle.
ASTUCES:
- on commence a la premiere ligne affichee (Y = YDEB)
- on termine a la derniere ligne affichee (Y < YFIN)
La debut d'image est indiquee par un increment 0 et le premier octet de l'image
*/

//Revenir au debut de l'ecran /////////////////////////////////////////////////
void Ecran(int i)
{
 y = YDEB;
 buffer[i] = 0;
 ecran[y] = cible[y];
 buffer[i + 1] = cible[y];
 y++;
}

//Affichage d'une image //////////////////////////////////////////////////////
void Image()
{
 int i; //index sur un groupe de 3 octets (deplacement, image, audio)
 int k; //distance a la difference precedente, de 1 a 255

 for(i = 0; i < BUFFERSIZE; i += 3)
 {
  //revenir au debut de l'ecran si toute l'image est balayee
  if(y >= YFIN) {Ecran(i); continue;}
  //recherche de la premiere difference
  //k varie de 1 a 254 pour les differences reelles
  //a defaut de difference reelle, k vaut 255 pour une difference fictive
  for(k = 1; k < 255; k++)
  {
   if(cible[y] != ecran[y]) break; //difference detectee
   if(++y >= YFIN) break; //fin d'une image
  }
  //affichage d'un nouvel ecran
  if(y >= YFIN) {Ecran(i); continue;}
  //stockage de la difference dans le buffer
  buffer[i] = k;            //deplacement dans l'image
  buffer[i + 1] = cible[y]; //nouvel octet dans l'image
  ecran[y] = cible[y];      //stockage de l'octet
  y++;
 }
 //ajout de l'audio (un octet sur trois)
 //chaque echantillon doit être dans l'intervalle $40-$7F
 for(i = 2; i < BUFFERSIZE; i += 3)
 {
  k = fgetc(fraw);
  k |= 0x40;       //bit acknowlege positionne pour sdanim3
  if(k == EOF) {buffer[i] = 0xff; continue;}
  if(k > 0x7f) {buffer[i] = 0x7f; continue;}
  if(k < 0x40) {buffer[i] = 0x40; continue;}
  buffer[i] = k;
 }
 //ecriture du buffer
 for(i = 0; i < BUFFERSIZE; i++)
 fputc(buffer[i], fcf);
}

//Generation d'un fichier video //////////////////////////////////////////////
void Video(char *filename, int filenamelength)
{
 int i , j;
 int filenumber;
 char filenameraw[256];
 char filenamebmp[256];
 char filenamecf[256];
 char string[256];
 //nom des fichiers
 sprintf(filenameraw, "audio\\%s.raw", filename);
 sprintf(filenamecf, "%s.sd", filename);
 //initialisation de l'image a blanc
 for(i = 0; i < 8000; i++) ecran[i] = 0;
 //ouverture des fichiers
 fraw = fopen(filenameraw, "rb");
 fcf = fopen(filenamecf, "wb");
 filenumber = 0;
 y = YDEB;
 //boucle de conversion
 while(1)
 {
  //ouverture du fichier bmp
  strcpy(string, "video\\");
  switch(filenamelength)
  {
   case 1 : strcat(string, "%01i"); break;
   case 2 : strcat(string, "%02i"); break;
   case 3 : strcat(string, "%03i"); break;
   case 4 : strcat(string, "%04i"); break;
   case 5 : strcat(string, "%05i"); break;
   case 6 : strcat(string, "%06i"); break;
   case 7 : strcat(string, "%07i"); break;
   default: strcat(string, "%08i"); break;
  }
  strcat(string, ".bmp");
  sprintf(filenamebmp, string, filenumber++);
  printf("Image: %s\n", filenamebmp);
  fbmp = fopen(filenamebmp, "rb");
  if(fbmp == NULL) break;
  //lecture de l'image cible
  fseek(fbmp, 0x3e, SEEK_SET);
  for(i = 199; i >= 0; i--) //de bas en haut
  for(j = 0; j < 40; j++)   //de gauche a droite
  //cible[40 * i + j] = (~fgetc(fbmp)) & 0xff; //lire en inversant les couleurs
  cible[40 * i + j] = fgetc(fbmp) & 0xff; //lire sans inverser les couleurs
  //fread(cible, 8000, 1, fbmp);
  fclose(fbmp);
  //traitement de l'image
  Image();
 }
 //fin du programme
 for(i = 0; i < BUFFERSIZE; i += 2)
 {
  fputc(0x00, fcf);
  fputc(0xff, fcf);
 }
 fclose(fcf);
}

//Programme principal ////////////////////////////////////////////////////////
int main()
{
 //parametres: nom du fichier, nombre de chiffres du nom de fichier .bmp
 //exemple: 4 pour 0000.bmp, 0001.bmp, ..., nnnn.bmp
 //les fichiers .bmp sont dans le sous-repertoire video\ 
 //la numerotation commence a zero. Le premier bmp est totalement noir.
 //le fichier son est dans le sous-repertoire audio\
 //brassens.raw 16125 echantillons par seconde 8 bits mono 
 Video("brassens", 4); 
 system("pause");
 return 0;
}
Daniel
L'obstacle augmente mon ardeur.
Fool-DupleX
Messages : 2284
Inscription : 06 avr. 2009 12:07

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

Message par Fool-DupleX »

Cette matrice void&cluster même si elle me semble avoir un leger defaut, rend vachement bien. Je pense que sur un tube cathodique avec la vitesse de l'animation, le resultat percu doit encore être meilleur (remanence).

Par contre, je suggere de compresser (au sens spectral, i.e. sur la courbe des gris) la video de maniere a eviter les tons en saturation, que ce soit vers le noir ou le blanc ; ex: dans la video star wars, certaines scenes sont trop foncées et donnent un ecran quasiment entierement noir une fois tramé.

Pour faire les choses correctement, il faut tramer un degradé horizontal, faire un flou gaussien de l'image obtenue; le rayon du flou gaussien devrait être calcule pour tenir compte approximativement de la distance entre l'ecran et l'observateur. Ensuite on soustrait cette image de l'original, on determine le delta d'erreur pour chaque niveau de gris et on construit une courbe de correction qu'on utilisera comme filtre gamma sur chaque frame juste avant le tramage. l'image originale filtrée aura parfois l'air degueu, mais le resultat tramé sera bien meilleur. il faut en effet se souvenir que la qualité des gris depend directement de la matrice de tramage et que le gamma de l'image est deformé par la matrice. Enfin pour eviter les saturations dans l'extreme, on peut ajouter une compression simple (ex: 0..255 -> 10..245) pour eliminer totalement les scenes trop saturees.

Et si vous etes vraiment fou et d'ailleurs la puissance de calcul actuelle le permet, au lieu de prendre un degrade, vous faites le calcul d'erreur sur chaque frame et vous construisez une courbe de correction specifique a chaque frame. La question que je me pose dans ce cas, c'est est-ce qu'il n'y aura pas des variations de luminosite parasites.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

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

Message par Daniel »

Nous sommes partis sur un sujet passionnant, mais difficile. D'autant plus que le résultat est largement subjectif, et qu'il y a beaucoup d'approches différentes sans qu'aucune surclasse toutes les autres.

N'oubliez pas un paramètre important : pour une animation fluide, il faut minimiser les différences entre deux images successives. La saturation des blancs et des noirs contribue à la réduction de ces différences. En la supprimant on améliore le rendu, mais on risque de pénaliser la vitesse d'affichage.
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 d'ailleurs il serait intéressant de savoir combien d'images se dessinent dans le temps imparti pour savoir si on tient bien les 25fps ou pas.

Ca doit revenir à calculer le nb moyen d'octets écrits sur le stream SD entre deux appels à Ecran(i) et de le diviser par le nb d'octets théoriques pour décrire une image (645*2 si j'ai bien compris le code). Si le ratio tourne autour de 2x ca veut die qu'on est au final plus proche de 12fps que de 25.

A noter: 12fps c'est pas si ridicule que ca. (Mes gifs sont à 11fps et personne n'a vu si c'était saccadé.)
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__ »

J'ai fini mon script

Code : Tout sélectionner

#/bin/perl

#use Graphics::Magick;

$file = $ARGV[0];

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


$BUFFERSIZE = 3*$hz/$fps;

# recherche la taille de l'image
open(IN, "./ffmpeg -i \"$file\" 2>&1 |");
while(<IN>) {
	if(/, (\d+)x(\d+)/) {
		my($x,$y) = ($1, $2);
		print $file," : ${x}x${y}";
		# 4:3
		if(abs($x - 4/3*$y) < abs($x - 16/9*$y)) {
			($w,$h) = (266,200);
		}
	}
}
close(IN);
$w = int($w*$zoom+31)&~31;
$h = int($h*$zoom+3)&~3;
print " -> ${w}x${h}\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,"| ./ffmpeg -i - -v 0 -r $fps -s ${w}x${h} -an $img_pattern");#  -vf format=gray
binmode(FFMPEG);

# fichier video (entree)
open(IN, "<$file");
binmode(IN);
unlink(<img*.bmp>);

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

# chargement image-magick la 1ere fois
eval 'use Image::Magick;';

# compteur image
$cpt = 1;

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

# position dans ecran
$pos = 7999;

# compression
$time = 0; $start = time; $realimg = 0; $pause = 60;
while(&next_image() && &compresse()) {
	if($cpt%$fps == 0) {
		++$time;
		my($d) = time-$start;
		print STDERR sprintf("%d:%02d:%02d (%.1gx) 1:%.3g          \r",
			int($time/3600), int($time/60)%60, $time%60,
			$time/$d, $realimg/$cpt);
		# pour ne pas trop chauffer
		if($d>$pause) {
			$pause += 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(<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 {
	# nom du fichier BMP
	my $name = sprintf($img_pattern, $cpt++);
	
	# taille fichier BMP
	my $expected_size = $h*((3*$w+31)&~31) + 54; # couleur

	# 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 FFMPEG, $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->Set(type=>"grayscale");
	$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]>0;}
		push(@cible, $v);
	}
	return 1;
}

# compresse @cible dans $BUFFERSIZE
sub compresse {
	my(@buf) = (0)x$BUFFERSIZE;
	my($ok) = 1;
	my($k);
	my($img_complete) = 0;
	
	# video
	for(my $i=0; $i<$BUFFERSIZE; $i+=3) {
		for($k=1; 
		    $k<255 && $ecran[$pos]==$cible[$pos] && ++$pos<8000; ++$k) {}
		$img_complete = 1 if $pos>=8000;
		$k = $pos = 0 if $pos>=8000;
		$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);
		# 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;
}
C'est un portage direct de ton code C avec quelques micro-optim permettant de jouer avec plusieurs paramètres comme la vitesse video (25fps par défaut) et la taille de l'image. Il affiche la vitesse d'encodage en Nx (pour en 1 sec de temps d'encodage on encode N images) ainsi qu'une estimation du ratio fps effectif sur fps attendu. Sur un corpus de fichier venant de youtube (mp4, flv) il donne

Code : Tout sélectionner

$ for i in *.mp4 *.flv; do perl conv_sd.pl "$i"; done

Daft Hands - Harder, Better, Faster, Stronger.mp4 : 540x360 -> 288x200
0:03:44 (0.2x) 1:0.818
Daft Punk - Harder Better Faster Stronger.mp4 : 640x360 -> 320x180
0:03:43 (0.2x) 1:0.625
Dire Straits - Calling Elvis.mp4 : 480x360 -> 288x200
0:04:44 (0.2x) 1:0.579
Dire Straits - Money For Nothing.mp4 : 480x360 -> 288x200
0:04:59 (0.2x) 1:0.588
Dire Straits - Private Investigations.mp4 : 480x360 -> 288x200
0:05:46 (0.2x) 1:0.73
Dire Straits - Sultans Of Swing.mp4 : 480x360 -> 288x200
0:04:26 (0.2x) 1:0.375
Eric Prydz - Call on me.mp4 : 640x360 -> 320x180
0:03:00 (0.2x) 1:0.344
Eric Prydz - Pjanoo.mp4 : 640x358 -> 320x180
0:03:08 (0.2x) 1:0.557
Indiana Jones Boulder Scene.mp4 : 640x278 -> 320x180
0:00:27 (0.3x) 1:0.708
Junior Senior - Move Your Feet (Official music video, HD).mp4 : 450x360 -> 288x200
0:03:18 (0.2x) 1:0.648
Kiss Kill - Candy Says.mp4 : 480x360 -> 288x200
0:02:58 (0.2x) 1:0.644
Kylie Minogue - Can't Get You Out Of My Head.mp4 : 554x360 -> 288x200
0:03:47 (0.2x) 1:0.362
Kylie Minogue - Come Into My World [HD].mp4 : 640x360 -> 320x180
0:04:17 (0.2x) 1:0.149
Kylie Minogue - In Your Eyes.mp4 : 626x360 -> 320x180
0:03:16 (0.2x) 1:0.266
Kylie Minogue - Love At First Sight.mp4 : 496x360 -> 288x200
0:03:56 (0.2x) 1:0.358
Kylie Minogue - Spinning Around.mp4 : 640x360 -> 320x180
0:03:30 (0.2x) 1:0.27
Masoud feat. Aneym - No More (Music video))).mp4 : 640x360 -> 320x180
0:04:06 (0.2x) 1:0.976
Michael Gray - The Weekend (Official Video).mp4 : 640x360 -> 320x180
0:03:10 (0.2x) 1:0.353
Star Trek Genesis.mp4 : 480x360 -> 288x200
0:01:04 (0.2x) 1:0.889
Star Wars A New Hope 1977 Trailer.mp4 : 640x360 -> 320x180
0:02:45 (0.2x) 1:0.56
Star Wars Episode V - The Empire Strikes Back Trailer.mp4 : 540x360 -> 288x200
0:03:15 (0.2x) 1:0.864
Star Wars- Return Of The Jedi Trailer (HD).mp4 : 640x360 -> 320x180
0:02:11 (0.2x) 1:0.751
Star Wars The Force Awakens Special Extended Trailer.mp4 : 1280x720 -> 320x180
0:02:28 (0.2x) 1:0.831
THE ABYSS - Trailer ( 1989 ).mp4 : 540x360 -> 288x200
0:02:57 (0.2x) 1:0.868
ZZ Top - Gimme All Your Lovin' (OFFICIAL MUSIC VIDEO).mp4 : 640x360 -> 320x180
0:01:41 (0.2x) 1:0.597
On constate que ca encode lentement (5 sec temps reel = 1 sec de video), mais c'est logique c'est de l'interprété. Par contre on est assez loin du ratio fps 1:1. Cela suggère qu'on a plein d'images thomson mixtes entre 2 ou plus images video. L'effet est en général pas heureux. Je te laisse voir le résultat dans ce fichier ZIP: http://dl.free.fr/niE4tZklG

Nota:
1) suite à expérience avec le son à 5khz et les volumes faibles j'ai ajouté un peu de random dans la gestion du son pour pouvoir entendre les morceaux hyper subtils de Dire Straits.
2) il consome très peu d'espace disk: les images sont générées une à une à la volée et tout passe par des "pipe" entre processus.

L'experience semble indiquer que pour des vidéos généralistes plus fluides, 25fps fullscreen est trop limite. Il vaut mieux descendre à 8-12fps avec un zoom = 70%. (ZIP plus tard: ca encode)
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
Fool-DupleX
Messages : 2284
Inscription : 06 avr. 2009 12:07

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

Message par Fool-DupleX »

vous pouvez me faire un quick up sur comment tester ? j'ai dcmoto derniere version, en mode to8D avec le cs90-280 et le fichier sd chargé et soit basic plante soit il met "file not found", j'ai essaye basic 1 et 512, en automatique et manuel.

merci
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

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

Message par Daniel »

Tu as fait une quantité de vidéo incroyable, il me faudra des heures pour tout visionner !

Ca confirme ce que j'avais déjà constaté : on ne peut pas utiliser n'importe quelle source. La méthode de compression ne supporte pas les changements de plans, ni les travellings. C'est pourquoi j'ai choisi dans mes exemples Brel à l'Olympia et Brassens à Bobino : très fort éclairage sur fond noir, pas trop de changements de plan.

On peut toujours espérer faire mieux en creusant tes idées sur la compression de plusieurs octets consécutifs, pour améliorer la fluidité. Lors d'un changement de plan, je crois qu'il est impossible de supprimer les décrochements. Ou alors, sur TO8 ou MO6, on pourrait préparer l'écran et commuter la page vidéo juste au moment du changement de plan, mais ça me paraît bien compliqué à réaliser dans la pratique.

Il reste quand même quelques sujets qui passent bien, en particulier Simon's Cat (décor fixe et peu d'objets en mouvement). J'ai fait d'autres essais avec Mickey Mouse, mais Disney utilise souvent des travellings pour le décor, et ils passent très mal.

Dans les films comme Indiana Jones ou Star Wars, il y a de bons passages, entrecoupés de décrochements assez désagréables. Même chose dans les clips de chansons. Dire Straits - Sultans of Swing est pas mal (sauf dans les gros plans) grâce au fond noir . Le point positif de tous ces essais est la qualité du son.
Daniel
L'obstacle augmente mon ardeur.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

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

Message par Daniel »

@FoolDuplex :
- dcmoto avec n'importe quel ordinateur (j'utilise le MO5, mais tous sont bons)
- pas de contrôleur (il n'est pas nécessaire de simuler les disquettes sur carte SD)
- dans Supports amovibles sélectionner Interface SDMOTO et Charger/Fichier sur carte SD
- en Basic : Fichier/Simuler le clavier avec le fichier sdanim3_bas.txt (ou le presse-papier) et taper RUN

Code : Tout sélectionner

1 '================================
2 ' SDANIM3
3 '================================
10 SCREEN7,0,0:LOCATE0,0,0:CLS
20 A=&H9000
30 READX$:IFX$="**"THEN99
40 POKEA,VAL("&H"+X$):A=A+1:GOTO30
99 EXEC&H9000:END
100 DATA 34,7F,1A,50,8E,1F,40,E6
101 DATA 84,63,84,E1,84,27,14,63
102 DATA 84,86,A7,1F,8B,96,C0,8A
103 DATA 01,97,C0,8E,00,00,7F,90
104 DATA 52,20,0D,86,E7,1F,8B,96
105 DATA C3,8A,01,97,C3,8E,40,00
106 DATA 4F,5F,DD,CE,C6,7F,DD,CC
107 DATA 8A,04,97,CE,97,CF,84,3F
108 DATA 97,CD,D6,CC,27,07,8A,40
109 DATA 97,CD,3A,20,09,8A,40,97
110 DATA CD,8E,40,00,20,00,84,3F
111 DATA 97,CD,D6,CC,8A,40,97,CD
112 DATA E7,84,84,3F,97,CD,96,CC
113 DATA 97,CD,2A,D2,35,FF,**
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__ »

@fool moi j'ai pris le dernier dcmoto_nouveau: http://dcmoto.free.fr/emulateur/dcmoto_nouveau.zip
mode MO5 sans interface CS (je crois). Jsute mis le fichier SD dans la partie "support ammovible"
Copier/coller le code basic de: http://dcmoto.free.fr/programmes/sdanim ... s_prog.txt avec le menu simuler le clavier
puis "RUN"

Mais ne ne recommande pas les video du ZIP (sauf pour voir les soucis). J'ai commencé à générer en 10fps à 70% et c'est nettement mieux! On a un ratio fps de 1: 0.95 mini, c'est à dire que quasiment toutes les images d'entrées sont compressées dans les 1600 et quelques octets disponible par image :D (c'est l'intéret du fps plsu bas: on a plus d'octets pour encoder l'image, et 10fps ca reste quand même très fluide).

A noter: l'audio à 16khz est vraiment bonne. On devrait pouvoir même descendre un peu. Si on met un octet son pour 3 octets video, ca nous travailler à 12khz pour l'audio. Ca doit toujours être correct et pour la peine on a 2 octets vidéo à recopier au lei d'un seul. Je pense que l'octet x et x+40 seraient des bons candidats. Cela reviendrait à travailler sur 2 lignes en une passe.

L'autre encodage ou les octets<0 indique une recopie texte des n octets à venir serait aussi très prometteur car l'analyse des data montre qu'on a souvent un truc comme deplace-1 valeur deplace-1 valeur deplace-1 sur les lignes qui sont complètement changées. La difficulté de cet encodage est qu'il faut entreméler l'octet son dans le bloc video (1 sur 3) ce qui fait que l'encodage n'est plus régulier. C'est une horreur.

@daniel: je me suis couché à 3h du mat en laissant la machine travailler. Ce matin à mon réveil 4h plus tard elle n'avait pas fini! (ca va être dur au travail aujourd'hui: petits yeux). Le fullscreen est trop demandeur en bande passante. Par contre 70% du fullscreen, soit moitié moins d'octets avec un fps plus bas (12) donne de très très bons résultats vidéos sans les zig-zag bizarres qui se produisent dans les travelling. Normalement le script que j'ai mis dans le zip contient ces paramètres. Si tu as cygwin avec image-magick d'installé, tu peux lancer le script par "perl conv_sd.pl fichier-video.ext" le zip contient aussi ffmpeg.exe à placer à coté du script. Il permet de traiter quasiment tous les fichiers vidéo du marché (avi, mp4, flv, mov etc).

A noter il faudra que je fasse une adaptation automatique du niveau sonore car dans dire-straits c'est vraiment très très bas (1-2 bits qui bougent dans le son).
Dernière modification par __sam__ le 09 juin 2015 11:43, modifié 1 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 »

Faites-moi plaisir, construisez l'interface Arduino pour voir les démos sur un vrai Thomson ! Si vous voulez des conseils pour choisir et assembler les composants, rendez-vous ici : http://forum.system-cfg.com/viewtopic.php?f=18&t=6296
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 devrais recevoir un TO8 (tout court) sous peu et j'ai (à part l'arduino) tous les composants qu'il faut (fiches db9 avec vis, cable dupont (monochrome), etc...). Comme je me suis appercu que mes talents de hardware sont limités, je privilègie, en attendant, le soft. Je trouve que l'emul permet de bien avancer et tester différents encodages. (j'ai toujours en tête de produire des audio/video en couleur!)
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__ »

J'ai pas mal travaillé sur mon script qui est à présent plus rapide (j'encode en x1, temps réel), possède une ampli audio auto-adaptative (parfait pour Dire Straits), utilsie la matrice void-and-cluster définie plus haut dans le fil et utilise une synchro plus maline combiné à un FPS et un ZOOM plus adapté ce qui fait qu'à présent toutes les images tiennes dans BUFFERSIZE: il y a très peu de décrochage de ce que je peux en juger.

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.
#                  
##############################################################################

#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 = 3*$hz/$fps;

# recherche la taille de l'image
open(IN, "./ffmpeg -i \"$file\" 2>&1 |");
while(<IN>) {
	if(/, (\d+)x(\d+)/) {
		my($x,$y) = ($1, $2);
		print $file," : ${x}x${y}";
		# 4:3
		if(abs($x - 4/3*$y) < abs($x - 16/9*$y)) {
			($w,$h) = (266,200);
		}
	}
}
close(IN);
$w = int($w*$zoom+7)&~7;
$h = int($h*$zoom+3)&~3;
print " -> ${w}x${h}\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,"| ./ffmpeg -i - -v 0 -r $fps -s ${w}x${h} -an $img_pattern");#  -vf format=gray
binmode(FFMPEG);

# fichier video (entree)
open(IN, "<$file");
binmode(IN);
unlink(<tmp/img*.bmp>);

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

# chargement image-magick la 1ere fois
eval 'use Image::Magick;';

# 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() && &compresse()) {
	if($cpt%$fps == 0) {
		++$time;
		my($d) = time-$start+.0001;
		print STDERR sprintf("%d:%02d:%02d (%.1gx) v=1:%.3g a=%.1g:%d        \r",
			int($time/3600), int($time/60)%60, $time%60,
			$time/$d, $realimg/$cpt, $audio_cor[0], -$audio_cor[1]);
		# 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 {
	# nom du fichier BMP
	my $name = sprintf($img_pattern, $cpt++);
	
	# taille fichier BMP
	my $expected_size = $h*((3*$w+31)&~31) + 54; # couleur

	# 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 FFMPEG, $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->Set(type=>"grayscale");
	$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;
}
Je suis en train d'encoder pleins de vidéos dont des démos amiga, qu'il est étonnant de voir sur thomson du coup. Vivement demain matin que l'encodage soit terminé de sorte que je puis modifier ce message pour proposer un gros ZIP avec pleins de trucs variés. J'espère que la qualité sera au rendez-vous et similaire sur l'ensemble du corpus à ce que j'obtiens ce soir sur 2-3 exemples choisis.
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
Répondre