Ich versuche, Effekte auf die Frames eines Videos mit der GPU anwenden und dann diese Frames in ein neues Ergebnis Video neu zu kodieren.MediaCodec gleichzeitige Codierung und Decodierung
Im Interesse der Leistung, die ich die folgende Strömung umgesetzt habe:
Es gibt 3 verschiedene Themen, die jeweils mit einem eigenen OpenGL-Kontext. Diese Kontexte sind so eingerichtet, dass sie Texturen untereinander teilen.
Thread 1 Extrakte Bilder vom Video und halten sie in den GPU-Speichern als Texturen, ähnlich wie this Beispiel.
Thread 2 verarbeitet die Texturen mit einer modifizierten Version von GPUImage, die auch Texturen im GPU-Speicher ausgibt.
Schließlich Gewinde 3 schreibt die vom Faden erhalten Texturen 2 in eine neue Videodatei ähnlich dem Verfahren, beschrieben here
Rahmenreihenfolge beibehalten wird Warteschlangen zwischen Threads 1 und 2 verwendet wird, und die Fäden 2 und 3. Texturen werden manuell aus dem Speicher gelöscht nach werden sie für die Verarbeitung/Schreiben verwendet.
Der ganze Sinn dieses Ablaufs besteht darin, jeden Prozess in der Hoffnung zu trennen, dass die endgültige Leistung die langsamste der drei Threads sein wird.
DAS PROBLEM:
Das letzte Video ist zu 90% schwarzer Rahmen, nur einige von ihnen richtig zu sein.
Ich habe die einzelnen Ergebnisse der Extraktion und Verarbeitung überprüft und sie funktionieren wie erwartet. Beachten Sie auch, dass die 3 Komponenten, die in den 3 Threads beschrieben werden, in einem einzigen Thread gut zusammenpassen.
Ich habe versucht, Thread 1 und Thread 3 zu synchronisieren, und nach dem Hinzufügen einer zusätzlichen 100ms Schlafzeit zu Thread 1 das Video funktioniert gut, mit vielleicht 1 oder 2 schwarzen Rahmen. Scheint mir so, als ob die zwei Instanzen von Decoder und Encoder nicht gleichzeitig arbeiten könnten.
Ich werde diesen Beitrag mit zusätzlichen Details bearbeiten.
Hallo @fadden und danke für Ihre Antwort. Meine ursprüngliche Lösung würde einen einzigen Thread verwenden und gut funktionieren, war aber nicht schnell genug. Ich bin mir nicht sicher, ob ich die Bedeutung der SurfaceTexture verstehe. Zu diesem Zeitpunkt kopiere ich die resultierenden Decoder-Texturen in eine neue Textur, die ich mit GLES20.glGenTextures erstelle, und behalte sie, damit ich sie später benutzen kann. Auch, wie genau soll ich einen Kontext über drei Threads verwenden? Decodierung, Verarbeitung und Codierung erfordern einen aktuellen OpenGL-Kontext. – Rakatan
SurfaceTexture nimmt alles, was auf einer Oberfläche gezeichnet ist, und wickelt es in eine GLES- "externe" Textur. Das ist es, was Ihr verlinktes Beispiel (ExtractMpegFramesTest) verwendet. Was war der Engpass bei der Verwendung eines einzelnen Threads? Was ist der langsamste Teil Ihrer Pipeline? Sie sollten nur GLES aus Thread # 2 im obigen Schema verwenden. – fadden
Der Frame-Extraktionsabschnitt scheint der langsamste zu sein, deshalb dachte ich, dass ich ihm mehr Zeit geben könnte, während die Verarbeitung durchgeführt wird. Sie haben recht mit dem verlinkten Beispiel, aber um die Zeit zu sparen, kopiere ich die extrahierte Textur in eine neue von mir verwaltete Textur, um sie schneller in Phase 2 zu überführen. – Rakatan