0

Ich arbeite an einem Python-Skript, das auf RPi3 läuft, und verwende gstreamer, um eine Verbindung zum RTSP-Feed meiner IP-Kamera herzustellen und decodierte H264-Frames an mein Python-Skript zu liefern.Neustart der GStreamer-Pipeline in Python auf EOS

Hier ist die gstreamear Pipeline verwendet Frames von Kamera zu bekommen:

rtspsrc location=rtsp://ip:port/path ! rtph264depay ! h264parse ! decodebin ! videoconvert ! video/x-raw, format=BGR ! appsink name=sink 

Problem: Da die Kamera auf eine langsame/unzuverlässige Internet-Verbindung ist, dass ich ab und zu dropped Frames erhalten, die bewirkt, dass ein EOS-Signal erzeugt werden. Die Internetverbindungsbandbreite kann ein Problem sein, das manchmal einen Stromschlag verursacht.

Ziel: Auf EOS-Signal möchte ich die Pipeline neu starten, damit Gstreamer Rahmen zu meinem Programm dienen kann.

Was ich versucht habe: Ich habe eine Funktion Rückruf an den Bus angeschlossen, die mithilfe von Nachrichten hört

bus.connect("message", on_message) 

Im Innern der „ON_MESSAGE“ -Funktion, ich bin in der Lage, erfolgreich festzustellen, ob die Nachricht ein EOS-Signal. Wenn ich ein EOS-Signal erkenne, versuche ich, die Pipeline neu zu starten, indem ich Folgendes tue:

Leider funktioniert das nicht. Sobald mein Skript versucht, die Pipeline mit dem obigen Snippet neu zu starten, erhalte ich die folgenden Fehler auf dem Bus. Und ich weiß, dass die Kamera online ist, also ist das nicht das Problem.

('ERROR!!!:', 'source', '!:!', 'Could not read from resource.') 
('Debug info:', 'gstrtspsrc.c(5583): gst_rtspsrc_send(): /GstPipeline:pipeline0/GstRTSPSrc:source:\nGot error response: 400 (Bad Request).') 
('ERROR!!!:', 'source', '!:!', 'Could not write to resource.') 
('Debug info:', 'gstrtspsrc.c(6933): gst_rtspsrc_close(): /GstPipeline:pipeline0/GstRTSPSrc:source:\nCould not send message. (Generic error)') 
('ERROR!!!:', 'udpsrc2', '!:!', 'Internal data stream error.') 
('Debug info:', 'gstbasesrc.c(2951): gst_base_src_loop(): /GstPipeline:pipeline0/GstRTSPSrc:source/GstUDPSrc:udpsrc2:\nstreaming stopped, reason not-linked (-1)') 

Falls das Problem war mit rtspsrc, ich habe auch versucht, ein kurzes lokales Video mit filesrc verwenden und mit dem EOS-Signal erzeugt wird, wenn gstreamer Ende der Videodatei erreicht zu testen, ob ich bin in der Lage, die Pipeline neu starten . Hier ist ein Beispiel Pipeline ich verwenden, um lokales Video zu spielen:

filesrc location=file.mp4 ! qtdemux ! decodebin ! videoconvert ! video/x-raw, format=BGR ! appsink name=sink 

Wenn es erfolgreich ist, sollte es gehe durch das Video erneut starten, aber kein Glück ... Stattdessen ich die folgende Fehlermeldung erhalten, die mich macht denke, dass filesrc irgendwie zurückgesetzt werden muss. Gleiche mit dem RTSP-Beispiel, in dem es wird ein Fehler von rtspsrc erzeugt wird

('ERROR!!!:', 'qtdemux0', '!:!', 'Internal data stream error.') 
('Debug info:', 'qtdemux.c(5847): gst_qtdemux_loop(): /GstPipeline:pipeline0/GstQTDemux:qtdemux0:\nstreaming stopped, reason not-linked (-1)') 

jemand irgendein Licht auf dieses Problem vergießen? Vielen Dank!

+0

Erstellen Sie Ihre Pipeline mit gst_parse_launch oder ähnlichem? – thiagoss

Antwort

0

Wenn Sie das tun

pipline.set_state (Gst.State.NULL)

es bedeutet nicht, dass die Pipeline diesen Zustand sofort erreicht hat. Um sicher zu sein, können Sie pipeline.get_state() aufrufen. Ich schlage auch vor, die Rückgabewerte für set_state() zu behandeln. Um schließlich wieder spielen zu können, müssen Sie nicht zuerst zu PAUSED gehen (es sei denn, Sie möchten etwas zwischen PUASED und PLAYING machen).

+0

Also habe ich etwas Debug-Code hinzugefügt, um den Pipeline-Status in der Befehlszeile während bestimmter Punkte zu drucken. Wenn EOS herausgegeben wird, befindet sich die Pipeline immer noch im "PLAYING" -Zustand. Ich kann es dann in den Zustand "BEREIT" und dann in den Zustand "NULL" versetzen. Um die Pipeline wieder hochzufahren, setze ich die Pipeline wieder auf "READY" (bestätige, dass sie bereit ist, indem ich "get_state()" verwende). Aber wenn ich versuche, es entweder in "PLAYING" oder "PAUSED" zurückzusetzen, bekomme ich den gleichen Fehler wie zuvor: 'qtdemux.c (5847): gst_qtdemux_loop():/GstPipeline: pipeline0/GstQTDemux: qtdemux0: \ nStreaming gestoppt, Ursache nicht verknüpft (-1) ' –

+0

Wenn ich meine RTSP-Quelle anstelle der lokalen Videowiedergabe verwende, erhalte ich einen sehr ähnlichen Fehler , außer diesmal von 'rtspsrc' anstatt' qtdemux'. ''gstbasesrc.c (2951): gst_base_src_loop():/GstPipeline: pipeline0/GstRTSPSrc: source/GstUDPSrc: udpsrc2: \ nstreaming gestoppt, Grund nicht verknüpft (-1)'' –

+0

Hmm, das nicht von qtdemux verbunden erzählt dass es bei der Wiederverwendung nicht dieselbe Initialisierung durchläuft, als wenn es neu wäre. Das könnte ein Fehler sein. Wenn Sie die Pipeline auf EOS neu erstellen und es funktioniert, würde dies dies bestätigen. Kannst du einen Fehler für gstreamer ablegen und dein Python-Beispiel hinzufügen? – ensonic