mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-27 14:31:01 +00:00
Doc updates,
Original commit message from CVS: * REQUIREMENTS: * docs/design/part-MT-refcounting.txt: * docs/design/part-clocks.txt: * docs/design/part-conventions.txt: * docs/design/part-gstobject.txt: * docs/design/part-relations.txt: * docs/design/part-standards.txt: * libs/gst/control/dparam.c: (gst_dparam_attach): * libs/gst/control/dparam.h: * libs/gst/control/dparammanager.c: (gst_dpman_add_required_dparam_callback), (gst_dpman_add_required_dparam_direct), (gst_dpman_add_required_dparam_array), (gst_dpman_attach_dparam), (gst_dpman_get_dparam), (gst_dpman_get_dparam_type), (gst_dpman_get_manager), (gst_dpman_bypass_dparam), (gst_dpman_preprocess_asynchronous), (gst_dpman_process_asynchronous), (gst_dpman_process_noop): * libs/gst/control/dparammanager.h: * testsuite/clock/clock2.c: (gst_clock_debug), (element_wait), (main): * testsuite/threads/signals.c: (run_thread), (main): * testsuite/threads/thread.c: (main): * tools/gst-launch.c: (fault_handler_sighandler), (fault_handler_sigaction), (fault_spin): Doc updates, Head backporting. Fix some testcases.
This commit is contained in:
parent
fdcf9acd4b
commit
bd9cd13058
19 changed files with 244 additions and 62 deletions
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
||||||
|
2005-03-10 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* REQUIREMENTS:
|
||||||
|
* docs/design/part-MT-refcounting.txt:
|
||||||
|
* docs/design/part-clocks.txt:
|
||||||
|
* docs/design/part-conventions.txt:
|
||||||
|
* docs/design/part-gstobject.txt:
|
||||||
|
* docs/design/part-relations.txt:
|
||||||
|
* docs/design/part-standards.txt:
|
||||||
|
* libs/gst/control/dparam.c: (gst_dparam_attach):
|
||||||
|
* libs/gst/control/dparam.h:
|
||||||
|
* libs/gst/control/dparammanager.c:
|
||||||
|
(gst_dpman_add_required_dparam_callback),
|
||||||
|
(gst_dpman_add_required_dparam_direct),
|
||||||
|
(gst_dpman_add_required_dparam_array), (gst_dpman_attach_dparam),
|
||||||
|
(gst_dpman_get_dparam), (gst_dpman_get_dparam_type),
|
||||||
|
(gst_dpman_get_manager), (gst_dpman_bypass_dparam),
|
||||||
|
(gst_dpman_preprocess_asynchronous),
|
||||||
|
(gst_dpman_process_asynchronous), (gst_dpman_process_noop):
|
||||||
|
* libs/gst/control/dparammanager.h:
|
||||||
|
* testsuite/clock/clock2.c: (gst_clock_debug), (element_wait),
|
||||||
|
(main):
|
||||||
|
* testsuite/threads/signals.c: (run_thread), (main):
|
||||||
|
* testsuite/threads/thread.c: (main):
|
||||||
|
* tools/gst-launch.c: (fault_handler_sighandler),
|
||||||
|
(fault_handler_sigaction), (fault_spin):
|
||||||
|
Doc updates,
|
||||||
|
Head backporting.
|
||||||
|
Fix some testcases.
|
||||||
|
|
||||||
2005-03-09 Wim Taymans <wim@fluendo.com>
|
2005-03-09 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/gstpad.c: (gst_pad_get_direction):
|
* gst/gstpad.c: (gst_pad_get_direction):
|
||||||
|
|
|
@ -8,7 +8,7 @@ report at http://sourceforge.net/bugs/?group_id=1936.
|
||||||
Required libraries:
|
Required libraries:
|
||||||
===================
|
===================
|
||||||
|
|
||||||
the latest glib2, currently at v2.0.4
|
glib2
|
||||||
libxml2 (also called gnome-xml, available from http://xmlsoft.org/)
|
libxml2 (also called gnome-xml, available from http://xmlsoft.org/)
|
||||||
|
|
||||||
These libraries are all central parts of gnome, and are available from the
|
These libraries are all central parts of gnome, and are available from the
|
||||||
|
|
|
@ -124,6 +124,15 @@ Atomic operations
|
||||||
small fixed size objects in a memchunk. They can also be used to implement a
|
small fixed size objects in a memchunk. They can also be used to implement a
|
||||||
lockfree list or stack.
|
lockfree list or stack.
|
||||||
|
|
||||||
|
Compare and swap
|
||||||
|
|
||||||
|
As part of the atomic operations, compare-and-swap (CAS) can be used to access
|
||||||
|
or update a single property or pointer in an object without having to take a
|
||||||
|
lock.
|
||||||
|
|
||||||
|
This technique is currently not used in GStreamer but might be added in the
|
||||||
|
future in performance critical places.
|
||||||
|
|
||||||
|
|
||||||
Objects
|
Objects
|
||||||
-------
|
-------
|
||||||
|
@ -198,7 +207,8 @@ Objects
|
||||||
corresponding macros. The public object properties are marked in the .h files
|
corresponding macros. The public object properties are marked in the .h files
|
||||||
with /*< public >*/. The public properties that require a lock to be held are
|
with /*< public >*/. The public properties that require a lock to be held are
|
||||||
marked with /*< public >*/ /* with <lock_type> */, where <lock_type> can be
|
marked with /*< public >*/ /* with <lock_type> */, where <lock_type> can be
|
||||||
"LOCK" or "STATE_LOCK" to mark the type(s) of lock to be held.
|
"LOCK" or "STATE_LOCK" or any other lock to mark the type(s) of lock to be
|
||||||
|
held.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -225,7 +235,7 @@ Objects
|
||||||
* Property lifetime
|
* Property lifetime
|
||||||
|
|
||||||
All properties requiring a lock can change after releasing the associated
|
All properties requiring a lock can change after releasing the associated
|
||||||
lock. This means that as soon as long as you hold the lock, the state of the
|
lock. This means that as long as you hold the lock, the state of the
|
||||||
object regarding the locked properties is consistent with the information
|
object regarding the locked properties is consistent with the information
|
||||||
obtained. As soon as the lock is released, any values required from the
|
obtained. As soon as the lock is released, any values required from the
|
||||||
properties might not be valid anymore and can as best be described as a
|
properties might not be valid anymore and can as best be described as a
|
||||||
|
@ -259,6 +269,16 @@ Objects
|
||||||
anymore of the pad. If you need to be sure it is, you need to extend the
|
anymore of the pad. If you need to be sure it is, you need to extend the
|
||||||
critical section to include the operations on the peer.
|
critical section to include the operations on the peer.
|
||||||
|
|
||||||
|
The following code is equivalent to the above but with using the functions
|
||||||
|
to access object properties.
|
||||||
|
|
||||||
|
peer = gst_pad_get_parent (pad);
|
||||||
|
if (peer) {
|
||||||
|
... use peer ...
|
||||||
|
|
||||||
|
gst_object_unref (GST_OBJECT (peer));
|
||||||
|
}
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
Accessing the name of an object makes a copy of the name. The caller of the
|
Accessing the name of an object makes a copy of the name. The caller of the
|
||||||
|
@ -271,6 +291,14 @@ Objects
|
||||||
|
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
name = gst_object_get_name (object);
|
||||||
|
|
||||||
|
... use name ...
|
||||||
|
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
|
||||||
* Accessor methods
|
* Accessor methods
|
||||||
|
|
||||||
|
@ -349,7 +377,7 @@ Objects
|
||||||
* GstIterator
|
* GstIterator
|
||||||
|
|
||||||
GstIterator provides an easier way of retrieving elements in a concurrent
|
GstIterator provides an easier way of retrieving elements in a concurrent
|
||||||
list. The followgin code example is equivalent to the previous example.
|
list. The following code example is equivalent to the previous example.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,10 @@ is defined as follows:
|
||||||
- In PLAYING, the stream time is the delta between the absolute time
|
- In PLAYING, the stream time is the delta between the absolute time
|
||||||
and the base time. The base time is defined as the absolute time minus
|
and the base time. The base time is defined as the absolute time minus
|
||||||
the stream time at the time when the pipeline is set to PLAYING.
|
the stream time at the time when the pipeline is set to PLAYING.
|
||||||
- after a seek, the stream time is set to 0 again.
|
- after a seek, the stream time is set to seek time.
|
||||||
|
|
||||||
|
The stream time is completely managed by the GstPipeline object using the
|
||||||
|
GstClock absolute time.
|
||||||
|
|
||||||
|
|
||||||
Timestamps
|
Timestamps
|
||||||
|
@ -79,7 +82,8 @@ threads. However, registering the same ID for multiple async notifications is
|
||||||
not possible, the callback will only be called once.
|
not possible, the callback will only be called once.
|
||||||
|
|
||||||
None of the wait operations unref the GstClockID, the application is
|
None of the wait operations unref the GstClockID, the application is
|
||||||
responsible for unreffing the ids itself.
|
responsible for unreffing the ids itself. This holds for both periodic and
|
||||||
|
single shot notifications.
|
||||||
|
|
||||||
These clock operations do not operate on the stream time, so the callbacks
|
These clock operations do not operate on the stream time, so the callbacks
|
||||||
will also occur when not in PLAYING state as if the clock just keeps on
|
will also occur when not in PLAYING state as if the clock just keeps on
|
||||||
|
|
|
@ -30,8 +30,6 @@ ASYNC. Where there is a prefix, as in the element flags, this is usually droppe
|
||||||
element flags should be cross-checked with the header, as there are currently two conventions in use: with and without
|
element flags should be cross-checked with the header, as there are currently two conventions in use: with and without
|
||||||
_FLAGS_ in the middle.
|
_FLAGS_ in the middle.
|
||||||
|
|
||||||
FIXME: check flags for consistency.
|
|
||||||
|
|
||||||
Drawing conventions
|
Drawing conventions
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,15 @@ allows for new additions later.
|
||||||
GstElement (inside a bin)
|
GstElement (inside a bin)
|
||||||
GstPad (inside an element)
|
GstPad (inside an element)
|
||||||
|
|
||||||
|
|
||||||
Refcounting
|
Refcounting
|
||||||
-----------
|
-----------
|
||||||
- GObject refcount is not threadsafe.
|
- GObject refcount is not threadsafe. This will be changed in the future.
|
||||||
GStreamer sets it to a constant value on each _ref/_unref()
|
GStreamer for now sets it to a constant value on each _ref/_unref()
|
||||||
and uses an atomic int "refcount" instead for threadsafe refcounting
|
and uses an atomic int "refcount" instead for threadsafe refcounting
|
||||||
This implies you should always use gst_object_ref() and gst_object_unref() !
|
This implies you should always use gst_object_ref() and gst_object_unref() !
|
||||||
|
|
||||||
|
|
||||||
Naming
|
Naming
|
||||||
------
|
------
|
||||||
- names of objects cannot be changed when they are parented
|
- names of objects cannot be changed when they are parented
|
||||||
|
@ -40,6 +42,7 @@ Naming
|
||||||
a more identifiable name. Typically a parent will call _set_name_prefix
|
a more identifiable name. Typically a parent will call _set_name_prefix
|
||||||
on children, taking a lock on them to do so.
|
on children, taking a lock on them to do so.
|
||||||
|
|
||||||
|
|
||||||
Locking
|
Locking
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -47,26 +50,58 @@ The GstObject contains the necessary primitives to lock the object in a
|
||||||
thread-safe manner. This will be used to provide general thread-safety as
|
thread-safe manner. This will be used to provide general thread-safety as
|
||||||
needed. However, this lock is generic, i.e. it covers the whole object.
|
needed. However, this lock is generic, i.e. it covers the whole object.
|
||||||
|
|
||||||
|
The object LOCK is a very lowlevel lock that should only be held to access
|
||||||
|
the object properties for short periods of code.
|
||||||
|
|
||||||
All members of the GstObject structure marked as
|
All members of the GstObject structure marked as
|
||||||
/*< public >*/ /* with LOCK */
|
/*< public >*/ /* with LOCK */
|
||||||
are protected by this lock. These members can only be accessed for reading
|
are protected by this lock. These members can only be accessed for reading
|
||||||
or writing while the lock is held.
|
or writing while the lock is held. All members should be copied or reffed
|
||||||
|
if they are used after releasing the LOCK.
|
||||||
|
|
||||||
Note that this does *not* mean that no other thread can modify the object at
|
Note that this does *not* mean that no other thread can modify the object at
|
||||||
the same time that the lock is held. It only means that any two sections of
|
the same time that the lock is held. It only means that any two sections of
|
||||||
code that obey the lock are guaranteed to not be running simultaneously. "The
|
code that obey the lock are guaranteed to not be running simultaneously. "The
|
||||||
lock is voluntary and cooperative".
|
lock is voluntary and cooperative".
|
||||||
|
|
||||||
This lock will ideally be used for parentage and refcounting, which is
|
This lock will ideally be used for parentage, flags and naming, which is
|
||||||
reasonable, since they are the only possible things to protect in the
|
reasonable, since they are the only possible things to protect in the
|
||||||
GstObject.
|
GstObject.
|
||||||
|
|
||||||
|
|
||||||
|
Locking order
|
||||||
|
-------------
|
||||||
|
|
||||||
|
In parent-child situations the lock of the parent must always be taken first
|
||||||
|
before taking the lock of the child. It is NOT allowed to hold the child
|
||||||
|
lock before taking the parent lock.
|
||||||
|
|
||||||
|
This policy allows for parents to iterate their children and setting properties
|
||||||
|
on them.
|
||||||
|
|
||||||
|
Whenever a nested lock needs to be taken on objects not involved in a
|
||||||
|
parent-child relation (eg. pads), an explictic locking order has to be defined.
|
||||||
|
|
||||||
|
|
||||||
Path Generation
|
Path Generation
|
||||||
---------------
|
---------------
|
||||||
FIXME: rethink this ?
|
|
||||||
|
|
||||||
Due to the base nature of the GstObject, it becomes the only reasonable place
|
Due to the base nature of the GstObject, it becomes the only reasonable place
|
||||||
to put this particular function (_get_path_string). It will generate a string
|
to put this particular function (_get_path_string). It will generate a string
|
||||||
describing the parent hierarchy of a given GstObject. Currently it is forced
|
describing the parent hierarchy of a given GstObject.
|
||||||
to use several child-class-specific functions, because we do not properly use
|
|
||||||
the base capabilities (parentage, etc.) of GstObject properly.
|
|
||||||
|
Flags
|
||||||
|
-----
|
||||||
|
|
||||||
|
Each object in the GStreamer object hierarchy can have flags associated with it,
|
||||||
|
which are used to describe a state or a feature of the object.
|
||||||
|
GstObject has flags to mark its lifecycle: FLOATING, DISPOSING and DESTROYED.
|
||||||
|
|
||||||
|
|
||||||
|
Class signals
|
||||||
|
-------------
|
||||||
|
|
||||||
|
It is possible to know when a new object is loaded by connecting to the
|
||||||
|
GstObjectClass signal. This feature is not very much used and might be removed
|
||||||
|
at some point.
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
Object relation types
|
Object relation types
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
This document describes the relations between objects that exist in GStreamer.
|
||||||
|
It will also describe the way of handling the relation wrt locking and
|
||||||
|
refcounting.
|
||||||
|
|
||||||
1) parent-child relation
|
1) parent-child relation
|
||||||
|
|
||||||
+---------+ +-------+
|
+---------+ +-------+
|
||||||
|
|
|
@ -1,16 +1,40 @@
|
||||||
Ownership of dynamic objects
|
Ownership of dynamic objects
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Any object-oriented system or language that doesn't have automatic garbage collection has many potential pitfalls as
|
Any object-oriented system or language that doesn't have automatic garbage
|
||||||
far as the pointers go. Therefore, some standards must be adhered to as far as who owns what.
|
collection has many potential pitfalls as far as the pointers go. Therefore,
|
||||||
|
some standards must be adhered to as far as who owns what.
|
||||||
|
|
||||||
Strings:
|
Strings
|
||||||
Arguments passed into a function are owned by the caller, and the function will make a copy of the string for its own
|
-------
|
||||||
internal use. The string should be const gchar *. Strings returned from a function remain the property of the
|
|
||||||
function called, and the caller must make a copy if it is to use the string for an extended duration.
|
Arguments passed into a function are owned by the caller, and the function
|
||||||
|
will make a copy of the string for its own internal use. The string should
|
||||||
|
be const gchar *. Strings returned from a function are always a copy of the
|
||||||
|
original and should be freed after usage by the caller.
|
||||||
|
|
||||||
|
ex:
|
||||||
|
|
||||||
|
name = gst_element_get_name (element); /* copy of name is made */
|
||||||
|
.. use name ..
|
||||||
|
g_free (name); /* free after usage */
|
||||||
|
|
||||||
|
|
||||||
|
Objects
|
||||||
|
-------
|
||||||
|
|
||||||
|
Objects passed into a function are owned by the caller, any additional
|
||||||
|
reference held to the object after leaving the function should increase the
|
||||||
|
refcount of that object.
|
||||||
|
|
||||||
|
Objects returned from a function are owned by the caller. This means that the
|
||||||
|
called should _free() or _unref() the object after usage.
|
||||||
|
|
||||||
|
ex:
|
||||||
|
|
||||||
|
peer = gst_pad_get_peer (pad); /* peer with increased refcount */
|
||||||
|
if (peer) {
|
||||||
|
.. use peer ..
|
||||||
|
gst_object_unref (GST_OBJECT (peer)); /* unref peer after usage */
|
||||||
|
}
|
||||||
|
|
||||||
Objects:
|
|
||||||
The ownership of an object during a function call depends on the type of function. If the function is simply returning
|
|
||||||
something from the object, such as _get_name(), the caller retains ownership. If the object passed is to be
|
|
||||||
manipulated in some way, it is generally the case that the function will take over the ownership. This should be
|
|
||||||
expressed as a reference increment on that object, but isn't in the general case (yet).
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* GStreamer
|
/* GStreamer
|
||||||
* Copyright (C) 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
|
* Copyright (C) 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
|
||||||
*
|
*
|
||||||
* gstdparam.c: Dynamic Parameter functionality
|
* gstdparam.c: Dynamic Parameter
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -247,10 +247,10 @@ gst_dparam_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_dparam_do_update_default:
|
* gst_dparam_do_update_default:
|
||||||
* @dparam:
|
* @dparam: the parameter to update
|
||||||
* @timestamp:
|
* @timestamp: when should the update take place
|
||||||
* @value:
|
* @value: the new value
|
||||||
* @update_info:
|
* @update_info: unused here
|
||||||
*
|
*
|
||||||
* Default implementation for changing a dynamic parameter.
|
* Default implementation for changing a dynamic parameter.
|
||||||
* Subclasses might overwrite the behaviour of this.
|
* Subclasses might overwrite the behaviour of this.
|
||||||
|
@ -321,6 +321,7 @@ void
|
||||||
gst_dparam_attach (GstDParam * dparam, GstDParamManager * manager,
|
gst_dparam_attach (GstDParam * dparam, GstDParamManager * manager,
|
||||||
GParamSpec * param_spec, gchar * unit_name)
|
GParamSpec * param_spec, gchar * unit_name)
|
||||||
{
|
{
|
||||||
|
GValue value = { 0, };
|
||||||
|
|
||||||
g_return_if_fail (dparam != NULL);
|
g_return_if_fail (dparam != NULL);
|
||||||
g_return_if_fail (GST_IS_DPARAM (dparam));
|
g_return_if_fail (GST_IS_DPARAM (dparam));
|
||||||
|
@ -339,6 +340,29 @@ gst_dparam_attach (GstDParam * dparam, GstDParamManager * manager,
|
||||||
GST_DPARAM_IS_LOG (dparam) = gst_unitconv_unit_is_logarithmic (unit_name);
|
GST_DPARAM_IS_LOG (dparam) = gst_unitconv_unit_is_logarithmic (unit_name);
|
||||||
GST_DEBUG ("attaching %s to dparam %p", GST_DPARAM_NAME (dparam), dparam);
|
GST_DEBUG ("attaching %s to dparam %p", GST_DPARAM_NAME (dparam), dparam);
|
||||||
|
|
||||||
|
// get default value from param-spec and set in dparam
|
||||||
|
g_value_init (&value, param_spec->value_type);
|
||||||
|
g_param_value_set_default (param_spec, &value);
|
||||||
|
switch (G_PARAM_SPEC_VALUE_TYPE (param_spec)) {
|
||||||
|
case G_TYPE_FLOAT:
|
||||||
|
dparam->value_float = g_value_get_float (&value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case G_TYPE_DOUBLE:
|
||||||
|
dparam->value_double = g_value_get_double (&value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case G_TYPE_INT:
|
||||||
|
dparam->value_int = g_value_get_int (&value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case G_TYPE_INT64:
|
||||||
|
dparam->value_int64 = g_value_get_int64 (&value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -55,7 +55,6 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstDParamClass GstDParamClass;
|
typedef struct _GstDParamClass GstDParamClass;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_DPARAM_UPDATE_FIRST,
|
GST_DPARAM_UPDATE_FIRST,
|
||||||
GST_DPARAM_UPDATE_NORMAL
|
GST_DPARAM_UPDATE_NORMAL
|
||||||
|
|
|
@ -205,7 +205,10 @@ gst_dpman_add_required_dparam_callback (GstDParamManager * dpman,
|
||||||
dpwrap =
|
dpwrap =
|
||||||
gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_CALLBACK);
|
gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_CALLBACK);
|
||||||
|
|
||||||
g_return_val_if_fail (dpwrap != NULL, FALSE);
|
if (!dpwrap) {
|
||||||
|
GST_INFO ("failed to obtain a new dparam wrapper");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG ("adding required callback dparam '%s'",
|
GST_DEBUG ("adding required callback dparam '%s'",
|
||||||
g_param_spec_get_name (param_spec));
|
g_param_spec_get_name (param_spec));
|
||||||
|
@ -244,7 +247,10 @@ gst_dpman_add_required_dparam_direct (GstDParamManager * dpman,
|
||||||
dpwrap =
|
dpwrap =
|
||||||
gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_DIRECT);
|
gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_DIRECT);
|
||||||
|
|
||||||
g_return_val_if_fail (dpwrap != NULL, FALSE);
|
if (!dpwrap) {
|
||||||
|
GST_INFO ("failed to obtain a new dparam wrapper");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG ("adding required direct dparam '%s'",
|
GST_DEBUG ("adding required direct dparam '%s'",
|
||||||
g_param_spec_get_name (param_spec));
|
g_param_spec_get_name (param_spec));
|
||||||
|
@ -282,7 +288,10 @@ gst_dpman_add_required_dparam_array (GstDParamManager * dpman,
|
||||||
dpwrap =
|
dpwrap =
|
||||||
gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_ARRAY);
|
gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_ARRAY);
|
||||||
|
|
||||||
g_return_val_if_fail (dpwrap != NULL, FALSE);
|
if (!dpwrap) {
|
||||||
|
GST_INFO ("failed to obtain a new dparam wrapper");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG ("adding required array dparam '%s'",
|
GST_DEBUG ("adding required array dparam '%s'",
|
||||||
g_param_spec_get_name (param_spec));
|
g_param_spec_get_name (param_spec));
|
||||||
|
@ -353,7 +362,12 @@ gst_dpman_attach_dparam (GstDParamManager * dpman, const gchar * dparam_name,
|
||||||
|
|
||||||
dpwrap = gst_dpman_get_wrapper (dpman, dparam_name);
|
dpwrap = gst_dpman_get_wrapper (dpman, dparam_name);
|
||||||
|
|
||||||
g_return_val_if_fail (dpwrap != NULL, FALSE);
|
if (!dpwrap) {
|
||||||
|
GST_INFO ("failed to obtain get the dparam wrapper for parameter '%s'",
|
||||||
|
dparam_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// FIXME: if these are triggered convert them to messages + returns as well
|
||||||
g_return_val_if_fail (dpwrap->value != NULL, FALSE);
|
g_return_val_if_fail (dpwrap->value != NULL, FALSE);
|
||||||
g_return_val_if_fail (G_PARAM_SPEC_VALUE_TYPE (dpwrap->param_spec) ==
|
g_return_val_if_fail (G_PARAM_SPEC_VALUE_TYPE (dpwrap->param_spec) ==
|
||||||
GST_DPARAM_TYPE (dparam), FALSE);
|
GST_DPARAM_TYPE (dparam), FALSE);
|
||||||
|
@ -407,7 +421,12 @@ gst_dpman_get_dparam (GstDParamManager * dpman, const gchar * dparam_name)
|
||||||
g_return_val_if_fail (dparam_name != NULL, NULL);
|
g_return_val_if_fail (dparam_name != NULL, NULL);
|
||||||
|
|
||||||
dpwrap = gst_dpman_get_wrapper (dpman, dparam_name);
|
dpwrap = gst_dpman_get_wrapper (dpman, dparam_name);
|
||||||
g_return_val_if_fail (dpwrap != NULL, NULL);
|
|
||||||
|
if (!dpwrap) {
|
||||||
|
GST_INFO ("failed to obtain get the dparam wrapper for parameter '%s'",
|
||||||
|
dparam_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return dpwrap->dparam;
|
return dpwrap->dparam;
|
||||||
}
|
}
|
||||||
|
@ -431,7 +450,12 @@ gst_dpman_get_dparam_type (GstDParamManager * dpman, const gchar * dparam_name)
|
||||||
g_return_val_if_fail (dparam_name != NULL, 0);
|
g_return_val_if_fail (dparam_name != NULL, 0);
|
||||||
|
|
||||||
dpwrap = gst_dpman_get_wrapper (dpman, dparam_name);
|
dpwrap = gst_dpman_get_wrapper (dpman, dparam_name);
|
||||||
g_return_val_if_fail (dpwrap != NULL, 0);
|
|
||||||
|
if (!dpwrap) {
|
||||||
|
GST_INFO ("failed to obtain get the dparam wrapper for parameter '%s'",
|
||||||
|
dparam_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return G_VALUE_TYPE (dpwrap->value);
|
return G_VALUE_TYPE (dpwrap->value);
|
||||||
}
|
}
|
||||||
|
@ -612,7 +636,7 @@ gst_dpman_set_parent (GstDParamManager * dpman, GstElement * parent)
|
||||||
* Fetch the GstElement that parameters are handled by this manager.
|
* Fetch the GstElement that parameters are handled by this manager.
|
||||||
*
|
*
|
||||||
* Returns: the GstDParamManager which belongs to this element or NULL
|
* Returns: the GstDParamManager which belongs to this element or NULL
|
||||||
* if it doesn't exist
|
* if it doesn't exist. Do not call g_object_unref() on it.
|
||||||
*/
|
*/
|
||||||
GstDParamManager *
|
GstDParamManager *
|
||||||
gst_dpman_get_manager (GstElement * parent)
|
gst_dpman_get_manager (GstElement * parent)
|
||||||
|
@ -623,6 +647,7 @@ gst_dpman_get_manager (GstElement * parent)
|
||||||
g_return_val_if_fail (GST_IS_ELEMENT (parent), NULL);
|
g_return_val_if_fail (GST_IS_ELEMENT (parent), NULL);
|
||||||
|
|
||||||
dpman = (GstDParamManager *) g_hash_table_lookup (_element_registry, parent);
|
dpman = (GstDParamManager *) g_hash_table_lookup (_element_registry, parent);
|
||||||
|
/* FIXME: shouldn't this be g_object_ref(dpman); */
|
||||||
return dpman;
|
return dpman;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,7 +674,7 @@ gst_dpman_bypass_dparam (GstDParamManager * dpman, const gchar * dparam_name)
|
||||||
g_return_if_fail (dpwrap != NULL);
|
g_return_if_fail (dpwrap != NULL);
|
||||||
|
|
||||||
if (dpwrap->dparam != NULL) {
|
if (dpwrap->dparam != NULL) {
|
||||||
g_warning ("Bypassing attached dparam '%s'. It will be detached",
|
GST_WARNING ("Bypassing attached dparam '%s'. It will be detached",
|
||||||
dparam_name);
|
dparam_name);
|
||||||
gst_dpman_detach_dparam (dpman, dparam_name);
|
gst_dpman_detach_dparam (dpman, dparam_name);
|
||||||
}
|
}
|
||||||
|
@ -835,7 +860,7 @@ gst_dpman_preprocess_asynchronous (GstDParamManager * dpman, guint frames,
|
||||||
|
|
||||||
|
|
||||||
if (GST_DPMAN_RATE (dpman) == 0) {
|
if (GST_DPMAN_RATE (dpman) == 0) {
|
||||||
g_warning ("The element hasn't given GstDParamManager a frame rate");
|
GST_WARNING ("The element hasn't given GstDParamManager a frame rate");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
dpman->rate_ratio = (guint) (1000000000LL / (gint64) GST_DPMAN_RATE (dpman));
|
dpman->rate_ratio = (guint) (1000000000LL / (gint64) GST_DPMAN_RATE (dpman));
|
||||||
|
@ -950,14 +975,14 @@ gst_dpman_process_asynchronous (GstDParamManager * dpman, guint frame_count)
|
||||||
GST_DEBUG ("in gst_dpman_process_asynchronous");
|
GST_DEBUG ("in gst_dpman_process_asynchronous");
|
||||||
|
|
||||||
if (frame_count >= dpman->num_frames) {
|
if (frame_count >= dpman->num_frames) {
|
||||||
g_warning ("there is no more buffer to process");
|
GST_WARNING ("there is no more buffer to process");
|
||||||
dpman->next_update_frame = dpman->num_frames;
|
dpman->next_update_frame = dpman->num_frames;
|
||||||
dpman->frames_to_process = 0;
|
dpman->frames_to_process = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_count != dpwrap->next_update_frame) {
|
if (frame_count != dpwrap->next_update_frame) {
|
||||||
g_warning ("frame count %u does not match update frame %u",
|
GST_WARNING ("frame count %u does not match update frame %u",
|
||||||
frame_count, dpwrap->next_update_frame);
|
frame_count, dpwrap->next_update_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1040,7 +1065,7 @@ gst_dpman_preprocess_noop (GstDParamManager * dpman, guint frames,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_dpman_process_noop (GstDParamManager * dpman, guint frame_count)
|
gst_dpman_process_noop (GstDParamManager * dpman, guint frame_count)
|
||||||
{
|
{
|
||||||
g_warning
|
GST_WARNING
|
||||||
("gst_dpman_process_noop should never be called - something might be wrong with your processing loop");
|
("gst_dpman_process_noop should never be called - something might be wrong with your processing loop");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,9 @@ struct _GstDParamAsyncToUpdate {
|
||||||
(dpman->next_update_frame < dpman->num_frames \
|
(dpman->next_update_frame < dpman->num_frames \
|
||||||
&& (GST_DPMAN_PROCESSFUNC(dpman)(dpman, frame_count))))
|
&& (GST_DPMAN_PROCESSFUNC(dpman)(dpman, frame_count))))
|
||||||
|
|
||||||
|
/* FIXME: this should pass dpwrap->dparam as the first arg
|
||||||
|
* the first arg in callback is usually object that triggered the callback
|
||||||
|
*/
|
||||||
#define GST_DPMAN_CALLBACK_UPDATE(dpwrap, value) ((dpwrap->update_func)(value, dpwrap->update_data))
|
#define GST_DPMAN_CALLBACK_UPDATE(dpwrap, value) ((dpwrap->update_func)(value, dpwrap->update_data))
|
||||||
|
|
||||||
void _gst_dpman_initialize(void);
|
void _gst_dpman_initialize(void);
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
static GstClock *clock = NULL;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_clock_debug (GstClock * clock, GstElement * fakesink)
|
gst_clock_debug (GstClock * clock, GstElement * fakesink)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +32,7 @@ element_wait (GstElement * element, GstClockTime time)
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
GstClock *clock = NULL;
|
||||||
GstElement *pipeline, *fakesrc, *fakesink;
|
GstElement *pipeline, *fakesrc, *fakesink;
|
||||||
|
|
||||||
gst_init (&argc, &argv);
|
gst_init (&argc, &argv);
|
||||||
|
|
|
@ -201,8 +201,10 @@ run_thread (GstTest * test)
|
||||||
gst_test_do_signal2 (test);
|
gst_test_do_signal2 (test);
|
||||||
if (TESTNUM == 3)
|
if (TESTNUM == 3)
|
||||||
gst_test_do_prop (test);
|
gst_test_do_prop (test);
|
||||||
if ((i++ % 10000) == 0)
|
if ((i++ % 10000) == 0) {
|
||||||
g_print (".");
|
g_print (".");
|
||||||
|
g_usleep (1); /* context switch */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -219,7 +221,7 @@ main (int argc, char **argv)
|
||||||
test1 = g_object_new (GST_TYPE_TEST, NULL);
|
test1 = g_object_new (GST_TYPE_TEST, NULL);
|
||||||
test2 = g_object_new (GST_TYPE_TEST, NULL);
|
test2 = g_object_new (GST_TYPE_TEST, NULL);
|
||||||
|
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 20; i++) {
|
||||||
g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
|
g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
|
||||||
g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
|
g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ main (gint argc, gchar * argv[])
|
||||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
g_print ("running ...\n");
|
g_print ("running ...\n");
|
||||||
while (gst_bin_iterate (GST_BIN (pipeline)));
|
while (gst_bin_iterate (GST_BIN (pipeline)));
|
||||||
|
g_print ("done ...\n");
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||||
}
|
}
|
||||||
if (TESTNUM == 4) {
|
if (TESTNUM == 4) {
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
static GstClock *clock = NULL;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_clock_debug (GstClock * clock, GstElement * fakesink)
|
gst_clock_debug (GstClock * clock, GstElement * fakesink)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +32,7 @@ element_wait (GstElement * element, GstClockTime time)
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
GstClock *clock = NULL;
|
||||||
GstElement *pipeline, *fakesrc, *fakesink;
|
GstElement *pipeline, *fakesrc, *fakesink;
|
||||||
|
|
||||||
gst_init (&argc, &argv);
|
gst_init (&argc, &argv);
|
||||||
|
|
|
@ -201,8 +201,10 @@ run_thread (GstTest * test)
|
||||||
gst_test_do_signal2 (test);
|
gst_test_do_signal2 (test);
|
||||||
if (TESTNUM == 3)
|
if (TESTNUM == 3)
|
||||||
gst_test_do_prop (test);
|
gst_test_do_prop (test);
|
||||||
if ((i++ % 10000) == 0)
|
if ((i++ % 10000) == 0) {
|
||||||
g_print (".");
|
g_print (".");
|
||||||
|
g_usleep (1); /* context switch */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -219,7 +221,7 @@ main (int argc, char **argv)
|
||||||
test1 = g_object_new (GST_TYPE_TEST, NULL);
|
test1 = g_object_new (GST_TYPE_TEST, NULL);
|
||||||
test2 = g_object_new (GST_TYPE_TEST, NULL);
|
test2 = g_object_new (GST_TYPE_TEST, NULL);
|
||||||
|
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 20; i++) {
|
||||||
g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
|
g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
|
||||||
g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
|
g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ main (gint argc, gchar * argv[])
|
||||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
g_print ("running ...\n");
|
g_print ("running ...\n");
|
||||||
while (gst_bin_iterate (GST_BIN (pipeline)));
|
while (gst_bin_iterate (GST_BIN (pipeline)));
|
||||||
|
g_print ("done ...\n");
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||||
}
|
}
|
||||||
if (TESTNUM == 4) {
|
if (TESTNUM == 4) {
|
||||||
|
|
|
@ -143,15 +143,17 @@ fault_handler_sighandler (int signum)
|
||||||
{
|
{
|
||||||
fault_restore ();
|
fault_restore ();
|
||||||
|
|
||||||
|
/* printf is used instead of g_print(), since it's less likely to
|
||||||
|
* deadlock */
|
||||||
switch (signum) {
|
switch (signum) {
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
g_print ("Caught SIGSEGV\n");
|
printf ("Caught SIGSEGV\n");
|
||||||
break;
|
break;
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
g_print ("Caught SIGQUIT\n");
|
printf ("Caught SIGQUIT\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_print ("signo: %d\n", signum);
|
printf ("signo: %d\n", signum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,17 +167,19 @@ fault_handler_sigaction (int signum, siginfo_t * si, void *misc)
|
||||||
{
|
{
|
||||||
fault_restore ();
|
fault_restore ();
|
||||||
|
|
||||||
|
/* printf is used instead of g_print(), since it's less likely to
|
||||||
|
* deadlock */
|
||||||
switch (si->si_signo) {
|
switch (si->si_signo) {
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
g_print ("Caught SIGSEGV accessing address %p\n", si->si_addr);
|
printf ("Caught SIGSEGV accessing address %p\n", si->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
g_print ("Caught SIGQUIT\n");
|
printf ("Caught SIGQUIT\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_print ("signo: %d\n", si->si_signo);
|
printf ("signo: %d\n", si->si_signo);
|
||||||
g_print ("errno: %d\n", si->si_errno);
|
printf ("errno: %d\n", si->si_errno);
|
||||||
g_print ("code: %d\n", si->si_code);
|
printf ("code: %d\n", si->si_code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +198,7 @@ fault_spin (void)
|
||||||
wait (NULL);
|
wait (NULL);
|
||||||
|
|
||||||
/* FIXME how do we know if we were run by libtool? */
|
/* FIXME how do we know if we were run by libtool? */
|
||||||
g_print ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, "
|
printf ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, "
|
||||||
"Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ());
|
"Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ());
|
||||||
while (spinning)
|
while (spinning)
|
||||||
g_usleep (1000000);
|
g_usleep (1000000);
|
||||||
|
|
Loading…
Reference in a new issue