Hi,
I have very strange problem that I can't understand and maybe some Linux hacker here can give me a hint about what might be wrong. I'm creating a pipeline that generates sound (audiotestsrc), puts it through queue to fdsink, reads whatever comes out of fdsrc (through queue) to the fakesink. It blocks, and me and my colleagues have no idea as to what may cause the deadlock. The reason I'm doing such a strange pipeline is that I have a commercial encoder that comes as a executable (no SDK, no libs to link to) that is able to get input from stdin and write output to stdout. To link it with a pipeline I'm spawning it within my GStreamer application and I build pipeline like that redirecting pipes of the encoder to fdsink and fdsrc. Can anyone explain why there is a deadlock? Here's the example code I'm talking about (first is python GStreamer application, next is the "testprocessing" code that you might switch the fdsink/fdsrc to): (pipe.py) #!/usr/bin/env python import pygst, gst, glib, gobject import sys, os import subprocess, signal, shlex def on_handoff(sink, buffer, pad): print "handoff: %d" % (len(buffer),) def on_message(bus, message): print "BUS %s: %s" % (bus.get_name(), message) if __name__ == "__main__": glib.threads_init() # argv = "testprocessing" # process = subprocess.Popen(shlex.split(argv), close_fds=True, # stdin=subprocess.PIPE, stdout=subprocess.PIPE) pipeline = gst.Pipeline("test") src = gst.element_factory_make("audiotestsrc") q1 = gst.element_factory_make("queue", "sink-queue") fsink = gst.element_factory_make("fdsink") fsrc = gst.element_factory_make("fdsrc") q2 = gst.element_factory_make("queue", "src-queue") sink = gst.element_factory_make("fakesink") sink.set_property("signal-handoffs", True) sink.connect("handoff", on_handoff); readfd, writefd = os.pipe() os.write(writefd, "1") s = os.read(readfd, 1) assert s == "1" # test whether pipe is actually working to prove it does print "================****************+++++++++++++++++", readfd, writefd fsink.set_property("fd", writefd) fsrc.set_property("fd", readfd) #fsink.set_property("fd", process.stdin.fileno()) #fsrc.set_property("fd", process.stdout.fileno()) pipeline.add(src, q1, fsink, fsrc, q2, sink) gst.element_link_many(src, q1, fsink) gst.element_link_many(fsrc, q2, sink) bus = pipeline.get_bus() bus.add_signal_watch() bus.connect("message", on_message) mainloop = glib.MainLoop() pipeline.set_state(gst.STATE_PLAYING) try: mainloop.run() except: pass print "Finishing" # process.send_signal(signal.SIGINT) # process.wait() print "Stopping pipeline" pipeline.set_state(gst.STATE_NULL) del pipeline (testprocessing.c) #include <string.h> #include <unistd.h> int main() { char buf[2][4096]; int i = 0; ssize_t len[2], wr; memset (buf, 0, sizeof (buf)); len[1] = read (STDIN_FILENO, buf[1], 4096); while (1) { len[i] = read (STDIN_FILENO, buf[i], 4096); i = (i + 1) % 2; wr = write (STDOUT_FILENO, buf[i], len[i]); } return 0; } ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
2010/7/23 Andrzej K. Haczewski <[hidden email]>:
> Hi, > > I have very strange problem that I can't understand and maybe some > Linux hacker here can give me a hint about what might be wrong. > > I'm creating a pipeline that generates sound (audiotestsrc), puts it > through queue to fdsink, reads whatever comes out of fdsrc (through > queue) to the fakesink. > > It blocks, and me and my colleagues have no idea as to what may cause > the deadlock. The reason I'm doing such a strange pipeline is that I > have a commercial encoder that comes as a executable (no SDK, no libs > to link to) that is able to get input from stdin and write output to > stdout. To link it with a pipeline I'm spawning it within my GStreamer > application and I build pipeline like that redirecting pipes of the > encoder to fdsink and fdsrc. > > Can anyone explain why there is a deadlock? > > Here's the example code I'm talking about (first is python GStreamer > application, next is the "testprocessing" code that you might switch > the fdsink/fdsrc to): Here's another try, that works. It uses 2 pipelines, one for each end. Why I can't have fdsink and fdsrc in the middle of the pipeline then? What am I getting wrong about the pipeline functionality? (pipe2.py) #!/usr/bin/env python import glib, gobject glib.threads_init() import pygst, gst import sys, os import subprocess, signal, shlex def on_handoff(sink, buffer, pad): print "handoff: %d" % (len(buffer),) def on_message(bus, message): print "BUS %s: %s" % (bus.get_name(), message) if __name__ == "__main__": # argv = "testprocessing" # process = subprocess.Popen(shlex.split(argv), close_fds=True, # stdin=subprocess.PIPE, stdout=subprocess.PIPE) pipeline = gst.Pipeline("test") pipeline2 = gst.Pipeline("test2") src = gst.element_factory_make("audiotestsrc") q1 = gst.element_factory_make("queue", "sink-queue") fsink = gst.element_factory_make("fdsink") fsrc = gst.element_factory_make("fdsrc") q2 = gst.element_factory_make("queue", "src-queue") sink = gst.element_factory_make("fakesink") sink.set_property("signal-handoffs", True) sink.connect("handoff", on_handoff); readfd, writefd = os.pipe() os.write(writefd, "1") s = os.read(readfd, 1) assert s == "1" print "================****************+++++++++++++++++", readfd, writefd fsink.set_property("fd", writefd) fsrc.set_property("fd", readfd) # fsink.set_property("fd", process.stdin.fileno()) # fsrc.set_property("fd", process.stdout.fileno()) pipeline.add(src, q1, fsink) pipeline2.add(fsrc, q2, sink) gst.element_link_many(src, q1, fsink) gst.element_link_many(fsrc, q2, sink) bus = pipeline.get_bus() bus.add_signal_watch() bus.connect("message", on_message) bus2 = pipeline2.get_bus() bus2.add_signal_watch() bus2.connect("message", on_message) mainloop = glib.MainLoop() pipeline.set_state(gst.STATE_PLAYING) pipeline2.set_state(gst.STATE_PLAYING) try: mainloop.run() except: pass print "Finishing" #process.send_signal(signal.SIGINT) #process.wait() print "Stopping pipeline" pipeline.set_state(gst.STATE_NULL) pipeline2.set_state(gst.STATE_NULL) del pipeline del pipeline2 ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
On Fri, 2010-07-23 at 13:22 +0200, Andrzej K. Haczewski wrote:
> > Can anyone explain why there is a deadlock? As I said on IRC, I think the problem is this: - the pipeline waits for all sinks to preroll - fdsink receives a buffer - fdsink prerolls and blocks (now in PAUSED state) - fdsink will only actually write data in PLAYING state - fakesink needs a buffer to preroll - fdsrc needs to receive a buffer first - fdsrc will only receive data once fdsink writes data - fdsink will only write data in PLAYING state - fdsink will only go into PLAYING state once the whole pipeline has prerolled - for the whole pipeline to preroll, fakesink needs to preroll You can use fakesink async=false to make it preroll even without data. Cheers -Tim ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
2010/7/23 Tim-Philipp Müller <[hidden email]>:
> On Fri, 2010-07-23 at 13:22 +0200, Andrzej K. Haczewski wrote: > >> > Can anyone explain why there is a deadlock? > > As I said on IRC, I think the problem is this: > > - the pipeline waits for all sinks to preroll > - fdsink receives a buffer > - fdsink prerolls and blocks (now in PAUSED state) > - fdsink will only actually write data in PLAYING state > > - fakesink needs a buffer to preroll > - fdsrc needs to receive a buffer first > - fdsrc will only receive data once fdsink > writes data > - fdsink will only write data in PLAYING state > - fdsink will only go into PLAYING state once > the whole pipeline has prerolled > - for the whole pipeline to preroll, fakesink > needs to preroll > > You can use fakesink async=false to make it preroll even without data. > > Cheers > -Tim One great Thank You, Tim. That solved huge problem for me. Cheers, Andrzej ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |