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

Interfaces Graphiques Perl Discussion :

[Perl-GTK2] `mencoder blabla..` prend 100% CPU empechant GTK d'agir


Sujet :

Interfaces Graphiques Perl

  1. #1
    Membre régulier Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Points : 86
    Points
    86
    Par défaut [Perl-GTK2] `mencoder blabla..` prend 100% CPU empechant GTK d'agir
    Bonjour,

    Je ne sait pas d'ou peu venir une solution ( de Perl ? de Gtk ? de bash ?.. ) donc j'ai fini par poster ce message ici. J'espere avoir choisi le forum le plus adapté.

    Bon, je vous expose ma situation et mon probleme (ps: je débute Perl)

    Avec des mots:
    Je fait une mini-GUI pour mencoder pour mon papa. Pour ce faire, je lance la commande mencoder dans perl, et j'en récupère la sortie pour l'examiner et en retirer l'avancement en pourcentage de l'encodage, ceci afin de faire avancer une barre de progression Gtk2::ProgressBar.

    [EDIT : ] je sai pas si ça va être plus clair ou si ça empire :aie: , mais le but c'est d'être plus clair. j'ai fait un super croquis de la mort pour expliquer:


    Avec du code ( très largement épuré )
    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
     
            # La commande de mencoder
            my $cmd = "nice -19 mencoder "		
    		."-ovc xvid -xvidencopts fixed_quant\=$videoBitrate "
    		."-oac mp3lame -lameopts abr\=$audioBitrate "
    		."\"$inpFile\" -o \"".$outDir."/".$outFile."\"";
     
            # transforme la ligne ou y'a le % qui change en plusieurs lignes pour utiliser avec <>
    	my $c = "$cmd | tr '\\r' '\\n' | grep 'Pos:' | ";
     
            # $progressBar est le widget Gtk2::progressBar
    	Gtk2->grab_add($progressBar);
    	open (COMMAND,$c);
    	select COMMAND; $|=1;
     
    	# Bar de progression
    	while (<COMMAND>) {
                    # je récupere le % dans la ligne sortie de mencoder
    		$_ =~ /\(((\s|[0-9])[0-9])\%\)/;
    		my $n = $1/100.;
                    # Si le % a changé
    		if (!($n==$percent)) {
    			$percent = $n;
    			$progressBar->set_fraction($n);
    			$progressBar->set_text($1.'%');
                            # je rend la main a Gtk2 le temps qu'il mette a jour la barre
    			Gtk2->main_iteration_do(TRUE);
    		}
    	}
    	$progressBar->set_fraction(1.);
    	$progressBar->set_text('Termine');
    	Gtk2->grab_remove($progressBar);


    Probleme

    Sur des petites vidéo, aucun probleme. Ca marche niquel.
    Sur des grosses vidéo (DV, genre +1Mb/s) mencoder encode sans probleme, mais il ne laisse aucune place à Gtk2 pour mettre a jour la barre de progression qui du coup passe de 0 à 100% quasiment d'un coup une fois l'encodage terminé.
    J'ai bien éssayé de foutre un "nice -19" devant la commande de mencoder, mais rien n'y fait.

    Une idée ? une Piste ?
    PS: Les fork() seraient-ils une solution ? ( mais ça a l'air un peu plus lourd a programmer .. )

    Merci par avance.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 41
    Points
    41
    Par défaut
    Salut,

    Tu devrais regarder du coté de l'autoflush ($++), voilà un bout de code qui permet juste d'affiché toute la ligne de mencoder ou il y a les info sur l'avencement de l'encodage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $|++; 					# Active l'autoflush
    my $pipe_1 = new IO::Pipe(); 
    	$pipe_1->reader("mencoder $dvd_1 $chemin $dvd_2$dvd_3 -of rawvideo -ovc x264 -x264encopts bitrate=$bitrate:pass=1:subq=4:8x8dct:me=dia:frameref=5:bframes=2:b_pyramid:weight_b:direct_pred=auto:partitions=all:qcomp=0.75:ip_factor=1.10:pb_factor=1.40$threads -vf crop=$crop -nosound -o /dev/null");
    	{ 
    		local $/ = "\r"; 
    		while( defined( my $line = $pipe_1->getline ) ) {
    			print $1 if $line =~ m/(Pos.*\r)$/;
    		}
    	}
    Sans l'autoflush, ca merdouille complet (ce n'est pas assez "rafraichi")

    Jjeje007

  3. #3
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Jjeje007
    Cette ligne est peut être importante également, je ne suis pas sûr du tout que sans ça Perl ne considère pas l'ensemble des "mises à jour du pourcentage" comme une immense ligne unique.

    --
    Jedaï

  4. #4
    Membre régulier Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Points : 86
    Points
    86
    Par défaut
    ah. je vai essayer avec l'autoflush ( ps: IO :: Pipe() est dans la distribution "core" de perl ou dans le CPAN ? enfin bref, j'vous pose la question mais je vai regarder moi-même )
    Par contre le sert a quoi ?
    J'ai aussi jeté un coup d'oeils aux sources d'AcidRip et j'ai croisé Gtk2->events_pending() utilisé quand la main est donné a Gtk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (Gtk2->events_pending() ) { Gtk2->main_iteration() }.
    Je vai essayer aussi.

    Merci bcp pour vos réponses; je revien dès que j'ai essayé tout ça.

  5. #5
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par knoodrake
    Par contre le sert a quoi ?
    Il sert à dire à Perl de lire avec <> uniquement jusqu'au prochain "\r" (le défaut est "\n", de façon à ce que <> lise ligne par ligne), qui est le caractère émis par mencoder entre deux mises à jour du pourcentage.

    --
    Jedaï

  6. #6
    Membre régulier Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Points : 86
    Points
    86
    Par défaut
    ah oui ok. ca remplace le "tr" que j'ai mis moi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	my $c = "$cmd | tr '\\r' '\\n' | grep 'Pos:' | ";

  7. #7
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    A priori, la manière "propre" c'est d'utiliser les "IO channels" de GLib, comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Glib::IO->add_watch(\*COMMAND,
               in => sub { local $_ = <COMMAND>);
                    # je récupere le % dans la ligne sortie de mencoder
    		$_ =~ /\(((\s|[0-9])[0-9])\%\)/;
    		my $n = $1/100.;
                    # Si le % a changé
    		if (!($n==$percent)) {
    			$percent = $n;
    			$progressBar->set_fraction($n);
    			$progressBar->set_text($1.'%');
    		}
    	});
    Essaie, peut-être cela améliorera-t-il les choses.

    --
    Jedaï

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par Jjeje007 Voir le message
    Salut,

    Tu devrais regarder du coté de l'autoflush ($++), voilà un bout de code qui permet juste d'affiché toute la ligne de mencoder ou il y a les info sur l'avencement de l'encodage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $|++; 					# Active l'autoflush
    my $pipe_1 = new IO::Pipe(); 
    	$pipe_1->reader("mencoder $dvd_1 $chemin $dvd_2$dvd_3 -of rawvideo -ovc x264 -x264encopts bitrate=$bitrate:pass=1:subq=4:8x8dct:me=dia:frameref=5:bframes=2:b_pyramid:weight_b:direct_pred=auto:partitions=all:qcomp=0.75:ip_factor=1.10:pb_factor=1.40$threads -vf crop=$crop -nosound -o /dev/null");
    	{ 
    		local $/ = "\r"; 
    		while( defined( my $line = $pipe_1->getline ) ) {
    			print $1 if $line =~ m/(Pos.*\r)$/;
    		}
    	}
    Sans l'autoflush, ca merdouille complet (ce n'est pas assez "rafraichi")

    Jjeje007
    Bonjour.

    Je ne vois pas ce qui dans la ligne de code suivante permet d'afficher toute la ligne de sortie de mencoder ("Pos:..."):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mencoder $dvd_1 $chemin $dvd_2$dvd_3 -of rawvideo -ovc x264 -x264encopts bitrate=$bitrate:pass=1:subq=4:8x8dct:me=dia:frameref=5:bframes=2:b_pyramid:weight_b:direct_pred=auto:partitions=all:qcomp=0.75:ip_factor=1.10:pb_factor=1.40$threads -vf crop=$crop -nosound -o /dev/null
    Est-ce que quelqu'un peut, s'il lui plaît, la réécrire de façon minimaliste?

    Je précise que j'ai le même problème que knoodrake (mais avec un autre langage de script). Si seulement je pouvais récupérer toutes les sorties "Pos:"...

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 50
    Points : 41
    Points
    41
    Par défaut
    Salut,

    Ce n'est pas la ligne que tu cites qui fait le bouleau, c'est l'expression régulière plus bas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $line =~ m/(Pos.*\r)$/;
    Jjeje007

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par Jjeje007 Voir le message
    Salut,

    Ce n'est pas la ligne que tu cites qui fait le bouleau, c'est l'expression régulière plus bas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $line =~ m/(Pos.*\r)$/;
    Jjeje007
    Salut Jjeje007. Merci pour ta réponse.

    Ça aurait pu m'aider si j'avais activé la notification des réponses par email. Je croyais l'avoir déjà fait il y a longtemps.

    Effectivement, les caractères importants dans la ligne que tu cites sont '\r'.
    J'essayais de récupérer des lignes finissant par '\n' au lieu de récupérer des chaînes de caractères finissant par '\r'. Au final je ne pouvais utiliser qu'un nombre très faible de chaînes de caractères 'Pos:...' et plus précisément de % de progression.

    J'ai longtemps cru qu'une option particulière de mencoder pouvait arranger cela.

    En tout cas je peux maintenant faire fonctionner correctement une barre de progression de mencoder.

  11. #11
    Membre régulier Avatar de knoodrake
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 86
    Points : 86
    Points
    86
    Par défaut
    J'ai presque 1 an de retard, mais j'avai fini par abandoné, et la, je me suis remis le nez dans une situation similaire et j'ai fini par trouver la solution a mon problème, ceci grâce aux bonnes indications de Jedai sur les IO Chanels.
    Je suis revenu poster ma solution car j'ai eu un mal fou à me renseigner la dessus sur le net.
    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
     
    my $c = 'ma commande';
    open our $fh, '-|', $c; 
    our $watch = Gtk2::Helper->add_watch( fileno($fh), in => \&foo );
     
    # ... code ...
     
    sub foo {
      our $tag;
      our $fh;
      local $_ = <$fh>;
     
      # ... code ...
      # comme par exemple:
      $ProgressBar->pulse;
     
      if(eof($fh)) {
          Gtk2::Helper->remove_watch($tag);
      }
    }
    à réussi

    Ps: a noter qu'on peu faire exactement la même chose sans Gtk2::Helper en utilisant Glib::IO ( de toute manière, Gtk2::Helper n'étant qu'un "raccourcis" si je puis dire )

Discussions similaires

  1. Gdb prend 100% de CPU avec Netbeans
    Par ads59 dans le forum NetBeans
    Réponses: 3
    Dernier message: 12/11/2009, 10h58
  2. svchost.exe prend 100% de la charge du uc
    Par aaron4444 dans le forum Windows XP
    Réponses: 2
    Dernier message: 17/09/2006, 15h40
  3. [VC Express] 100% CPU - désactiver intellisense
    Par xterminhate dans le forum VC++ .NET
    Réponses: 4
    Dernier message: 10/07/2006, 11h07
  4. msn prend 100% du CPU
    Par ogenki dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 02/05/2006, 15h12
  5. [mySQL]Requete qui prend 100 % du CPU et n'aboutit pas
    Par LE NEINDRE dans le forum Requêtes
    Réponses: 20
    Dernier message: 12/10/2005, 10h36

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