dipesh
dipesh

Reputation: 43

convert gstreamer pipeline to python code

Im trying to convert gstreamer pipeline to python code using gi library.

This is the pipeline which is running successfully in terminal:

gst-launch-1.0 rtspsrc location="rtsp://admin:[email protected]:554/H264?ch=1&subtype=0&proto=Onvif" latency=300 ! rtph264depay ! h264parse ! nvv4l2decoder drop-frame-interval=1 ! nvvideoconvert ! video/x-raw,width=1920,height=1080,formate=I420 ! queue !  nveglglessink window-x=0 window-y=0 window-width=1080 window-height=720

but while running the same pipeline using python code, there is no output window displaying rtsp stream and also no error on the terminal. The terminal simply stuck until i press ctrl+c.

This is the code that im using to run the gstreamer command:

import gi

gi.require_version("Gst", "1.0")

from gi.repository import Gst, GObject


def main(device):
    GObject.threads_init()
    Gst.init(None)

    pipeline = Gst.Pipeline()

    source = Gst.ElementFactory.make("rtspsrc", "video-source")
    source.set_property("location", device)
    source.set_property("latency", 300)
    pipeline.add(source)

    depay = Gst.ElementFactory.make("rtph264depay", "depay")
    pipeline.add(depay)
    source.link(depay)

    parse = Gst.ElementFactory.make("h264parse", "parse")
    pipeline.add(parse)
    depay.link(parse)

    decoder = Gst.ElementFactory.make("nvv4l2decoder", "decoder")
    decoder.set_property("drop-frame-interval", 2)
    pipeline.add(decoder)
    parse.link(decoder)

    convert = Gst.ElementFactory.make("nvvideoconvert", "convert")
    pipeline.add(convert)
    decoder.link(convert)

    caps = Gst.Caps.from_string("video/x-raw,width=1920,height=1080,formate=I420")
    filter = Gst.ElementFactory.make("capsfilter", "filter")
    filter.set_property("caps", caps)
    pipeline.add(filter)
    convert.link(filter)

    queue = Gst.ElementFactory.make("queue", "queue")
    pipeline.add(queue)
    filter.link(queue)

    sink = Gst.ElementFactory.make("nveglglessink", "video-sink")
    sink.set_property("window-x", 0)
    sink.set_property("window-y", 0)
    sink.set_property("window-width", 1280)
    sink.set_property("window-height", 720)

    pipeline.add(sink)

    queue.link(sink)

    loop = GObject.MainLoop()

    pipeline.set_state(Gst.State.PLAYING)

    try:
        loop.run()
    except:
        pass

    pipeline.set_state(Gst.State.NULL)

if __name__ == "__main__":
    main("rtsp://admin:[email protected]:554/H264?ch=1&subtype=0&proto=Onvif")

Does anyone know what is the mistake? Thank you!

Upvotes: 4

Views: 4085

Answers (1)

nielsdg
nielsdg

Reputation: 2733

The reason it doesn't work is because rtspsrc's source pad is a so-called "Sometimes pad". The link here explains it quite well, but basically you cannot know upfront how many pads will become available on the rtspsrc, since this depends on the SDP provided by the RTSP server.

As such, you should listen to the "pad-added" signal of the rtspsrc, where you can link the rest of your pipeline to the source pad that just showed up in the callback.

So summarised:

def main(device):
    GObject.threads_init()
    Gst.init(None)

    pipeline = Gst.Pipeline()
    source = Gst.ElementFactory.make("rtspsrc", "video-source")
    source.set_property("location", device)
    source.set_property("latency", 300)
    source.connect("pad-added", on_rtspsrc_pad_added)
    pipeline.add(source)

    # We will add/link the rest of the pipeline later
    loop = GObject.MainLoop()

    pipeline.set_state(Gst.State.PLAYING)

    try:
        loop.run()
    except:
        pass

    pipeline.set_state(Gst.State.NULL)

def on_rtspsrc_pad_added(rtspsrc, pad, *user_data):
    # Create the rest of your pipeline here and link it 
    depay = Gst.ElementFactory.make("rtph264depay", "depay")
    pipeline.add(depay)
    rtspsrc.link(depay)

    # and so on ....

Upvotes: 4

Related Questions