mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-05 16:06:43 +00:00
77 lines
3.8 KiB
Text
77 lines
3.8 KiB
Text
|
-*- Mode: text -*-
|
||
|
|
||
|
Sometimes it's difficult to use GStreamer in real applications where the GUI and
|
||
|
the GStreamer pipeline are in different threads. You have to somehow make sure
|
||
|
that the object is not modifying its properties while you get and set them. This
|
||
|
document is a brief outline of a potential fix to this issue.
|
||
|
|
||
|
* When is it safe to get or set properties?
|
||
|
|
||
|
Well, it is only safe to do so when other threads are not accessing an object.
|
||
|
So, from the main thread, it is only safe to query or modify properties on an
|
||
|
object when it is not in the RUNNING state, because when it is RUNNING its
|
||
|
properties are potentially changing in the thread of execution.
|
||
|
|
||
|
The only place that it is safe to get or set properties while in the RUNNING
|
||
|
state is from within the thread of execution. Thus, something within the
|
||
|
iteration loop of the thread must check to see if there are pending property
|
||
|
changes or queries. There are two places this could be done, from within
|
||
|
gstthread itself and from within the scheduler. Doing it from gstthread sounds
|
||
|
like a good idea because it keeps more code out of the scheduler, but is also
|
||
|
bad in a way because it requires a gstthread-specific api to proxy prop_set and
|
||
|
prop_get. Setting it in the scheduler sounds good because of its finer
|
||
|
granularity, but might be bad because it would clutter the scheduler a bit more.
|
||
|
|
||
|
I propose to go with the scheduler-based solution based on system response time
|
||
|
and out of potentials for integration with gst_clock_wait.
|
||
|
|
||
|
* Implementation
|
||
|
|
||
|
We do want to preserve some measure of generality, however. Considering that
|
||
|
more threadsafety issues could pop up in the future, it would be nice to have
|
||
|
one function to call from the scheduler, in the interests of code
|
||
|
simplification. This function will be present in some elements and not in
|
||
|
others, and will be modified at run time, so we will make it a function pointer
|
||
|
within the GstElement struct.
|
||
|
|
||
|
struct _GstElement {
|
||
|
...
|
||
|
void (*pre_run_func) (GstElement *);
|
||
|
void (*post_run_func) (GstElement *);
|
||
|
}
|
||
|
|
||
|
Only the managing bin of an element is allowed to set that function, because
|
||
|
presumably that bin would know something about how to schedule the element.
|
||
|
Then, in the scheduler, before we call chain functions and before we switch into
|
||
|
loop functions:
|
||
|
|
||
|
if (element->pre_run_func)
|
||
|
element->pre_run_func (element);
|
||
|
|
||
|
Then, to get or set properties, we use the new functions gst_element_get or
|
||
|
gst_element_set. _set would add the property name and a gvalue onto a queue
|
||
|
(probably a GAsyncQueue). Then the pre_run_func would go ahead and set the
|
||
|
properties. _get is a little more tricky; _set doesn't hardly block at all,
|
||
|
although it's not instantaneous. With _get though, you really don't know what
|
||
|
the properties are until you query them. The best thing would be to connect to
|
||
|
the ::notify signal, which executes within the thread of interest. However, say
|
||
|
you really want to use _get. Hmm. I think that it would have to block. On what?
|
||
|
Well, probably on an element's mutex. So it seems we might need a
|
||
|
post_run_func too, to unlock the mutex. We can use the GstObject lock for this.
|
||
|
|
||
|
But we need a little more. How do we know whether or not just calling
|
||
|
g_object_get/set is ok? I'm thinking this whole prop set/get proxy thing should
|
||
|
not be abstracted away, that it should be contained in gstelement.c. There are
|
||
|
more kinds of bins that need threadsafety than just gstthread (I'm thinking
|
||
|
about jack here). So, we can add on a GAsyncQueue *prop_set_queue; to the
|
||
|
GstElement struct, and only initialize it in certain managing bins. Then, we can
|
||
|
set a flag on gstelement, GST_ELEMENT_USE_THREADSAFE_PROPERTIES. If this flag is
|
||
|
set (by the managing bin), do all this complicated mess; otherwise use the
|
||
|
gobject native functionality.
|
||
|
|
||
|
So, this is the plan. We'll see how the implementation goes. This should make MT
|
||
|
gst programming much easier.
|
||
|
|
||
|
wingo.
|
||
|
25 May 2002.
|