2017-02-17 1 views
0

J'ai prévu d'utiliser OpenGL pour rendre le flux vidéo.glTexImage2D provoque une fuite de mémoire

La première étape que je fais après avoir reçu la première image de la vidéo consiste à allouer un tampon d'octets directs et à y placer tous les fragments de trame. Le ByteBuffer est alloué une seule fois.

directBuffer = ByteBuffer.allocateDirect(frameSize * fragmentCount);

Lorsque tous les fragments de cadre sont en place, je passe le ByteBuffer OpenGL renderer

public ByteBuffer getBuffer() { 
    buffer.rewind(); 
    fragments.stream().forEach((frameFragment) -> { 
     for (byte byteFragment : frameFragment.getFrameData()) { 
      buffer.put(byteFragment); 
     } 
    }); 
    buffer.flip(); 
    return buffer; 
} 

La file d'attente de blocage dans la boucle principale de scène est en attente de cadre pour être prêt et rend alors la scène.

ByteBuffer frame = framesQueue.take();

Après compensation im la scène, la mise en fenêtre et ainsi de suite

  glClear(GL_COLOR_BUFFER_BIT); 
      glColor3f(1, 1, 1); 
      glMatrixMode(GL_PROJECTION); 
      glPushMatrix(); 
      glLoadIdentity(); 
      glOrtho(-480, 480, -270, 270, -1, 1); 
      glPushMatrix(); 
      glViewport(0, 0, 768, 576); 

Quand il est fait, je suis prêt à dessiner un quad texturé sur la scène.

glBindTexture(GL_TEXTURE_2D, glGenTextures()); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 768, 576, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer); 
    glBegin(GL_QUADS); 
    { 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex2f(0.0f, 0.0f); 

     glTexCoord2f(1.0f, 0.0f); 
     glVertex2f(768, 0.0f); 

     glTexCoord2f(1.0f, 1.0f); 
     glVertex2f(768, 576); 

     glTexCoord2f(0.0f, 1.0f); 
     glVertex2f(0.0f, 576); 
    } 
    glEnd(); 

Le programme est en cours d'exécution, la vidéo est assez lisse et assez faible latence (qui était la principale préoccupation)

Le problème est que la méthode

 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 768, 576, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer); 

est à l'origine de mémoire pour fuir .

Le heapspace java semble bien enter image description here

Mais l'utilisation de la mémoire java ne cesse de croître à l'infini. enter image description here

Pour un test, je l'ai fait un commentaire exécution de

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 768, 576, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer); 
méthode

et la fuite de mémoire n'a pas eu lieu. J'ai aussi essayé d'utiliser la méthode drawPixels, qui a également aidé mais je pense que l'utilisation de textures est la voie à suivre ici, pas la méthode drawPixels obsolète.

Comment puis-je résoudre le problème de fuite de mémoire? Alternativement, quels sont les autres, efficaces, façons d'afficher une nouvelle texture sur scène toutes les 40ms. La latence est critique.

+1

Y a-t-il une raison pour laquelle vous générez une nouvelle texture dans chaque image au lieu de simplement télécharger de nouvelles données? De plus, vous ne supprimez pas l'ancienne texture. Comme la vieille texture reste en mémoire, il n'est pas surprenant que la mémoire augmente. – BDL

+0

L'utilisation du même textID et la suppression de la texture après le rendu de chaque image semblent avoir aidé. Est-ce un moyen d'y aller? Edit: En fait, en utilisant seulement 0 comme tex-id, sans même supprimer la texture aidée. – lichoniespi

Répondre

1

Cet appel semblait être un problème

glBindTexture(GL_TEXTURE_2D, glGenTextures()); 

Depuis im juste en utilisant une texture unique l'appel peut être remplacé par

qui empêche OpenGL de créer de nouvelles textures chaque appel.