Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1009 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  [JAVA] Extrême lenteur pour decoder et afficher un jpeg.

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[JAVA] Extrême lenteur pour decoder et afficher un jpeg.

n°1059717
spiderbana​na
Posté le 25-04-2005 à 14:12:52  profilanswer
 

Je suis en train de concevoir un programme java qui manipule des cameras IP. Celles-ci renvoyent un flux mjpeg, dont j'extrais des tableaux de bytes correspondant chacun à un fichier jpeg.
Le problème c'est que le décodage de ce byte[] est extrêmement lent (~ 100ms pour un petit jpeg de 12ko en 512*512) et fait ralentir toute l'application (conso CPU ~70% pour du 10 fps :/). J'ai testé différentes méthodes et libraries utilisant des méthodes natives pour arriver au même résultat.
Avec jmf et en utilisant le même tableau de byte au départ les performances sont très bonnes, je peux atteindre les 30 fps en gardant des utilisation CPU très faibles <10%.
Comment avoir de si bon résultats sans utiliser JMF ? Quel est le secret de JMF ? Je me remet à vous car ca fait 2 semaines que je craque sur ce problème :(
 
 
 
Je vous montre quand même le code, mais c'est basic ...
 

Code :
  1. private void createimage() {
  2.  Image image = null;
  3.  //m_rawImage correspond au byte[]
  4.  InputStream in = new ByteArrayInputStream(m_rawImage);
  5.  JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
  6.  try {
  7.   try {
  8.    long t1 = System.currentTimeMillis();
  9.    image = decoder.decodeAsBufferedImage();
  10.    System.out
  11.      .println("Time: " + (System.currentTimeMillis() - t1));
  12.   } catch (IOException e2) {
  13.    e2.printStackTrace();
  14.   }
  15.  } catch (ImageFormatException e) {
  16.   e.printStackTrace();
  17.  }
  18.  try {
  19.   in.close();
  20.  } catch (IOException e1) {
  21.   e1.printStackTrace();
  22.  }
  23.  m_imain = image;
  24. }

mood
Publicité
Posté le 25-04-2005 à 14:12:52  profilanswer
 

n°1059923
nraynaud
lol
Posté le 25-04-2005 à 15:33:27  profilanswer
 

spiderbanana a écrit :

et fait ralentir toute l'application (conso CPU ~70% pour du 10 fps :/).


je n'y crois pas. Ta caméra doit simplement être mal réglée (réglée avec un cadence de 10fps).
 
si vraiment le taquet venait du décodage, tu serais à 100%.
 
 
utilise-tu le même code avec JMF et sans JMF pour initialiser la caméra ?


---------------
trainoo.com, c'est fini
n°1060078
spiderbana​na
Posté le 25-04-2005 à 17:31:27  profilanswer
 

En fait j'ai un thread qui tourne en permanance et récupère les images jpeg. J'utilise des callback pour indiquer au SourceStream JMF ou à mon panel qu'un nouvelle image est dispo. Dans le cas de JMF, je lui fait remonter le byte[] et il se debrouille avec ses codec, dans le cas de mon panel je decode moi même le byte[] (en fait dans ce cas là, c'est le thread de production qui va decoder l'image, pour jmf il a son propre thread). Tant que le decodage n'est pas en route j'ai un bon FPS ...
 

Citation :

si vraiment le taquet venait du décodage, tu serais à 100%.


J'ai un peu de mal à trouver des explication pour ca. C'est vrai que c'est étrange. En plus, quand je veux decoder pas mal d'images par secondes ET que je les affiches le temps de decodage varie enormement (passe de 100ms à 0 ms ??!!).


Message édité par spiderbanana le 25-04-2005 à 17:40:06
n°1062478
guinoumi
Posté le 27-04-2005 à 11:23:48  profilanswer
 

Hello,
J'ai le meme souci que toi !!
je voudrais bien connaitre ta solution avec le JMF moi je ne m'en sort pas !
merci d'avance ;)

n°1062787
spiderbana​na
Posté le 27-04-2005 à 14:37:03  profilanswer
 

guinoumi a écrit :

Hello,
J'ai le meme souci que toi !!
je voudrais bien connaitre ta solution avec le JMF moi je ne m'en sort pas !
merci d'avance ;)


 
Je te conseille d'aller voir ici: http://java.sun.com/products/java- [...] Movie.html
Tu y trouveras le code pour faire une vidéo .mov à partie d'images jpeg avec jmf.
Modifie le code et utilise un Player à la place du Processor, vire tout ce qui est utile au processing, et modifie DataStream pour que ca colle avec ton programme.
Bonne chance !

n°1063028
guinoumi
Posté le 27-04-2005 à 16:52:37  profilanswer
 

Pourrais tu m'expliquer ce que tu entend par :
J'utilise des callback pour indiquer au SourceStream JMF ou à mon panel qu'un nouvelle image est dispo!

n°1063080
guinoumi
Posté le 27-04-2005 à 17:16:37  profilanswer
 

De meme j'aimerais savoir comment tu crée ton tableau de byte m_rawImage (moi je detecte les caractere de debut et de fin d'un fichier JPEG :0xffd8 et 0xffd9 car je ne connais pas la taille du fichier a l'avance mais c'est vraiment la galere !!)

n°1063168
spiderbana​na
Posté le 27-04-2005 à 18:01:52  profilanswer
 

guinoumi a écrit :

