IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[VLC] sortie frame buffer


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut [VLC] sortie frame buffer


    J'ai vu que VLC proposait plusieurs sorties pour la lecture d'un fichier. L'une d'entre elle m'intéresse assez, c'est la sortie frame buffer.
    Je suis sous Linux, dans les options le frame buffer est /dev/fb0.

    Je me pose la question de savoir s'il est possible de récupérer cette frame depuis un programme écrit en C++ pour pouvoir la manipuler ? Si oui, quelles fonctions sont nécessaires ?

    Merci bien

  2. #2
    screetch
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int f = open("/dev/fb0");
    read(f, data, size);


    man framebuffer donne kekchose ?

    voila un tuto rapidos

    http://209.85.135.104/search?q=cache...ient=firefox-a

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Excellent merci !

    Je n'avais pas trouvé de tuto jusqu'à présent pour pouvoir récupérer les frames dans ce buffer.

    Tu as répondu efficacement et très rapidement à ma question, merci beaucoup !

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Re salut,

    Bon je viens de m'attaquer au problème, et malheureusement le cache pour le lien sur le tuto de VLC est mort.

    J'ai essayé avec tes méthodes simples en faisant un open sur le frame buffer /dev/fb0.
    Mon soucis c'est que je ne sais absolument pas dans quel format sont les frames dans ce buffer.

    Voici le code que j'ai utilisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     // recuperation de la frame (frameBuffer = fileDescriptor de "/dev/fb0")
     nbBytesReaden = read ( frameBuffer, tempBuffer, TAILLEFRAMEVIDEOYUV ) ;
     // placement de l'offset en début pour lire la nouvelle frame
     lseek( frameBuffer, 0, SEEK_SET ) ;
    Ici TAILLEFRAMEVIDEOYUV est le format d'une frame au format YUY2 soit YCbCr 4:2:2 ( 576 * 720 * 2 octets ). Je peux changer ce format, mais je ne sais absolument pas la taille d'une frame écrite dans le frame buffer par vlc. Et, encore moins pour le son !

    J'ai joué sur une sortie SDI les frames lues (récupérées donc dans "tempBuffer") à l'aide d'un autre programme sur un moniteur, et l'écran reste figé avec des couleurs fluos ! Autant dire que je ne lis pas grand chose ...

    En entrée je lis un fichier .ts (transport stream), avec VLC (sortie en mode "GNU/Linux console framebuffer video output" ). Lorsque je lis la vidéo, je parviens à la visualiser avec le lecteur (sur mon écran pc, de manière classique).
    Sans doute que VLC écrit sur la sortie standard en plus du frameBuffer.

    Quelqu'un a-t-il une idée ?
    Merci d'avance !

    Raph

  5. #5
    screetch
    Invité(e)
    Par défaut
    salut,

    voila une copie du tuto qui marchait bien :

    http://qt.developpez.com/doc/3.3/emb-framebuffer-howto/

    tu verras comment recuperer des infos sur l'ecran et mapper l'image en memoire. Ensuite il "suffit" de lire cette memoire!
    Dernière modification par Deepin ; 01/09/2011 à 09h27.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    merci screetch,

    Je vais tester ça aujourd'hui et je te tiendrais au courant. En tout cas, ce tuto a l'air de répondre exactement à mes attentes !

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Bon,

    je n'ai toujours pas le résultat attendu. Mon écran reste toujours fluo ...
    Mon noyau supporte correctement le frame buffer, J'ai ouvert le buffer /dev/fb0 et mapper en mémoire son contenu partiel. Ensuite j'ai récupéré la frame à partir de cette mémoire pour l'envoyer dans un autre buffer (pour être traité par un autre thread).

    Voici le code du thread chargé de récupéré la frame envoyée par VLC.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
     
    void* threadReaderFrameBuffer ( void* arg ) {
     
     
    	printf ( "[threadReaderFrameBuffer] se lance \n" ) ; 
    	threadReaderFrameBufferIsWorking = true ;
     
    	// ouverture du frame buffer
    	int frameBuffer = open ( "/dev/fb0", O_RDONLY ) ;
    	if ( frameBuffer == -1 ) {
    		perror ( "Erreur a l'ouverture du frameBuffer de VLC \n" ) ;
    		exit ( 1 ) ;
    	}
    	printf ( "Ouverture du frameBuffer de VLC avec succes \n" ) ;
     
    	// frame courante
    	unsigned char* currentFrame = NULL ;	
     
    	while ( ( currentFrame = ( unsigned char* ) mmap ( 0, TAILLEFRAMEVIDEOYUV, PROT_READ, MAP_SHARED, frameBuffer, 0) ) != ( void* ) -1 ) {
     
    		// on replace l'offset sur le debut du buffer
    		lseek( frameBuffer, 0, SEEK_SET ) ;
     
    		// si le buffer YUV est plein, on bloque le thread
    		if ( bufferYUV.size() == NBFRAMEBUFFERYUV ) {
    			threadReaderFrameBufferIsWorking = false ;
    			printf ( "[threadReaderFrameBuffer] se bloque \n" ) ; fflush ( stdout ) ;
    			pthread_cond_wait( &conditionYUV_cond, &conditionYUV_mutex ) ;
    		}
     
    		// on envoit la frame lue dans le buffer YUV
    		pthread_mutex_lock ( &conditionYUV_mutex ) ;
    		bufferYUV.push ( currentFrame ) ;
    		pthread_mutex_unlock ( &conditionYUV_mutex ) ;
     
    		// si le  buffer YUV etait vide, on reveille le thread AJA
    		if ( bufferYUV.size () == 1 ) {
    			AJAThreadIsWorking = true ;
    			printf ( "[AJA] se reveille \n" ) ; fflush ( stdout ) ;
    			pthread_cond_broadcast( &conditionYUV_cond ) ;
    		}
    	} // fin boucle de lecture
     
    	// on a fini de lire toutes les donnees depuis le buffer
    	threadReaderFrameBufferIsWorking = false ;
    	threadReaderFrameBufferEnd = true ;
    	printf ( "[threadReaderFrameBuffer] a termine \n" ) ;
     
    }
    Voilà, vos avis sont les bienvenus.
    Je ne sais pas si on doit mapper en mémoire le frame buffer pour chaque frame, ( je découvre pour la première fois cette fonction mmap ).
    Je ne sais pas non plus le format des frames écrites dans /dev/fb0 par VLC, si quelqu'un le connait ce pourrait être un détail intéressant.

    Merci d'avance,
    Raph.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    petite précision,

    lorsque je joue sur la sortie frame buffer de VLC, le lecteur semble figé. Cette fois ci il ne sort pas sur la sortie standard la vidéo que je lis.
    Pour le quitter je suis obligé de le "forcer à quitter" (ou en le killant).

  9. #9
    screetch
    Invité(e)
    Par défaut
    En fait mmap est une fonction magique qui va "mapper" (d'ou le nom) le framebuffer dans ta memoire.

    Une fois que tu as mappé le fichier en mémoire,

    void* frame = mmap(framebuffer, SIZEOFFRAMEUFFER, 0); ... je sais plus trp la syntaxe

    dans frame tu auras toujours la frame. Le fichier est maintenant "en memoire", si tu ecris dedans ca ecrira dans l'ecran et si tu lis ca lis l'ecran. Donc tu n'as plus besoin de reouvrir le fichier (mais ne le ferme pas par contre ! ) ni de remapper le fichier ni de rembobiner le fichier.

    Ce que je te conseille :
    - ouvre le fichier
    - mappe le en memoire
    - le mapping devient exactement l'ecran, quand quelque chose sera ecrit dedans cela sera reflete en memoire, et si tu ecris quelque chose dedans cela va l'afficher a l'ecran



    ensuite ne remappe plus le fichier, jamais! il va te suffir de lire la memoire pour obtenir la reame et d'ecrire en memoire pour afficher.

    Je ne sais pas si je suis tres clair ^^

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    merci screetch,

    je m'étais rendu compte de ces points dernièrement en faisant des tests.
    Par contre, comme tu le dis le frame buffer /dev/fb0 contient ce qui a à l'écran ... je pensais que lorsqu'on spécifiait à VLC cette sortie il écrivait dedans, et donc que le contenu de ce buffer serait la vidéo lue (y compris avec le son).

    Enfin, je vais faire une lecture plein écran et lire à partir de cette mémoire mappée et je vais voir ce que ça donne.

    merci bien !

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Bon,

    j'ai fait plusieurs fonctions pour récupérer l'image qui se trouve dans le buffer /dev/fb0 en supposant qu'il s'agisse de l'image de l'écran.

    Je ne connais absolument aucunes informations sur la taille et le format de ces images, Cependant en faisant un cp /dev/fb0 (capture d'ecran à partir du buffer), j'ai récupéré un fichier de taille 1,5 mo. Ce qui correspondrait pour moi à du 1024 * 768 au format YUY2, pour la capture d'écran.
    Par contre, ça m'étonne beaucoup car ma résolution de l'écran est 1280 * 1024 et que je pensais que le format des images affichées sur un écran LCD était du RGB...

    A partir de ce point, j'ai mappé le buffer /dev/fb0 pour récupérer l'image de l'écran. J'ai ensuite fait quelques fonctions pour convertir cette image 1204 * 768 en 720 * 576 pour les envoyer a une carte d'acquisition vidéo et les jouer sur un moniteur.

    Mon soucis c'est que j'ai toujours un truc très moche à l'écran. Je m'attendais à voir mon écran d'ordinateur sur le moniteur ...

    Voici le code du thread qui récupère les images depuis le buffer et qui les traite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    void* threadReaderFrameBuffer ( void* arg ) {
     
    	printf ( "[threadReaderFrameBuffer] se lance \n" ) ; 
    	threadReaderFrameBufferIsWorking = true ;
     
    	// ouverture du frame buffer
    	int frameBuffer = open ( "/dev/fb0", O_RDONLY ) ;
    	if ( frameBuffer == -1 ) {
    		perror ( "Erreur a l'ouverture du frameBuffer de VLC \n" ) ;
    		exit ( 1 ) ;
    	}
    	printf ( "Ouverture du frameBuffer de VLC avec succes \n" ) ;
     
    	// frame recuperee sur le frame buffer
    	unsigned char* frameVLC = ( unsigned char* ) mmap ( 0, 1024 * 768 * 2, PROT_READ, MAP_SHARED, frameBuffer, 0) ;
     
    	while ( frameVLC != ( void* ) -1 ) {
     
    		// allocation d'une frame video qu'on envoit dans le buffer YUV
    		unsigned char* currentFrame = ( unsigned char* ) malloc ( 1024 * 768 * 2 ) ;
    		// posix_memalign ( ( void** ) &currentFrame, 4096, 1024 * 768 * 2 ) ;
     
    		// recopie du contenu du frameBuffer VLC dans cette frame
    		memcpy ( ( void* ) currentFrame, ( void* ) frameVLC, 1024 * 768 * 2 ) ;
     
    		// currentFrame pointe sur l'image de la capture d'ecran en 1024 * 768 YUY2
     
    		// on l'a convertit en 1024 * 768 RGB 
    		currentFrame = YUY2toRGB ( 1024, 768, currentFrame ) ;
     
    		// on la filtre pour obtenir une image 720 * 576 RGB 
    		currentFrame = gaussianFilter ( currentFrame ) ;
     
    		// on convertit cette image filtree au format YUY2
    		// currentFrame = RGBtoYUY2 ( 720, 576, currentFrame ) ;
     
    		// currentFrame pointe sur une image allouee par posix_memalign en 720 * 576 YUY2 lisible par la carte AJA
     
    		// si le buffer YUV est plein, on bloque le thread
    		if ( bufferYUV.size() == NBFRAMEBUFFERYUV ) {
    			threadReaderFrameBufferIsWorking = false ;
    			printf ( "[threadReaderFrameBuffer] se bloque \n" ) ; fflush ( stdout ) ;
    			pthread_cond_wait( &conditionYUV_cond, &conditionYUV_mutex ) ;
    		}
     
    		// on envoit la frame lue dans le buffer YUV
    		pthread_mutex_lock ( &conditionYUV_mutex ) ;
    		printf ( "[threadReaderFrameBuffer] envoi d'une frame dans le buffer YUV ... " ) ; fflush ( stdout ) ;
    		bufferYUV.push ( currentFrame ) ;
    		printf ( "ok \n" ) ; fflush ( stdout ) ;
    		pthread_mutex_unlock ( &conditionYUV_mutex ) ;
     
    		// si le  buffer YUV etait vide, on reveille le thread AJA
    		if ( bufferYUV.size () == 1 ) {
    			AJAThreadIsWorking = true ;
    			printf ( "[AJA] se reveille \n" ) ; fflush ( stdout ) ;
    			pthread_cond_broadcast( &conditionYUV_cond ) ;
    		}
    	} // fin boucle de lecture
     
    	// on a fini de lire toutes les donnees depuis le buffer	
    	threadReaderFrameBufferIsWorking = false ;
    	threadReaderFrameBufferEnd = true ;
    	free ( frameVLC ) ;	
    	printf ( "[threadReaderFrameBuffer] a termine \n" ) ;
    	exit ( 1 ) ;
     
    }
    j'ai des fonctions qui permettent de changer d'espace colorimétrique entre RGB et YUY2. Sinon, gaussianFilter est une petite fonction permettant de passer d'une image RGB 1024 * 768 à la résolution 720 * 576 en applicant un filtrage sur la majorité des pixels.

    Quelqu'un a-t-il une aidé de ce qui pourrait clocher ?

    Merci d'avance !
    Raph.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    petit up, personne n'a une idée ?

Discussions similaires

  1. Utilisation du frame buffer avec Nvidia
    Par HNT dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 05/07/2006, 12h47
  2. format frame buffer
    Par jeremieLuminy dans le forum OpenGL
    Réponses: 9
    Dernier message: 22/04/2006, 09h50
  3. Frame Buffer
    Par nicolaskarp dans le forum Linux
    Réponses: 3
    Dernier message: 20/03/2006, 04h11
  4. Frame buffer object
    Par Pen² dans le forum OpenGL
    Réponses: 6
    Dernier message: 14/11/2005, 10h17
  5. Linear Frame Buffer
    Par Neo82 dans le forum Assembleur
    Réponses: 10
    Dernier message: 01/03/2003, 21h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo