Control of pipeline and g_main_loop in a daughter thread
t.i.m at zen.co.uk
Wed Apr 3 06:43:08 PDT 2013
I have only skimmed your explanations in detail, but:
> So the questions are:
> Am I right that the stops and quits have to issued in the thread th==where
> the pipeline and loop are running?
>From a GStreamer point of view, the main loop is merely for convenience.
You don't have to use it. GStreamer pipelines don't care if there's a
thread running a main loop or not, and they don't know anything about
If you do have a thread that runs a main loop / iterates a main context,
it is good practice to do the main pipeline-related operations
(start/stop/pause) from that thread.
However, in theory GStreamer should not care about what threads you
manipulate the pipeline state from, the only rule is that you can't do
it from a GStreamer streaming thread (i.e. a pad-added callback or
GStreamer only cares about 'streaming threads' vs. 'other threads', but
not which of the other threads is doing what. If that doesn't work
right, it might well be a bug.
> Why is this so. What mechanism lets the thread 1, etc. objects ignore the
> thread 0 calls to end them?
> Or, what simple trick did I miss to get the attention of the loop and
> pipeline. I tried adding a wakeup for the context after the quit:
> g_main_loop_quit( m_loop );
> g_main_context_wakeup( g_main_loop_get_context( m_loop )); // context
> is "default"
> which didn't work.
_quit() should wakeup the context already by itself.
> Should I have some method of associating the pipeline and loop in their
> thread? How does the pipeline know which main loop to attach to if there
> are multiple loops?
pipelines don't attach to anything. It's not about "loops" really but
main context (you can have 0-N loops iterating the same context, the
loop bit is just about where in your code you block/wait). You would
typically loop/iterate a main context only in one thread.
You can "marshal" operations to another thread running a main loop,
either by posting an application bus message on the bus and letting it
pick that up, or via g_idle_add() and returning FALSE in the callback,
or via g_main_context_invoke().
More information about the gstreamer-devel