2017-02-17 4 views
0

Ich plante, OpenGL zu verwenden, um Videostrom zu übertragen.glTexImage2D verursacht Speicherverlust

Erster Schritt, nachdem ich das erste Bild des Videos empfangen habe, wird der direkte Byte-Puffer zugewiesen und alle Rahmenfragmente darin eingefügt. Der ByteBuffer wird nur einmal vergeben.

directBuffer = ByteBuffer.allocateDirect(frameSize * fragmentCount);

Wenn alle Rahmenfragmente an Ort und Stelle sind, bin ich vorbei die ByteBuffer zu OpenGL-Renderer

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

Die Sperr Warteschlange in Schleife Haupt Szene für Rahmen wartet, bereit zu sein, und dann macht die Szene.

ByteBuffer frame = framesQueue.take();

Danach im die Szene löschen, Ansichtsfenster einstellen und so weiter

  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); 

Wenn es fertig ist, im bereit eine strukturierte Quad auf die Szene zu zeichnen.

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(); 

Das Programm läuft, ist das Video ziemlich glatt und hat ziemlich niedrige Latenz (das war das Hauptanliegen)

Das Problem ist, dass Verfahren

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

Speicher verursacht Leck .

Die Java heapspace scheint in Ordnung enter image description here

Aber die Speichernutzung durch Java wächst unendlich. enter image description here

Für einen Test tat i Kommentar Ausführung

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

Verfahren und der Speicherverlust nicht auftreten. Ich habe auch versucht, drawPixels-Methode, die auch geholfen, aber ich denke, dass die Verwendung von Texturen ist der Weg, hier zu gehen, nicht veraltet drawPixels-Methode.

Wie kann ich das Speicherverlustproblem lösen? Alternativ dazu, was sind die anderen, effizienten Möglichkeiten, neue Texturen alle 40ms auf der Bühne anzuzeigen. Latenz ist kritisch.

+1

Gibt es einen Grund, warum Sie in jedem Frame eine neue Textur generieren, anstatt nur neue Daten hochzuladen? Außerdem löschen Sie nicht die alte Textur. Da die alte Textur im Speicher verbleibt, ist es nicht überraschend, dass die Speicherkapazität zunimmt. – BDL

+0

Die gleiche texID zu verwenden und die Textur nach dem Rendern jedes Frames zu löschen, scheint geholfen zu haben. Ist es ein Weg zu gehen? Bearbeiten: Eigentlich nur 0 als Tex-ID verwenden, ohne sogar die Textur zu entlasten. – lichoniespi

Antwort

1

Dieser Aufruf schien ein Problem mit

glBindTexture(GL_TEXTURE_2D, glGenTextures()); 

Da im nur eine einzige Textur verwendet, kann der Anruf

ersetzt werden, dass jeder Anruf von der Schaffung neuer Textur OpenGL verhindert.

Verwandte Themen