Speichern der openGL-Kontext als video-Ausgang
Ich bin versucht derzeit, speichern Sie die animation in openGL
zu einer video-Datei. Ich habe versucht mit openCV
's videowriter
aber keinen Vorteil. Ich habe erfolgreich in der Lage, eine Momentaufnahme zu generieren und speichern Sie es als bmp
mit der SDL
Bibliothek. Wenn ich speichern Sie alle Schnappschüsse, die Sie und erstellen Sie dann das video mit ffmpeg
, das ist wie das sammeln von 4 GB im Wert von Bildern. Nicht sinnvoll ist.
Wie kann ich schreiben, video-frames direkt beim Rendern?
Hier der code, den ich verwenden, um Schnappschüsse zu machen, wenn ich verlangen:
void snapshot(){
SDL_Surface* snap = SDL_CreateRGBSurface(SDL_SWSURFACE,WIDTH,HEIGHT,24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
char * pixels = new char [3 *WIDTH * HEIGHT];
glReadPixels(0, 0,WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
for (int i = 0 ; i <HEIGHT ; i++)
std::memcpy( ((char *) snap->pixels) + snap->pitch * i, pixels + 3 * WIDTH * (HEIGHT-i - 1), WIDTH*3 );
delete [] pixels;
SDL_SaveBMP(snap, "snapshot.bmp");
SDL_FreeSurface(snap);
}
Muss ich die video-Ausgabe. Ich habe entdeckt, dass ffmpeg
können verwendet werden, um videos zu erstellen von C++ - code, aber nicht in der Lage, herauszufinden, den Prozess. Bitte um Hilfe!!
BEARBEITEN : ich habe versucht mit openCV
CvVideoWriter
Klasse, aber das Programm stürzt ab ("segmentation fault
") der moment, in der Sie deklariert ist.Zusammenstellung zeigt keine Fehler, natürlich. Irgendwelche Vorschläge dazu?
LÖSUNG FÜR PYTHON NUTZER (Erfordert Python2.7
,python-imaging
,python-opengl
,python-opencv
, codecs von format, das Sie möchten, zu schreiben, ich bin auf Ubuntu 14.04 64-bit
):
def snap():
pixels=[]
screenshot = glReadPixels(0,0,W,H,GL_RGBA,GL_UNSIGNED_BYTE)
snapshot = Image.frombuffer("RGBA",W,H),screenshot,"raw","RGBA",0,0)
snapshot.save(os.path.dirname(videoPath) + "/temp.jpg")
load = cv2.cv.LoadImage(os.path.dirname(videoPath) + "/temp.jpg")
cv2.cv.WriteFrame(videoWriter,load)
Hier W
und H
sind die Fenster-Dimensionen (Breite,Höhe). Was passiert ist, ich bin mit PIL zum konvertieren der raw-Pixel Lesen aus der glReadPixels
Befehl in eine JPEG
Bild. Ich bin laden, dass JPEG in der openCV
Bild und Schrift, um die videowriter. Ich hatte bestimmte Probleme direkt mit dem PIL-Bild in der videowriter (das sparen würde Millionen von Taktzyklen des I/O
), aber jetzt bin ich nicht arbeiten. Image
ist ein PIL
Modul cv2
ist ein python-opencv
Modul.
- Anstatt
ffmpeg
, das ist ein Befehlszeilen-Dienstprogramm zum codieren von video, das Sie verwenden solltenlibavcodec
undlibavformat
. Dies sind die Bibliotheken auf denenffmpeg
ist tatsächlich aufgebaut, und erlaubt Ihnen zu Kodieren von video-und speichern Sie es in einem standard-stream/interchange format (z.B. RIFF/ - AVI), ohne ein separates Programm. - kann ich einen Hinweis, wie diese Bibliotheken zu nutzen, weil ich auch überprüft diese, nicht genug Daten, um zu begreifen, wie die Arbeit
Du musst angemeldet sein, um einen Kommentar abzugeben.
Klingt es so, als wenn Sie das Befehlszeilen-Dienstprogramm:
ffmpeg
. Anstatt mit dem command-line-Kodierung des Videos aus einer Sammlung von Standbildern, die Sie verwenden solltenlibavcodec
undlibavformat
. Dies sind die Bibliotheken auf denenffmpeg
ist tatsächlich aufgebaut, und erlaubt Ihnen zu Kodieren von video-und speichern Sie es in einem standard-stream/interchange format (z.B. RIFF/- AVI), ohne ein separates Programm.Wahrscheinlich werden Sie nicht finden eine Menge von tutorials auf Umsetzung, weil es traditionell der Fall, dass Menschen verwenden wollte
ffmpeg
in die andere Richtung gehen; das ist, decodieren verschiedene video-Formate für die Darstellung in OpenGL. Ich denke, das wird sich ändern, sehr bald mit der Einführung der gameplay-video-encoding auf der PS4 und Xbox One Konsolen, plötzlich die Nachfrage für diese Funktionalität wird in die Höhe Schießen.Das Allgemeine Verfahren ist dies jedoch:
Eine nette Sache über diese ist Sie nicht wirklich brauchen, um eine Datei zu schreiben. Seit Sie regelmäßig die Kodierung von Datenpaketen aus Ihren Puffer von noch frames, können Sie streamen Sie Ihre codierte Videodaten über ein Netzwerk, wenn Sie möchten - dies ist der Grund, warum codec und container (interchange) - format getrennt sind.
Andere nette Sache ist, Sie müssen nicht zum synchronisieren der CPU und GPU, können Sie setup ein pixel-buffer-Objekt und OpenGL kopieren von Daten in der CPU-Speicher ein paar frames hinter der GPU. Das macht die real-time-encoding von video-viel weniger anspruchsvoll, Sie haben nur zu Kodieren, und Spülen Sie das video auf die Festplatte oder über das Netzwerk regelmäßig, wenn video-Latenz Forderungen sind nicht unvernünftig. Dies funktioniert sehr gut in real-time rendering, da Sie einen ausreichend großen pool von Daten zu halten, einen CPU-thread beschäftigt Codierung zu allen Zeiten.
Encoding frames können sogar in Echtzeit auf der GPU, sofern genug Speicher für einen großen Puffer der Rahmen (da letztendlich die kodierten Daten werden kopiert von der GPU zu CPU und Sie möchten dies tun, so selten wie möglich). Natürlich ist dies nicht über
ffmpeg
gibt es spezialisierte Bibliotheken mittels CUDA /OpenCL /compute-Shader für diesen Zweck. Ich habe noch nie verwendet, aber Sie existieren.Portabilität Willen, Sie sollten stick mit libavcodec-und Pixel-Buffer-Objekte, die für asynchrone GPU->CPU kopieren. CPUs haben dieser Tage genug Kerne, Sie können wahrscheinlich Weg erhalten, ohne GPU-assisted-Codierung, wenn Sie Puffer genug frames zu Kodieren, bei mehreren gleichzeitigen threads (das schafft zusätzlichen Synchronisations-overhead und erhöht die Latenz bei der Ausgabe von kodierten video) oder einfach "drop frames /niedrigere Auflösung (poor man' s solution).
Gibt es viele Konzepte, die hier behandelt werden, die weit über den Umfang von SDL, aber Sie haben Sie Fragen, wie dies mit besser Leistung als die aktuelle Lösung. Kurz gesagt, verwenden OpenGL-Pixel-Buffer-Objekte, um Daten zu übertragen, und libavcodec-für die Codierung. Ein Beispiel-Anwendung kodiert video finden Sie auf der ffmpeg - libavcodec Beispiele Seite.
Für einige fast-test so etwas wie der code unten funktioniert (getestet), in der Größe anpassbare Fenster sind unbehandelt.
"wb"
um für diese zu arbeiten.pixels
variable? kann u geben Sie ein vollständiges Beispiel?glReadPixels
füllen es mit dem Inhalt des aktuellen render-buffer.unsigned char pixels[800*600*3]
odervoid *pixels = malloc(800*600*3)
tun sollteRunnable Beispiel mpg mit FFmpeg 2.7
Erklärung und eine Obermenge Beispiel an: Wie zu verwenden GLUT/OpenGL zum Rendern in eine Datei?
Betrachten https://github.com/FFmpeg/FFmpeg/blob/n3.0/doc/examples/muxing.c zu generieren, eine geschlossene format.