2016-08-11 3 views
0

Ich habe Probleme beim Speichern von appsrc in Filesink, wenn mehrere gstreamer-Prozesse gleichzeitig ausgeführt werden. Nur einer der gstreamer-Prozesse schreibt korrekt, während die anderen fast leere Dateien schreiben. Während der Dateisuchoperation scheint es zu Schreibkonflikten zu kommen.Mehrere gleichzeitige Filesinks können nicht aus appsrc geschrieben werden

Hinweis: Ich verwende gstreamer1.0 (v1.8.2) mit python3 (v3.5.2) unter MAC OS 10.11.6.

Hier ist, was mein Code tatsächlich tun:

Im Hintergrund habe ich von einem einzigen Video-Stream in Rahmen lese, jeden Frame BGR numpy Arrays der Größe 1920x800x3 Konvertieren und jeden Frame in einem Ringpuffer speichert . Ich habe eine "gstreamer_writer" -Funktion erstellt, die Frames aus diesem Ringpuffer liest, die Frames in einen Byte-Stream konvertiert und diesen Stream in appsrc einspeist.

Dies funktioniert, indem Sie einen neuen Multiprozess (multiprocessing.Process) instanziieren und auf die "gstreamer_writer" -Funktion verweisen. Dies funktioniert völlig einwandfrei für einen einzelnen Multiprozess/Funktionsaufruf. Appsrc korrekt den Bytestrom zugeführt und speichere ich diese BGR-Rahmen in eine MP4 mit H264-Codierung der folgenden gstreamer Pipeline verwendet:

appsrc format=3 name=app emit-signals=true do-timestamp=true is-live=true blocksize=4608000 max-bytes=0 caps=video/x-raw,format=BGR,width=1920,height=800 ! videoconvert ! video/x-raw,format=I420,width=1920,height=800 ! vtenc_h264 ! mp4mux ! filesink location=test1.mp4 

Wenn jedoch I instanziieren zwei oder mehr multiprocesses und sie an dem Funktionspunkt nur ein von Filesinks funktionieren ordnungsgemäß. Zum Beispiel, wenn man auf "test1.mp4" schreibt und der andere auf "test2.mp4" schreibt, dann wird eines der Videos korrekt geschrieben und das andere wird fehlschlagen und ein fast leeres mp4 (~ 500kb) schreiben. Es ist nicht immer das gleiche mp4, 50% der Zeit test1.mp4 wird richtig geschrieben und 50% der Zeit test2.mp4 wird korrekt geschrieben. Es sieht so aus, als gäbe es eine Art Race Condition oder Write Contention, die verhindert, dass beide MP4s korrekt in die Datei geschrieben werden.

Eine Sache zu beachten ist, dass jeder Multiprozess auf die gleichen Frames aus dem gleichen Ring-Puffer zugreift. Ich dachte, das hätte Probleme mit dem Gstreamer verursacht. Wenn ich die Streams jedoch mit autovideosink zeige, anstatt sie in eine Datei zu schreiben, kann ich so viele Streams/Multiprocesses anzeigen, wie ich möchte. Dies bedeutet, dass die Daten ordnungsgemäß durch die Pipeline geleitet werden und nur während der Schreibphase ausfallen. Getestet habe ich diese den GStreamer-Befehl:

appsrc format=3 name=app emit-signals=true do-timestamp=true is-live=true blocksize=4608000 max-bytes=0 caps=video/x-raw,format=BGR,width=1920,height=800 ! videoconvert ! video/x-raw,format=I420,width=1920,height=800 ! vtenc_h264 ! avdec_h264 ! autovideosink 

Wenn jemand irgendwelche Vorschläge für hat, wie ich dieses Problem beheben kann ich würde es zu schätzen wissen. Ich hoffe, es ist eine einfache Änderung, aber Sie wissen nie mit Gstreamer!

Danke!

Antwort

0

Zu lang für einen Kommentar, und dies kann Ihr Problem lösen, wenn ich richtig bin ..

hinzufügen Warteschlange vor filesink:

appsrc format=3 name=app emit-signals=true do-timestamp=true is-live=true blocksize=4608000 max-bytes=0 caps=video/x-raw,format=BGR,width=1920,height=800 ! videoconvert ! video/x-raw,format=I420,width=1920,height=800 ! queue ! vtenc_h264 ! mp4mux ! queue ! filesink location=test1.mp4 

Queue hat zwei Funktionen: + einen Puffer, bevor raubend Element (welcher Encoder ist - er benötigt viele Frames, bevor er mit der Kodierung beginnen kann) + separate Weiterverarbeitung in neuen Thread - damit Filesink Daten im neuen Thread verarbeiten würde.

HTH

+0

Danke für die schnelle Antwort @otoplsky! Leider hat das Hinzufügen dieser beiden Warteschlangen das Problem nicht gelöst. Ein Prozess beginnt sofort mit dem Schreiben in die Datei, während der andere bei 0 MB bleibt.Ich habe eine neue Fehlermeldung vom Hinzufügen der Warteschlangen erhalten, die nur einmal am Anfang ausgelöst: Fehler: GST_PADS gstpad.c: 3279: gboolean gst_pad_query_latency_default (GstPad *, GstQuery *): minimale Latenz größer als maximale Latenz. Ich bekomme auch immer den folgenden Fehler beim Start: vtenc vtenc.c: 807: gst_vtenc_create_session: VTCompressionSessionCreate() zurückgegeben: -12915 –

Verwandte Themen