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 |
Free forum by Nabble | Edit this page |