Hi,
I try to make whole gstreamer pipeline live in separate thread. I need it generally because I work with very slow v4l2 device driver and it takes considerable time for to change state of pipeline (init driver etc.). So I create special QThread in Qt4 app and make all the construction work (i.e. create all the elements, the pipeline itself etc.) in its run() method. I also connect to the bus of the pipeline to get some info: GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, audio_bus_call, this); gst_object_unref (bus); But I eventually found that all the message dispatching is processed in the main thread of the app. I.e. if I call thread() function which returns a pointer to a running thread in bus callback: void audio_bus_call() { qDebug()<<"thread:"<<thread(); } it returns a pointer to the main thread in spite of that all the GStreamer objects are created in different thread. Is there any way to make message dispatching process run in different thread other than main? Or somehow bind GStreamer event loop to Qt's event loop of some QThread object? Thank you very much, Alexey Chernov ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Administrator
|
Two variants. 1. Poll a message bus in your application's main loop http://n4.nabble.com/How-can-I-have-two-main-loops-in-my-program-tt1594663.html#a1594734 http://n4.nabble.com/running-g-main-loop-run-in-separate-thread-question-tt1680629.html#a1680629 2. Run a GThread. GStreamer uses glib, so it's anyway included. I do this way. class gst_player{ public: .... void main_loop_thread(void) ///< функция для запуска g_main_loop_run в отдельном потоке g_main_loop_run(m_loop); g_thread_exit(0); }; void open(char *filename) ; .... protected: GMainLoop *m_loop; ///< экземпляр mainloop GThread *m_loop_thread; ///< Поток, в котором будет работать mainloop ... }; .... static void main_loop_run(gpointer data) { if(!data) return; gst_player *player = (gst_player *)data; player->main_loop_thread(); } ... void gst_player::open(char * filename) { close(); m_loop = g_main_loop_new(NULL,FALSE); ... if((m_loop_thread=g_thread_create((GThreadFunc)main_loop_run,this,FALSE,NULL))==NULL){ close(); report_error(); } ... } |
In reply to this post by Alexey Chernov
4ernov wrote:
> Hi, > > I try to make whole gstreamer pipeline live in separate thread. GStreamer already run the data processing in separate threads. > I need > it generally because I work with very slow v4l2 device driver and it > takes considerable time for to change state of pipeline (init driver > etc.). Are you synchronously waiting for the state change to happen? I wonder if you just use things a bit sub optimal. Stefan > So I create special QThread in Qt4 app and make all the > construction work (i.e. create all the elements, the pipeline itself > etc.) in its run() method. I also connect to the bus of the pipeline > to get some info: > > GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); > gst_bus_add_watch (bus, audio_bus_call, this); > gst_object_unref (bus); > > But I eventually found that all the message dispatching is processed > in the main thread of the app. I.e. if I call thread() function which > returns a pointer to a running thread in bus callback: > void audio_bus_call() > { > qDebug()<<"thread:"<<thread(); > } > it returns a pointer to the main thread in spite of that all the > GStreamer objects are created in different thread. > > Is there any way to make message dispatching process run in different > thread other than main? Or somehow bind GStreamer event loop to Qt's > event loop of some QThread object? > > Thank you very much, > > Alexey Chernov > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/gstreamer-devel > ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
In reply to this post by Alexey Chernov
Thank you. And could you please give some details on how to start main
loop with g_main_loop_run to run in a separate thread? Maybe code sample of main_loop_thread(). Thank you in advance! ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Administrator
|
No more details, my main_loop_thread() is the inliner, declared inside the class declaration: class gst_player{ public: ... void main_loop_thread(void){ g_main_loop_run(m_loop); g_thread_exit(0); }; ... }; I've accidentally deleted { in my previous post. |
Administrator
|
I was just working on this :-)
I put my callback routines in friend functions of the class that I run in the separate thread. I am not sure which thread they run in, guess I can check that, but it works great. You do have to pass "this" as the data to the callbacks so you can manipulate the class members. Wes |
Yeah, Wes, I did the same except callbacks are global functions instead of
threads. And in my variant I found that callbacks run in main thread. Seems Qt somewhere runs g_main_loop_run() inside of its event loop and all the message dispatching goes to main thread. Could you please detect which thread your callbacks run in? Maybe friend functions is the solution... В сообщении от Пятница 16 апреля 2010 19:31:15 вы написали: > I was just working on this :-) > > I put my callback routines in friend functions of the class that I run in > the separate thread. I am not sure which thread they run in, guess I can > check that, but it works great. You do have to pass "this" as the data to > the callbacks so you can manipulate the class members. > > Wes ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
In reply to this post by Stefan Sauer
> GStreamer already run the data processing in separate threads.
Yes, I've read about it but in my case I would like to make callback functions live in a separate thread. > > > I need > > > > it generally because I work with very slow v4l2 device driver and it > > takes considerable time for to change state of pipeline (init driver > > etc.). > > Are you synchronously waiting for the state change to happen? I wonder > if you just use things a bit sub optimal. No, my case is a little complicated. I run two pipelines, one just for v4l2src and ximagesink (video pipeline) and another for alsasrc and pulsesink (audio pipeline). The aim is to inform user if he entered wrong /dev/videoX device (i.e. he entered /dev/video1 but the device is /dev/video0). I start both pipelines and try to switch them to READY. v4l2src says that he has a wrong device and throws error on the bus. In this case I try to switch both pipelines to NULL and print a message to user. But the problem is that audio pipeline hasn't completed its switch to READY (because of slow tuner driver). But I try to change it to NULL and it blocks everything until it gets READY state and then switch back to NULL. Stefan, it seems that Qt event loop has g_main_loop_run() call somewhere inside of it. For example, I don't call g_main_loop_run anywhere in my program at all and even don't create GMainLoop object, I don't have while(true) pseudo event loop but all the gstreamer stuff works just ok except this issue with threads. Do you know if it's true? If so, maybe there's some way to bind gstreamer's event loop to other QThread's Qt event loop.. Thanks for your help ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Administrator
|
Does "all the gstreamer stuff" include your-defined bus watch? It's very easy to check, who calls this function - just run your app in gdb and put a breakpoint inside the function. Then use the 'bt' command to display the backtrace. Googleing for the "Qt polls glib main loop" shows some messages, suggesting that the work on uniting main loops or QT and GLib were on their way in 2004. |
Administrator
|
In reply to this post by Alexey Chernov
Bus watch, set with gst_bus_add_watch, is called from the Glib main loop. Sync signal handler, set with gst_bus_set_sync_handler, is called from the elements' thread contexts. There is no difference, how functions are defined. A callback function anyway won't be a C++ class member (except static class members), because you have to pass its address to the registration routine, and you can't determine the address of a C++ class member if its not static. You can also be interested in the queue elements (http://www.gstreamer.net/data/doc/gstreamer/head/manual/html/chapter-threads.html). |
In reply to this post by Alexey Chernov
On Fri, 2010-04-16 at 23:32 +0400, Alexey Chernov wrote:
> Stefan, it seems that Qt event loop has g_main_loop_run() call somewhere > inside of it. For example, I don't call g_main_loop_run anywhere in my program > at all and even don't create GMainLoop object, I don't have while(true) pseudo > event loop but all the gstreamer stuff works just ok except this issue with > threads. Do you know if it's true? If so, maybe there's some way to bind > gstreamer's event loop to other QThread's Qt event loop.. > > Thanks for your help If you want to process bus messages in a specific thread context that's not the main application thread, then I would recommend just using gst_bus_(timed)_pop_(filtered)() for this, either blocking in a while loop with a small timeout, or hooked into whatever other event/loop mechanism there is already. You don't need to use a GMainLoop to get to the bus messages. Cheers -Tim ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
In reply to this post by wl2776
Thank you.
I've read some of those articles about Qt vs. Glib main loop, too. With the main loop everything is ok. The question is how QThread and GLib's context and threads are connected to each other and how different QThread's event loop interacts with Glib stuff. I said about all the message dispatching in GStreamer, but of course the main problem is concerning my callback call by bus. Also, thanks for info about gst_bus_set_sync_handler, I'll try it, too. В сообщении от Понедельник 19 апреля 2010 15:42:54 вы написали: > Bugzilla from [hidden email] wrote: > > Could you please detect which thread your callbacks run in? Maybe friend > > functions is the solution... > > Bus watch, set with gst_bus_add_watch, is called from the Glib main loop. > Sync signal handler, set with gst_bus_set_sync_handler, is called from the > elements' thread contexts. > There is no difference, how functions are defined. > A callback function anyway won't be a C++ class member (except static class > members), because you have to pass its address to the registration routine, > and you can't determine the address of a C++ class member if its not > static. > > You can also be interested in the queue elements > (http://www.gstreamer.net/data/doc/gstreamer/head/manual/html/chapter-threa > ds.html). ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
In reply to this post by Tim-Philipp Müller-2
Thank you, Tim, you're right, tying bus to Qt's event loop is what I really
want. The problem is that although Qt has separate event loops for its threads (QThreads) all of these loops seem to interact with the only GMainLoop somewhere deep inside. And the aim is to switch the bus dispatching to its QThread's event loop. One of solutions is to set bus handler with gst_bus_set_sync_handler() instead of gst_bus_add_watch() how wl2776 proposed. В сообщении от Понедельник 19 апреля 2010 16:09:05 вы написали: > On Fri, 2010-04-16 at 23:32 +0400, Alexey Chernov wrote: > > Stefan, it seems that Qt event loop has g_main_loop_run() call somewhere > > inside of it. For example, I don't call g_main_loop_run anywhere in my > > program at all and even don't create GMainLoop object, I don't have > > while(true) pseudo event loop but all the gstreamer stuff works just ok > > except this issue with threads. Do you know if it's true? If so, maybe > > there's some way to bind gstreamer's event loop to other QThread's Qt > > event loop.. > > > > Thanks for your help > > If you want to process bus messages in a specific thread context that's > not the main application thread, then I would recommend just using > gst_bus_(timed)_pop_(filtered)() for this, either blocking in a while > loop with a small timeout, or hooked into whatever other event/loop > mechanism there is already. You don't need to use a GMainLoop to get to > the bus messages. > > Cheers > -Tim ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
In reply to this post by Alexey Chernov
Thank you guys for support, I finally managed to make gstreamer process
callbacks in separate thread. The solution was to set bus handler with gst_bus_set_sync_handler() instead of gst_bus_add_watch() as wl2776 proposed, special thanks for him. So here're some things which I found out from this case: 1. Qt actually dispatches glib events and no additional g_main_loop_run() is necessary for Qt applications. 2. Qt seems to create separate glib context for glib objects which are created in separate QThread objects. 3. To make callbacks be called in separate thread where the certain gst objects were created you need to set them as a handler with gst_bus_set_sync_handler() to make them processed in the context of certain objects and not in the main context. Stefan is right that it's often unnecessary to run gst part of application in its own thread, but in some cases especially when performance depends on some drivers of special hardware (tuners, cameras etc.) it could be useful to separate threads. ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
On Sun, Apr 25, 2010 at 10:35 PM, Alexey Chernov <[hidden email]> wrote:
> Thank you guys for support, I finally managed to make gstreamer process > callbacks in separate thread. The solution was to set bus handler with > gst_bus_set_sync_handler() instead of gst_bus_add_watch() as wl2776 proposed, > special thanks for him. So here're some things which I found out from this > case: > 1. Qt actually dispatches glib events and no additional g_main_loop_run() is > necessary for Qt applications. > 2. Qt seems to create separate glib context for glib objects which are created > in separate QThread objects. > 3. To make callbacks be called in separate thread where the certain gst > objects were created you need to set them as a handler with > gst_bus_set_sync_handler() to make them processed in the context of certain > objects and not in the main context. Hi! I'm also trying to use GStreamer with Qt, and I'm experiencing some weird problems. 1) I'm not sure if Qt dispatches glib events (on Windows, at least): gst_bus_add_watch()'ed callback is never called 2) gst_bus_set_sync_handler() works, but events that I send from it (using Qt::QueuedConnection) seem to never reach the main loop, and I don't even know how to debug this If anybody can help me with these issues, it will be greatly appreciated. Gregory ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Administrator
|
On Sun, 2010-05-02 at 17:20 +0400, Gregory Petrosyan wrote:
> On Sun, Apr 25, 2010 at 10:35 PM, Alexey Chernov <[hidden email]> wrote: > > Thank you guys for support, I finally managed to make gstreamer process > > callbacks in separate thread. The solution was to set bus handler with > > gst_bus_set_sync_handler() instead of gst_bus_add_watch() as wl2776 proposed, > > special thanks for him. So here're some things which I found out from this > > case: > > 1. Qt actually dispatches glib events and no additional g_main_loop_run() is > > necessary for Qt applications. > > 2. Qt seems to create separate glib context for glib objects which are created > > in separate QThread objects. > > 3. To make callbacks be called in separate thread where the certain gst > > objects were created you need to set them as a handler with > > gst_bus_set_sync_handler() to make them processed in the context of certain > > objects and not in the main context. > > Hi! > > I'm also trying to use GStreamer with Qt, and I'm experiencing some > weird problems. > > 1) I'm not sure if Qt dispatches glib events (on Windows, at least): > gst_bus_add_watch()'ed callback is never called Use gst_bus_add_signal_watch(bus) and then connect to the 'message' event of the bus. If Qt is built with glib and uses the GMainLoop internally, the message signal will be emitted in the main thread. > 2) gst_bus_set_sync_handler() works, but events that I send from it > (using Qt::QueuedConnection) seem to never reach the main loop, and I > don't even know how to debug this It's a *synchronous* handler, therefore the callback you set will be called in the thread context of whoever emitted that message. > > If anybody can help me with these issues, it will be greatly appreciated. > > Gregory > > ------------------------------------------------------------------------------ > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/gstreamer-devel ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
On Mon, May 3, 2010 at 11:32 AM, Edward Hervey <[hidden email]> wrote:
> On Sun, 2010-05-02 at 17:20 +0400, Gregory Petrosyan wrote: >> On Sun, Apr 25, 2010 at 10:35 PM, Alexey Chernov <[hidden email]> wrote: >> > Thank you guys for support, I finally managed to make gstreamer process >> > callbacks in separate thread. The solution was to set bus handler with >> > gst_bus_set_sync_handler() instead of gst_bus_add_watch() as wl2776 proposed, >> > special thanks for him. So here're some things which I found out from this >> > case: >> > 1. Qt actually dispatches glib events and no additional g_main_loop_run() is >> > necessary for Qt applications. >> > 2. Qt seems to create separate glib context for glib objects which are created >> > in separate QThread objects. >> > 3. To make callbacks be called in separate thread where the certain gst >> > objects were created you need to set them as a handler with >> > gst_bus_set_sync_handler() to make them processed in the context of certain >> > objects and not in the main context. >> >> Hi! >> >> I'm also trying to use GStreamer with Qt, and I'm experiencing some >> weird problems. >> >> 1) I'm not sure if Qt dispatches glib events (on Windows, at least): >> gst_bus_add_watch()'ed callback is never called > > Use gst_bus_add_signal_watch(bus) and then connect to the 'message' > event of the bus. If Qt is built with glib and uses the GMainLoop > internally, the message signal will be emitted in the main thread. Thanks, If you mean that I should use g_signal_connect(bus, "message", ...) after gst_bus_add_signal_watch(bus), then no, unfortunately that does not work. Looks like default windows Qt version does not dispatch glib events. >> 2) gst_bus_set_sync_handler() works, but events that I send from it >> (using Qt::QueuedConnection) seem to never reach the main loop, and I >> don't even know how to debug this > > It's a *synchronous* handler, therefore the callback you set will be > called in the thread context of whoever emitted that message. Sure, I know this :-) I was trying to post Qt events from this synchronous handler to the main thread (using QMetaObject::invokeMethod(&obj, "method", Qt::QueuedConnection) to be precise). Gregory ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
On Mon, May 3, 2010 at 12:21 PM, Gregory Petrosyan
<[hidden email]> wrote: > On Mon, May 3, 2010 at 11:32 AM, Edward Hervey <[hidden email]> wrote: >> On Sun, 2010-05-02 at 17:20 +0400, Gregory Petrosyan wrote: >>> On Sun, Apr 25, 2010 at 10:35 PM, Alexey Chernov <[hidden email]> wrote: >>> > Thank you guys for support, I finally managed to make gstreamer process >>> > callbacks in separate thread. The solution was to set bus handler with >>> > gst_bus_set_sync_handler() instead of gst_bus_add_watch() as wl2776 proposed, >>> > special thanks for him. So here're some things which I found out from this >>> > case: >>> > 1. Qt actually dispatches glib events and no additional g_main_loop_run() is >>> > necessary for Qt applications. >>> > 2. Qt seems to create separate glib context for glib objects which are created >>> > in separate QThread objects. >>> > 3. To make callbacks be called in separate thread where the certain gst >>> > objects were created you need to set them as a handler with >>> > gst_bus_set_sync_handler() to make them processed in the context of certain >>> > objects and not in the main context. >>> >>> Hi! >>> >>> I'm also trying to use GStreamer with Qt, and I'm experiencing some >>> weird problems. >>> >>> 1) I'm not sure if Qt dispatches glib events (on Windows, at least): >>> gst_bus_add_watch()'ed callback is never called >> >> Use gst_bus_add_signal_watch(bus) and then connect to the 'message' >> event of the bus. If Qt is built with glib and uses the GMainLoop >> internally, the message signal will be emitted in the main thread. > > Thanks, > > If you mean that I should use g_signal_connect(bus, "message", ...) > after gst_bus_add_signal_watch(bus), then no, unfortunately that does > not work. Looks like default windows Qt version does not dispatch glib > events. > >>> 2) gst_bus_set_sync_handler() works, but events that I send from it >>> (using Qt::QueuedConnection) seem to never reach the main loop, and I >>> don't even know how to debug this >> >> It's a *synchronous* handler, therefore the callback you set will be >> called in the thread context of whoever emitted that message. > > Sure, I know this :-) > > I was trying to post Qt events from this synchronous handler to the > main thread (using QMetaObject::invokeMethod(&obj, "method", > Qt::QueuedConnection) to be precise). OK, I've nailed down the problem. It is in no way GStreamer-related: I've reimplemented QObject::event() in my widget, and forgot to call the base method. Because of this, events were not dispatching correctly. Hope this message can save hours of debugging for someone :-) Gregory ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
In reply to this post by Alexey Chernov
Hi ,
You do not need to create a separate thread while working on Qt. AFAIK the gst helloworld has a g_main_loop so that the main thread does not exit while gstreamer runs in its own thread. But we don't have this problem while working with Qt GUI apps. I have attached a simple gst-launch style Qt gui app using gstreamer to demo this. Hope it saves time of someone :)
On Fri, Apr 16, 2010 at 1:01 PM, 4ernov <[hidden email]> wrote: Hi, ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel test.tar.bz2 (5K) Download Attachment |
Free forum by Nabble | Edit this page |