Pourrais tu m'expliquer ce que tu entend par :
J'utilise des callback pour indiquer au SourceStream JMF ou à mon panel qu'un nouvelle image est dispo!


 
En fait j'utilise le même principe que les evenements en java. En gros ma classe SourceStream implemente un listener (une interface) et la classe qui va chercher les images renseigne tout ses listeners connus qu'une nouvelle image est dispo.
C'est une methode très utilisée en java, fait une recherche sur les interface et les callbacks.
 

Citation :

De meme j'aimerais savoir comment tu crée ton tableau de byte m_rawImage (moi je detecte les caractere de debut et de fin d'un fichier JPEG :0xffd8 et 0xffd9 car je ne connais pas la taille du fichier a l'avance mais c'est vraiment la galere !!)


 
Ben moi je récupère un flux mjpeg, donc je cherche les balises --myboundary pour decouper le flux. Mais c'est vrai que c'est très chiant. Par contre y a la classe StreamTokeniser (chuis pas sûr du nom)  en java qui pourra bien t'être utile.


Message édité par spiderbanana le 27-04-2005 à 18:02:39
n°1063179
spiderbana​na
Posté le 27-04-2005 à 18:07:03  profilanswer
 

Personne d'autre peut m'aider ?

n°1063180
guinoumi
Posté le 27-04-2005 à 18:08:46  profilanswer
 

Merci pour tout ces renseignements je vais essayer de m'en sortir !

mood
Publicité
Posté le 27-04-2005 à 18:08:46  profilanswer
 

n°1063185
spiderbana​na
Posté le 27-04-2005 à 18:10:29  profilanswer
 

guinoumi a écrit :

Merci pour tout ces renseignements je vais essayer de m'en sortir !


Elles viennent d'ou tes images ?

n°1063386
guinoumi
Posté le 27-04-2005 à 21:35:25  profilanswer
 

Mes image viennent de camera IP mais de differentes marque ! et la resolution et la vitesse d'affichage peuvent changer a tout moment !
J'ai regerder la classe StremTokenizer mais c'est plus de l'analyse lexical que "byte a byte" !
c'est donc aussi un flux MJPEG et j'utilise aussi ta methode pour delimiter les images mais je ne vois pas comment les mettre dans un tableau dont je ne peu connaitre la taille a l'avance ?
pour l'instant j"envoyai le flux directement dans  le decodeur  mais je doit sauvgarder les images et la je suis un peu bloquer !

n°1063931
guinoumi
Posté le 28-04-2005 à 10:09:16  profilanswer
 

pourrais tu m'en dire plus sur ron listener que tu as mis sur ta classe DataStream ?
C'est la methode read qui'il faut lancer lorsque une nouvelle image est dispo ?

n°1064093
spiderbana​na
Posté le 28-04-2005 à 12:02:42  profilanswer
 

Code :
  1. /**
  2.  * Retourne si la prochaine lecture sera blocante
  3.  */
  4. public boolean willReadBlock() {
  5.  return block;
  6. }
  7. Object wait = new Object();
  8. /**
  9.  * On bloque tant que la nouvelle image ne sera pas arrivée
  10.  */
  11. boolean waitUnblock() {
  12.  synchronized (wait) {
  13.   try {
  14.    while (block) {
  15.     wait.wait();
  16.    }
  17.   } catch (Exception e) {
  18.   }
  19.  }
  20.  return true;
  21. }
  22. /**
  23.  * Méthode appelée par le processeur (JMF Processor) pour lire la nouvelle image
  24.  *  
  25.  */
  26. public void read(Buffer buf) throws IOException {
  27.  waitUnblock(); //on attent la nouvelle image
  28.  block = true;
  29.  byte[] raw = cam.getRawImage();
  30.  buf.setData(raw);
  31.  buf.setOffset(0);
  32.  buf.setLength(raw.length);
  33.  buf.setFormat(format);
  34.  buf.setFlags(buf.getFlags() | Buffer.FLAG_KEY_FRAME);
  35.   long time = (long) (nextImage * (1000 / format.getFrameRate()) * 1000000);
  36.   buf.setTimeStamp(time);
  37.   buf.setSequenceNumber(nextImage);
  38.  nextImage++;
  39. }
  40. public void imageChanged(ImageChangeEvent ie) {
  41.  {
  42.    synchronized (wait) {
  43.    //System.out.println("CameraSourceStream: image ok" );
  44.     block = false;
  45.    wait.notifyAll();
  46.   }
  47.  }
  48. }


Voilà pour le stream
 
Sinon pour ton flux mjpeg, tu devrais regarde du côté là: http://www.charliemouse.com/code/cambozola/
Il y a absolument toutes les classes nécessaires (et les sources).
Sinon certaines camera envoient aussi la taille de chaques images avant celle ci, c'est un petit raccourci pour parser le flux.
Bonne chance !


Message édité par spiderbanana le 28-04-2005 à 12:06:27
n°1064598
guinoumi
Posté le 28-04-2005 à 17:11:39  profilanswer
 

que faut t'il mettre dans :
public void controllerUpdate(ControllerEvent ce) ???


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  [JAVA] Extrême lenteur pour decoder et afficher un jpeg.

 

Sujets relatifs
afficher une page pendant x seconde puis revenir a la page précédente?[JAVA] Organisation des objets d'une IHM?
[PHP/XML] Afficher en fonction de sa valeur classer ? [maj][JAVA] Transmettre une Socket...
[Java] Le topic-passage-obligé pour débutants !Afficher un groupe
[Java] Outil de gestion de "composants"; GraphEdit "like"[Java/xml] Caractères à la con ds un .xml généré en dom
Cryptage md5 & javaGénération d'images en Java (server side)
Plus de sujets relatifs à : [JAVA] Extrême lenteur pour decoder et afficher un jpeg.


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR