Correct way to change source (filesrc location) in python

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Correct way to change source (filesrc location) in python

whoman
Hello,
Can anyone help me confirm that I'm doing the correct process/workflow in order to change the source (filesrc) of a pipeline dynamically in python?

Currently, the way I'm changing the source is :

1.  Set pipeline state to READY:
2.  change location property of filesrc:
3.  Set pipeline state to PLAYING

(example code below)

Is this the correct way, or am I missing some steps?
My python example is below.

The reason I ask is that I am using rockchip's mppvideodec (h264 hardware GST decoder element for rockchip).  I'm experiencing a tiny continuous memory leak while playing h264 videos with rockchip's hardware decoder.  This leak is very small, so in order to show the memory leak, I made a simple python script that changes source once per second.  

The maintainer of gstreamer-rockchip has suggested that the way I'm changing the source might not be correct, and that I should be handling state change messages from the bus (somehow).

Now, this maintainer (Jeffy) is a really great person and a great maintainer, and over the last month or two he has helped me VERY MUCH to debug many problems I was experiencing with 'changing the source' (filesrc location) with gstreamer-rockchip elements.  Because of this, I want to follow his advice and determine if there are steps I'm missing when changing source (stopping/starting pipeline).


Jeffy's response:  https://github.com/rockchip-linux/gstreamer-rockchip/issues/70#issuecomment-684649694

"guessing you just cannot do it this way, since the state changing would create and post an async message to the pipeline bus, which needs to be handled...
1/ you need to add a bus watch to handle messages(especially the state changed messages in your case)
2/ you need to run the glib main loop"



My example is below
please note:  this small leak does not occur when using avdec_h264 in place of mppvideodec.

Can anyone confirm which steps I may be missing when stopping/changingSrc/starting the pipeline?

Thanks




import tty
import sys
import termios
import gi
import subprocess
import os, signal
import time
from time import sleep
gi.require_version('Gst', '1.0')
gi.require_version('GLib', '2.0')
gi.require_version('GObject', '2.0')
from gi.repository import Gst, GObject, GLib
GObject.threads_init()
Gst.init(sys.argv)



#GST PIPELINE
#GST - create the elements
source = Gst.ElementFactory.make("filesrc", "source")
demux = Gst.ElementFactory.make("qtdemux", "demux")
parse = Gst.ElementFactory.make("h264parse", "parse")
decoder = Gst.ElementFactory.make("mppvideodec", "decoder")
video_convert = Gst.ElementFactory.make("videoconvert", "videoconvert")
sink = Gst.ElementFactory.make("kmssink", "sink")

#GST - create the empty pipeline
p1 = Gst.Pipeline.new("test-pipeline")

if not p1 or not source or not sink:
print("ERROR: Not all elements could be created")
sys.exit(1)

#GST - add and link elements in pipeline
p1.add(source)
p1.add(demux)
p1.add(parse)
p1.add(decoder)
p1.add(video_convert)
p1.add(sink)

if not source.link(demux):
print("ERROR: Could not link source to demux")
sys.exit(1)
#if not demux.link(parse):
# print("ERROR: Could not link demux to parse")
# sys.exit(1)
if not parse.link(decoder):
print("ERROR: Could not link parse to decoder")
sys.exit(1)
if not decoder.link(video_convert):
print("ERROR: Could not link decoder to video_convert")
# sys.exit(1)
#if not decoder.link(sink):
if not video_convert.link(sink):
print("ERROR: Could not link scaler to sink")
sys.exit(1)

# set the source element's location property
source.set_property("location", "/video/g62.mp4")

ret = p1.get_state(1)
print ret.state



#GST - handler for the pad-added signal
def demux_on_pad_added(src, new_pad):
if new_pad.get_name() == "video_0":
print(
"Received new pad '{0:s}' from '{1:s}'".format(
new_pad.get_name(),
src.get_name()))

# attempt the link
sink_pad = parse.get_static_pad("sink")
new_pad_caps = new_pad.get_current_caps()
new_pad_struct = new_pad_caps.get_structure(0)
new_pad_type = new_pad_struct.get_name()
print(new_pad_type)
ret = new_pad.link(sink_pad)
if not ret == Gst.PadLinkReturn.OK:
print("Type is '{0:s}' but link failed".format(new_pad_type))
else:
print("Link succeeded (type '{0:s}')".format(new_pad_type))
return
return

# connect to the pad-added signal
demux.connect("pad-added", demux_on_pad_added)



def dispose_src_cb(src):
    src.set_state(Gst.State.NULL)


p1.set_state(Gst.State.PLAYING)


#GST - Puase playback, set "location", and begin playback
def PlayVideo1():
# GST stop pipeline
        ret = p1.get_state(1)
        print "current state:"
        print ret.state
        print "setting STATE to READY"
        p1.set_state(Gst.State.READY)
#        GLib.idle_add(dispose_src_cb, decoder)
        ret = p1.get_state(1)
        print "current state:"
        print ret.state



# GST set filesrc 'location'
        print "changing filesrc location"
        source.set_property('location', '/video/test1.mp4')
print "filesrc location has been changed.  Setting STATE back to PLAYING"

# GST start pipeline
#        decoder.sync_state_with_parent()
        p1.set_state(Gst.State.PLAYING)
        ret = p1.get_state(1)
        print "current state:"
        print ret.state


def PlayVideo2():
# GST stop pipeline
        p1.set_state(Gst.State.READY)
#       GLib.idle_add(dispose_src_cb, decoder)

# GST set filesrc 'location'
        source.set_property('location', '/video/test2.mp4')

# GST start pipeline
# decoder.sync_state_with_parent()
        p1.set_state(Gst.State.PLAYING)

#KEYBOARD - detect key press, and launch GST PlayVideo functions
orig_settings = termios.tcgetattr(sys.stdin)

tty.setcbreak(sys.stdin)
x = 0
while x != chr(27): # ESC
    x=sys.stdin.read(1)[0]
    print("You pressed", x)
    if x == "1":
        PlayVideo1()
    if x == "2":
        PlayVideo2()
    if x == "x":
        exit()

termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings) 

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel