more tests (and fixes) for the controller more docs for the controller integrated companies docs for the adapter

Original commit message from CVS:
more tests (and fixes) for the controller
more docs for the controller
integrated companies docs for the adapter
This commit is contained in:
Stefan Kost 2005-08-05 10:02:44 +00:00
parent 9711c54975
commit a34f2613f9
75 changed files with 717 additions and 100 deletions

View file

@ -1,3 +1,30 @@
2005-08-05 Stefan Kost <ensonic@users.sf.net>
* check/gst-libs/controller.c: (gst_test_mono_source_get_property),
(gst_test_mono_source_set_property),
(gst_test_mono_source_class_init), (GST_START_TEST),
(gst_controller_suite):
* docs/gst/gstreamer-docs.sgml:
* docs/gst/gstreamer-sections.txt:
* docs/gst/gstreamer.types:
* docs/libs/gstreamer-libs-docs.sgml:
* docs/libs/gstreamer-libs-sections.txt:
* gst/base/gstadapter.c:
* libs/gst/controller/gst-controller.c:
(gst_controlled_property_new), (gst_controlled_property_free),
(gst_controller_new_valist),
(gst_controller_remove_properties_valist),
(gst_controller_sink_values), (_gst_controller_finalize):
* libs/gst/controller/gst-controller.h:
* libs/gst/controller/gst-helper.c:
(gst_object_control_properties), (gst_object_uncontrol_properties),
(gst_object_get_controller), (gst_object_set_controller),
(gst_object_sink_values), (gst_object_get_value_arrays),
(gst_object_get_value_array):
more tests (and fixes) for the controller
more docs for the controller
integrated companies docs for the adapter
2005-08-05 Thomas Vander Stichele <thomas at apestaart dot org>
* check/elements/gstfakesrc.c: (setup_fakesrc), (cleanup_fakesrc),

View file

@ -30,7 +30,7 @@ enum
{
ARG_ULONG = 1,
ARG_DOUBLE,
ARG_SWITCH,
ARG_BOOLEAN,
ARG_COUNT
};
@ -47,6 +47,9 @@ typedef struct _GstTestMonoSourceClass GstTestMonoSourceClass;
struct _GstTestMonoSource
{
GstElement parent;
gulong val_ulong;
gdouble val_double;
gboolean val_bool;
};
struct _GstTestMonoSourceClass
{
@ -59,14 +62,17 @@ static void
gst_test_mono_source_get_property (GObject * object,
guint property_id, GValue * value, GParamSpec * pspec)
{
//GstTestMonoSource *self = GST_TEST_MONO_SOURCE(object);
GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
switch (property_id) {
case ARG_ULONG:
g_value_set_ulong (value, self->val_ulong);
break;
default:{
case ARG_DOUBLE:
g_value_set_double (value, self->val_double);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
break;
}
}
@ -75,14 +81,17 @@ static void
gst_test_mono_source_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec)
{
//GstTestMonoSource *self = GST_TEST_MONO_SOURCE(object);
GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
switch (property_id) {
case ARG_ULONG:
self->val_ulong = g_value_get_ulong (value);
break;
default:{
case ARG_DOUBLE:
self->val_double = g_value_get_double (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
break;
}
}
@ -100,6 +109,12 @@ gst_test_mono_source_class_init (GstTestMonoSourceClass * klass)
"ulong prop",
"ulong number parameter for the test_mono_source",
0, G_MAXULONG, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_DOUBLE,
g_param_spec_double ("double",
"double prop",
"double number parameter for the test_mono_source",
0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
}
static void
@ -177,17 +192,13 @@ GST_START_TEST (controller_new_fail)
ctrl = gst_controller_new (G_OBJECT (elem), "_schrompf_", NULL);
fail_unless (ctrl == NULL, NULL);
/* that property exists, but is not controllable */
ASSERT_CRITICAL (ctrl = gst_controller_new (G_OBJECT (elem), "name", NULL));
fail_unless (ctrl == NULL, NULL);
g_object_unref (elem);
}
GST_END_TEST;
/* tests for an element with controlled params */
GST_START_TEST (controller_new_okay)
GST_START_TEST (controller_new_okay1)
{
GstController *ctrl;
GstElement *elem;
@ -204,6 +215,121 @@ GST_START_TEST (controller_new_okay)
GST_END_TEST;
/* controlling several params should return the same controller */
GST_START_TEST (controller_new_okay2)
{
GstController *ctrl1, *ctrl2;
GstElement *elem;
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl1 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
fail_unless (ctrl1 != NULL, NULL);
/* that property should exist and should be controllable */
ctrl2 = gst_controller_new (G_OBJECT (elem), "double", NULL);
fail_unless (ctrl2 != NULL, NULL);
fail_unless (ctrl1 == ctrl2, NULL);
g_object_unref (ctrl2);
g_object_unref (ctrl1);
g_object_unref (elem);
}
GST_END_TEST;
/* controlling a params twice should be handled */
GST_START_TEST (controller_param_twice)
{
GstController *ctrl;
GstElement *elem;
gboolean res;
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "ulong", NULL);
fail_unless (ctrl != NULL, NULL);
/* it should have been added at least once, let remove it */
res = gst_controller_remove_properties (ctrl, "ulong", NULL);
fail_unless (res, NULL);
/* removing it agian should not work */
res = gst_controller_remove_properties (ctrl, "ulong", NULL);
fail_unless (!res, NULL);
g_object_unref (ctrl);
g_object_unref (elem);
}
GST_END_TEST;
/* tests if we cleanup properly */
GST_START_TEST (controller_finalize)
{
GstController *ctrl;
GstElement *elem;
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
fail_unless (ctrl != NULL, NULL);
/* free the controller */
g_object_unref (ctrl);
/* object shouldn't have a controller anymore */
ctrl = gst_object_get_controller (G_OBJECT (elem));
fail_unless (ctrl == NULL, NULL);
g_object_unref (elem);
}
GST_END_TEST;
/* test timed value handling without interpolation */
GST_START_TEST (controller_interpolate_none)
{
GstController *ctrl;
GstElement *elem;
gboolean res;
GValue val_ulong = { 0, };
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
fail_unless (ctrl != NULL, NULL);
/* set interpolation mode */
gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
/* set control values */
g_value_init (&val_ulong, G_TYPE_ULONG);
g_value_set_ulong (&val_ulong, 0);
res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
fail_unless (res, NULL);
g_value_set_ulong (&val_ulong, 100);
res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
fail_unless (res, NULL);
/* now pull in values for some timestamps */
gst_controller_sink_values (ctrl, 0 * GST_SECOND);
fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
gst_controller_sink_values (ctrl, 1 * GST_SECOND);
fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
gst_controller_sink_values (ctrl, 2 * GST_SECOND);
fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
g_object_unref (ctrl);
g_object_unref (elem);
}
GST_END_TEST;
/* @TODO write more tests (using an internal element that has controlable params)
*/
Suite *
@ -215,7 +341,11 @@ gst_controller_suite (void)
suite_add_tcase (s, tc);
tcase_add_test (tc, controller_init);
tcase_add_test (tc, controller_new_fail);
tcase_add_test (tc, controller_new_okay);
tcase_add_test (tc, controller_new_okay1);
tcase_add_test (tc, controller_new_okay2);
tcase_add_test (tc, controller_param_twice);
tcase_add_test (tc, controller_finalize);
tcase_add_test (tc, controller_interpolate_none);
return s;
}

View file

@ -55,6 +55,7 @@
<!ENTITY GstVersion SYSTEM "xml/gstversion.xml">
<!ENTITY GstXML SYSTEM "xml/gstxml.xml">
<!ENTITY GstAdapter SYSTEM "xml/gstadapter.xml">
<!ENTITY GstBaseSrc SYSTEM "xml/gstbasesrc.xml">
<!ENTITY GstBaseSink SYSTEM "xml/gstbasesink.xml">
<!ENTITY GstBaseTransform SYSTEM "xml/gstbasetransform.xml">
@ -204,10 +205,11 @@
These base classes are provided to be extended by elements.
</para>
&GstAdapter;
&GstBaseSrc;
&GstBaseSink;
&GstBaseTransform;
&GstPushSrc;
&GstPushSrc;
</chapter>

View file

@ -1633,6 +1633,30 @@ gst_xml_get_type
# base classes
<SECTION>
<FILE>gstadapter</FILE>
<TITLE>GstAdapter</TITLE>
GstAdapter
GstAdapterClass
gst_adapter_new
gst_adapter_clear
gst_adapter_push
gst_adapter_peek
gst_adapter_flush
gst_adapter_available
gst_adapter_available_fast
<SUBSECTION Standard>
GST_ADAPTER_SRC
GST_IS_ADAPTER_SRC
GST_TYPE_ADAPTER_SRC
GST_ADAPTER_SRC_CLASS
GST_IS_ADAPTER_SRC_CLASS
GST_ADAPTER_SRC_GET_CLASS
<SUBSECTION Private>
gst_adapter_src_get_type
</SECTION>
<SECTION>
<FILE>gstbasesrc</FILE>
<TITLE>GstBaseSrc</TITLE>

View file

@ -33,11 +33,13 @@ gst_xml_get_type
% base classes
#include <gst/base/gstadapter.h>
#include <gst/base/gstbasesrc.h>
#include <gst/base/gstbasesink.h>
#include <gst/base/gstbasetransform.h>
#include <gst/base/gstpushsrc.h>
gst_adapter_get_type
gst_base_src_get_type
gst_base_sink_get_type
gst_base_transform_get_type

View file

@ -87,6 +87,9 @@ Check out both <ulink url="http://www.cse.ogi.edu/sysl/">OGI's
pipeline</ulink> and Microsoft's DirectShow for some background.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION gst_init ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstBaseSink
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstBaseSink ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstBaseSrc
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstBaseSrc ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstBaseTransform
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstBaseTransform ##### -->
<para>

View file

@ -55,6 +55,9 @@ clock providers in the bin.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstBin ##### -->
<para>

View file

@ -85,6 +85,9 @@ Last reviewed on August 12th, 2004 (0.8.5)
#GstPad, #GstMiniObject
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstBuffer ##### -->
<para>
The basic structure of a buffer.

View file

@ -14,6 +14,9 @@ Structure describing sets of media formats
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstCaps ##### -->
<para>

View file

@ -22,6 +22,9 @@ a good measure of the current playback time in the pipeline.
#GstSystemClock
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstClock ##### -->
<para>

View file

@ -16,3 +16,6 @@ This can be done in CFLAGS for compiling old code.
</para>
<!-- ##### SECTION Stability_Level ##### -->

View file

@ -37,6 +37,9 @@ If a subsystem is disabled in GStreamer, a value is defined in
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### MACRO GST_DISABLE_LOADSAVE_REGISTRY ##### -->
<para>

View file

@ -65,6 +65,9 @@ and gst_element_set_clock(). You can wait for the clock to reach a given
<!-- basic object functions -->
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstElement ##### -->
<para>

View file

@ -14,6 +14,9 @@ Defines public information about a #GstElement
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstElementDetails ##### -->
<para>
This struct is used to define public information about the element. It

View file

@ -54,6 +54,9 @@ so that the autopluggers can select a plugin more appropriatly
#GstElement, #GstPlugin, #GstPluginFeature, #GstPadTemplate.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstElementFactory ##### -->
<para>

View file

@ -14,3 +14,6 @@ all gstreamer core related enumerations
</para>
<!-- ##### SECTION Stability_Level ##### -->

View file

@ -14,6 +14,9 @@ Categorized error messages
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstCoreError ##### -->
<para>

View file

@ -27,6 +27,9 @@ gst_event_new_flush() creates a new flush event.
#GstPad, #GstElement
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstEvent ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstFakeSink
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstFakeSink ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstFakeSrc
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstFakeSrc ##### -->
<para>
@ -39,6 +42,7 @@ GstFakeSrc
@:
@:
@:
@:
@:
<!-- ##### ARG GstFakeSrc:data ##### -->

View file

@ -14,6 +14,9 @@ GstFileSink
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstFileSink ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstFileSrc
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstFileSrc ##### -->
<para>

View file

@ -17,6 +17,9 @@ on its own.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### USER_FUNCTION GstFilterFunc ##### -->
<para>

View file

@ -15,6 +15,9 @@ formats can be used to perform seeking or conversions/query operations.
#GstPad, #GstElement
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstFormat ##### -->
<para>
Standard predefined formats

View file

@ -14,6 +14,9 @@ Pseudo link pads
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstGhostPad ##### -->
<para>

View file

@ -14,6 +14,9 @@ Core interface implemented by #GstElements that allows runtime querying of inter
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstImplementsInterface ##### -->
<para>

View file

@ -15,6 +15,9 @@ in a pipeline.
#GstIndexFactory
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstIndex ##### -->
<para>

View file

@ -14,6 +14,9 @@ GstIndexFactory is used to dynamically create GstIndex implementations.
#GstIndex
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstIndexFactory ##### -->
<para>
The GstIndexFactory object

View file

@ -68,6 +68,9 @@ categories. These are explained at GST_DEBUG_CATEGORY_INIT().
and environment variables that affect the debugging output.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstDebugLevel ##### -->
<para>
The level defines the importance of a debugging message. The more important a

View file

@ -14,6 +14,9 @@ GstIterator
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstIterator ##### -->
<para>

View file

@ -14,3 +14,6 @@ various portabillity helper macros
</para>
<!-- ##### SECTION Stability_Level ##### -->

View file

@ -21,6 +21,9 @@ The GstMemChunk is used to allocate critical resources for #GstBuffer and
#GstBuffer, #GstEvent, #GstData
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstMemChunk ##### -->
<para>
The memchunk structure

View file

@ -14,6 +14,9 @@ GstMiniObject
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstMiniObject ##### -->
<para>

View file

@ -67,6 +67,9 @@ object.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstObject ##### -->
<para>

View file

@ -57,6 +57,9 @@ Last reviewed on December 13th, 2002 (0.5.0.1)
#GstPadTemplate, #GstElement, #GstEvent
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstPad ##### -->
<para>

View file

@ -73,6 +73,9 @@ The following example shows you how to add the padtemplate to an elementfactory:
#GstPad, #GstElementFactory
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstPadTemplate ##### -->
<para>
The padtemplate object.

View file

@ -14,6 +14,9 @@ get a pipeline from a text pipeline description
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION gst_parse_error_quark ##### -->
<para>

View file

@ -21,6 +21,9 @@ the pipeline, use gst_object_unref() to free its resources.
#GstBin
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstPipeline ##### -->
<para>

View file

@ -35,6 +35,9 @@ to bring the plugin into memory.
#GstPluginFeature, #GstType, #GstAutoplug, #GstElementFactory
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION gst_plugin_error_quark ##### -->
<para>
Get the error quark

View file

@ -14,6 +14,9 @@ This is a base class for anything that can be added to a #GstPlugin.
#GstPlugin
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstPluginFeature ##### -->
<para>

View file

@ -15,6 +15,9 @@ Query types can be used to perform queries on pads and elements.
#GstPad, #GstElement
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstQueryType ##### -->
<para>
Standard predefined Query types

View file

@ -25,6 +25,9 @@ The queue blocks by default.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstQueue ##### -->
<para>

View file

@ -15,3 +15,6 @@ All registries build the #GstRegistryPool.
#GstPlugin, #GstPluginFeature
</para>
<!-- ##### SECTION Stability_Level ##### -->

View file

@ -15,6 +15,9 @@ the system.
GstRegistry
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION gst_registry_pool_list ##### -->
<para>

View file

@ -14,6 +14,9 @@ Generic structure containing fields of names and values
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstStructure ##### -->
<para>

View file

@ -15,6 +15,9 @@ system time.
#GstClock
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstSystemClock ##### -->
<para>

View file

@ -14,6 +14,9 @@ List of tags and values used to describe media metadata
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### TYPEDEF GstTagList ##### -->
<para>

View file

@ -14,6 +14,9 @@ Element interface that allows setting and retrieval of media metadata
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstTagSetter ##### -->
<para>

View file

@ -14,6 +14,9 @@ Tracing functionality
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstTrace ##### -->
<para>

View file

@ -14,6 +14,9 @@ gsttrashstack
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstTrashStack ##### -->
<para>

View file

@ -14,6 +14,9 @@ typefinding subsystem
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstTypeFind ##### -->
<para>

View file

@ -67,6 +67,9 @@ the given data. You can get quite a bit more complicated than that though.
<link linkend="gstreamer-Writing-typefind-functions">Writing typefind functions</link>
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstTypeFindFactory ##### -->
<para>
Object that stores information about a typefind function

View file

@ -14,6 +14,9 @@ various global enums and constants
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstElementState ##### -->
<para>
These contants describe the state a #GstElement is in and transition scheduled for the #GstElement (the pending state).

View file

@ -15,6 +15,9 @@ and the element property that can handle a given URI.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstURIHandler ##### -->
<para>

View file

@ -14,6 +14,9 @@ describes URI types
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstURIType ##### -->
<para>

View file

@ -14,6 +14,9 @@ various utility functions
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### FUNCTION gst_util_set_value_from_string ##### -->
<para>

View file

@ -14,6 +14,9 @@ GValue implementations specific to GStreamer
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### MACRO GST_MAKE_FOURCC ##### -->
<para>
will transform four characters into a host-endiannness guint32 fourcc:

View file

@ -15,6 +15,9 @@ The version macros get defined by including "gst/gst.h".
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### MACRO GST_VERSION_MAJOR ##### -->
<para>
The major version of GStreamer at compile time

View file

@ -14,6 +14,9 @@ XML save/restore operations of pipelines
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT GstXML ##### -->
<para>

View file

@ -5,6 +5,7 @@
%version-entities;
<!ENTITY GstBytestream SYSTEM "xml/gstbytestream.xml">
<!ENTITY GstController SYSTEM "xml/gstcontroller.xml">
<!ENTITY GstControllerGObject SYSTEM "xml/gstcontrollergobject.xml">
<!ENTITY GstGetbits SYSTEM "xml/gstgetbits.xml">
<!-- has not yet been written
<!ENTITY GstPutbits SYSTEM "xml/gstputbits.xml">
@ -40,7 +41,7 @@
<chapter id="gstreamer-control">
<title>gstcontrol</title>
&GstController;
<!--&GstControllerGObject; -->
&GstControllerGObject;
</chapter>
</part>

View file

@ -142,3 +142,18 @@ GST_TYPE_CONTROLLER
<SUBSECTION Private>
gst_controller_get_type
</SECTION>
<SECTION>
<FILE>gstcontrollergobject</FILE>
<TITLE>GstControllerGObject</TITLE>
<INCLUDE>libs/controller/gstcontroller.h</INCLUDE>
gst_object_control_properties
gst_object_uncontrol_properties
gst_object_get_controller
gst_object_set_controller
gst_object_sink_values
gst_object_get_value_arrays
gst_object_get_value_array
<SUBSECTION Standard>
<SUBSECTION Private>
</SECTION>

View file

@ -27,6 +27,9 @@ network connections also need a protocol to do this.
#GstBuffer, #GstCaps, #GstEvent
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### ENUM GstDPHeaderFlag ##### -->
<para>

View file

@ -14,6 +14,9 @@ accelerated routines for getting bits from a data stream.
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### STRUCT gst_getbits_t ##### -->
<para>

View file

@ -17,6 +17,47 @@
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:gstadapter
* @short_description: object to splice and merge buffers to desired size
* @see_also: #GstBytestream, #GstFilePad
*
* This class is for elements that receive buffers in an undesired size.
* While for example raw video contains one image per buffer, the same is not
* true for a lot of other formats, especially those that come directly from
* a file. So if you have undefined buffer sizes and require a specific size,
* this object is for you.
*
* The theory of operation is like this: All buffers received are put
* into the adapter using gst_adapter_push() and the data is then read back
* in chunks of the desired size using gst_adapter_peek(). After the data is
* processed, it is freed using gst_adapter_flush(). An example function that
* needs to process data in 10 byte chunks could look like this:
* <programlisting>
* void
* process_buffer (GstAdapter *adapter, GstBuffer *buffer)
* {
* guint8 *data;
* // put buffer into adapter
* #gst_adapter_push (adapter, buffer);
* // while we can read out 10 bytes, process them
* while ((data = #gst_adapter_peek (adapter, 10))) {
* // process the 10 bytes here
* // after processing the data, flush it
* #gst_adapter_flush (adapter, 10);
* }
* }
* </programlisting>
* For another example, a simple element inside GStreamer that uses GstAdapter
* is the libvisual element.
*
* A last thing to note is that while GstAdapter is pretty optimized,
* merging buffers still might be an operation that requires a memcpy()
* operation, and this operation is not the fastest. Because of this, some
* functions like gst_adapter_available_fast() are provided to help speed up
* such cases should you want to.
*/
#include <string.h>
#include "gstadapter.h"

View file

@ -17,6 +17,47 @@
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:gstadapter
* @short_description: object to splice and merge buffers to desired size
* @see_also: #GstBytestream, #GstFilePad
*
* This class is for elements that receive buffers in an undesired size.
* While for example raw video contains one image per buffer, the same is not
* true for a lot of other formats, especially those that come directly from
* a file. So if you have undefined buffer sizes and require a specific size,
* this object is for you.
*
* The theory of operation is like this: All buffers received are put
* into the adapter using gst_adapter_push() and the data is then read back
* in chunks of the desired size using gst_adapter_peek(). After the data is
* processed, it is freed using gst_adapter_flush(). An example function that
* needs to process data in 10 byte chunks could look like this:
* <programlisting>
* void
* process_buffer (GstAdapter *adapter, GstBuffer *buffer)
* {
* guint8 *data;
* // put buffer into adapter
* #gst_adapter_push (adapter, buffer);
* // while we can read out 10 bytes, process them
* while ((data = #gst_adapter_peek (adapter, 10))) {
* // process the 10 bytes here
* // after processing the data, flush it
* #gst_adapter_flush (adapter, 10);
* }
* }
* </programlisting>
* For another example, a simple element inside GStreamer that uses GstAdapter
* is the libvisual element.
*
* A last thing to note is that while GstAdapter is pretty optimized,
* merging buffers still might be an operation that requires a memcpy()
* operation, and this operation is not the fastest. Because of this, some
* functions like gst_adapter_available_fast() are provided to help speed up
* such cases should you want to.
*/
#include <string.h>
#include "gstadapter.h"

View file

@ -217,7 +217,6 @@ gst_controlled_property_new (GObject * object, const gchar * name)
gchar *signal_name;
prop->name = pspec->name; // so we don't use the same mem twice
prop->object = object;
prop->type = G_PARAM_SPEC_VALUE_TYPE (pspec);
gst_controlled_property_set_interpolation_mode (prop,
GST_INTERPOLATE_NONE);
@ -298,7 +297,6 @@ gst_controlled_property_free (GstControlledProperty * prop)
{
GList *node;
g_signal_handler_disconnect (prop->object, prop->notify_handler_id);
for (node = prop->values; node; node = g_list_next (node)) {
g_free (node->data);
}
@ -370,16 +368,25 @@ gst_controller_new_valist (GObject * object, va_list var_args)
self = g_object_get_qdata (object, controller_key);
// create GstControlledProperty for each property
while ((name = va_arg (var_args, gchar *))) {
// create GstControlledProperty and add to self->propeties List
if ((prop = gst_controlled_property_new (object, name))) {
// if we don't have a controller object yet, now is the time to create one
if (!self) {
self = g_object_new (GST_TYPE_CONTROLLER, NULL);
self->lock = g_mutex_new ();
// store the controller
g_object_set_qdata (object, controller_key, self);
// test if this property isn't yet controlled
if (!self || !(prop = gst_controller_find_controlled_property (self, name))) {
// create GstControlledProperty and add to self->propeties List
if ((prop = gst_controlled_property_new (object, name))) {
// if we don't have a controller object yet, now is the time to create one
if (!self) {
self = g_object_new (GST_TYPE_CONTROLLER, NULL);
self->lock = g_mutex_new ();
self->object = object;
// store the controller
g_object_set_qdata (object, controller_key, self);
} else {
// increment ref-count
self = g_object_ref (self);
}
self->properties = g_list_prepend (self->properties, prop);
}
self->properties = g_list_prepend (self->properties, prop);
} else {
GST_WARNING ("trying to control property again");
}
}
va_end (var_args);
@ -434,6 +441,7 @@ gst_controller_remove_properties_valist (GstController * self, va_list var_args)
g_mutex_lock (self->lock);
if ((prop = gst_controller_find_controlled_property (self, name))) {
self->properties = g_list_remove (self->properties, prop);
g_signal_handler_disconnect (self->object, prop->notify_handler_id);
gst_controlled_property_free (prop);
} else {
res = FALSE;
@ -712,7 +720,7 @@ gst_controller_sink_values (GstController * self, GstClockTime timestamp)
value = prop->get (prop, timestamp);
prop->last_value.timestamp = timestamp;
g_value_copy (value, &prop->last_value.value);
g_object_set_property (prop->object, prop->name, value);
g_object_set_property (self->object, prop->name, value);
}
}
g_mutex_unlock (self->lock);
@ -864,16 +872,21 @@ _gst_controller_finalize (GObject * object)
{
GstController *self = GST_CONTROLLER (object);
GList *node;
GstControlledProperty *prop;
// free list of properties
/* free list of properties */
if (self->properties) {
for (node = self->properties; node; node = g_list_next (node)) {
gst_controlled_property_free (node->data);
prop = node->data;
g_signal_handler_disconnect (self->object, prop->notify_handler_id);
gst_controlled_property_free (prop);
}
g_list_free (self->properties);
self->properties = NULL;
}
g_mutex_free (self->lock);
/* remove controller from objects qdata list */
g_object_set_qdata (self->object, controller_key, NULL);
if (G_OBJECT_CLASS (parent_class)->finalize)
(G_OBJECT_CLASS (parent_class)->finalize) (object);

View file

@ -110,7 +110,6 @@ typedef struct _GstInterpolateMethod
typedef struct _GstControlledProperty
{
gchar *name; // name of the property
GObject *object; // the object we control
GType type; // type of the handled property
GValue default_value; // default value for the handled property
GValue result_value; // result value location for the interpolation method
@ -160,6 +159,7 @@ struct _GstController
GList *properties; // List of GstControlledProperty
GMutex *lock; // Secure property access, elements will access from threads
GObject *object; // the object we control
};
struct _GstControllerClass
@ -207,17 +207,17 @@ gboolean gst_controller_set_interpolation_mode (GstController * self,
/* GObject convenience functions */
GstController *g_object_control_properties (GObject * object, ...);
gboolean g_object_uncontrol_properties (GObject * object, ...);
GstController *gst_object_control_properties (GObject * object, ...);
gboolean gst_object_uncontrol_properties (GObject * object, ...);
GstController *g_object_get_controller (GObject * object);
gboolean g_object_set_controller (GObject * object, GstController * controller);
GstController *gst_object_get_controller (GObject * object);
gboolean gst_object_set_controller (GObject * object, GstController * controller);
gboolean g_object_sink_values (GObject * object, GstClockTime timestamp);
gboolean gst_object_sink_values (GObject * object, GstClockTime timestamp);
gboolean g_object_get_value_arrays (GObject * object,
gboolean gst_object_get_value_arrays (GObject * object,
GstClockTime timestamp, GSList * value_arrays);
gboolean g_object_get_value_array (GObject * object,
gboolean gst_object_get_value_array (GObject * object,
GstClockTime timestamp, GstValueArray * value_array);
/* lib init/done */

View file

@ -14,7 +14,7 @@ GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
extern GQuark controller_key;
/**
* g_object_control_properties:
* gst_object_control_properties:
* @object: the object of which some properties should be controlled
* @var_args: %NULL terminated list of property names that should be controlled
*
@ -28,7 +28,7 @@ extern GQuark controller_key;
* one or more of the given properties aren't available, or cannot be controlled, for the given element.
*/
GstController *
g_object_control_properties (GObject * object, ...)
gst_object_control_properties (GObject * object, ...)
{
GstController *ctrl;
@ -43,7 +43,7 @@ g_object_control_properties (GObject * object, ...)
}
/**
* g_object_uncontrol_properties:
* gst_object_uncontrol_properties:
* @object: the object of which some properties should not be controlled anymore
* @var_args: %NULL terminated list of property names that should be controlled
*
@ -55,7 +55,7 @@ g_object_control_properties (GObject * object, ...)
* controller, %TRUE otherwise
*/
gboolean
g_object_uncontrol_properties (GObject * object, ...)
gst_object_uncontrol_properties (GObject * object, ...)
{
gboolean res = FALSE;
GstController *ctrl;
@ -73,14 +73,14 @@ g_object_uncontrol_properties (GObject * object, ...)
}
/**
* g_object_get_controller:
* gst_object_get_controller:
* @object: the object that has controlled properties
*
* Returns: the controller handling some of the given element's properties,
* %NULL if no controller
*/
GstController *
g_object_get_controller (GObject * object)
gst_object_get_controller (GObject * object)
{
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
@ -88,7 +88,7 @@ g_object_get_controller (GObject * object)
}
/**
* g_object_set_controller:
* gst_object_set_controller:
* @object: the object that should get the controller
* @controller: the controller object to plug in
*
@ -97,7 +97,7 @@ g_object_get_controller (GObject * object)
* Returns: %FALSE if the GObject already has an controller, %TRUE otherwise
*/
gboolean
g_object_set_controller (GObject * object, GstController * controller)
gst_object_set_controller (GObject * object, GstController * controller)
{
GstController *ctrl;
@ -111,7 +111,7 @@ g_object_set_controller (GObject * object, GstController * controller)
}
/**
* g_object_sink_values:
* gst_object_sink_values:
* @object: the object that has controlled properties
* @timestamp: the time that should be processed
*
@ -120,7 +120,7 @@ g_object_set_controller (GObject * object, GstController * controller)
* Returns: same thing as gst_controller_sink_values()
*/
gboolean
g_object_sink_values (GObject * object, GstClockTime timestamp)
gst_object_sink_values (GObject * object, GstClockTime timestamp)
{
GstController *ctrl = NULL;
@ -133,7 +133,7 @@ g_object_sink_values (GObject * object, GstClockTime timestamp)
}
/**
* g_object_get_value_arrays:
* gst_object_get_value_arrays:
* @object: the object that has controlled properties
* @timestamp: the time that should be processed
* @value_arrays: list to return the control-values in
@ -150,7 +150,7 @@ g_object_sink_values (GObject * object, GstClockTime timestamp)
* Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
*/
gboolean
g_object_get_value_arrays (GObject * object, GstClockTime timestamp,
gst_object_get_value_arrays (GObject * object, GstClockTime timestamp,
GSList * value_arrays)
{
GstController *ctrl;
@ -164,7 +164,7 @@ g_object_get_value_arrays (GObject * object, GstClockTime timestamp,
}
/**
* g_object_get_value_array:
* gst_object_get_value_array:
* @self: the object that has controlled properties
* @timestamp: the time that should be processed
* @value_array: array to put control-values in
@ -179,7 +179,7 @@ g_object_get_value_arrays (GObject * object, GstClockTime timestamp,
* Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
*/
gboolean
g_object_get_value_array (GObject * object, GstClockTime timestamp,
gst_object_get_value_array (GObject * object, GstClockTime timestamp,
GstValueArray * value_array)
{
GstController *ctrl;

View file

@ -217,7 +217,6 @@ gst_controlled_property_new (GObject * object, const gchar * name)
gchar *signal_name;
prop->name = pspec->name; // so we don't use the same mem twice
prop->object = object;
prop->type = G_PARAM_SPEC_VALUE_TYPE (pspec);
gst_controlled_property_set_interpolation_mode (prop,
GST_INTERPOLATE_NONE);
@ -298,7 +297,6 @@ gst_controlled_property_free (GstControlledProperty * prop)
{
GList *node;
g_signal_handler_disconnect (prop->object, prop->notify_handler_id);
for (node = prop->values; node; node = g_list_next (node)) {
g_free (node->data);
}
@ -370,16 +368,25 @@ gst_controller_new_valist (GObject * object, va_list var_args)
self = g_object_get_qdata (object, controller_key);
// create GstControlledProperty for each property
while ((name = va_arg (var_args, gchar *))) {
// create GstControlledProperty and add to self->propeties List
if ((prop = gst_controlled_property_new (object, name))) {
// if we don't have a controller object yet, now is the time to create one
if (!self) {
self = g_object_new (GST_TYPE_CONTROLLER, NULL);
self->lock = g_mutex_new ();
// store the controller
g_object_set_qdata (object, controller_key, self);
// test if this property isn't yet controlled
if (!self || !(prop = gst_controller_find_controlled_property (self, name))) {
// create GstControlledProperty and add to self->propeties List
if ((prop = gst_controlled_property_new (object, name))) {
// if we don't have a controller object yet, now is the time to create one
if (!self) {
self = g_object_new (GST_TYPE_CONTROLLER, NULL);
self->lock = g_mutex_new ();
self->object = object;
// store the controller
g_object_set_qdata (object, controller_key, self);
} else {
// increment ref-count
self = g_object_ref (self);
}
self->properties = g_list_prepend (self->properties, prop);
}
self->properties = g_list_prepend (self->properties, prop);
} else {
GST_WARNING ("trying to control property again");
}
}
va_end (var_args);
@ -434,6 +441,7 @@ gst_controller_remove_properties_valist (GstController * self, va_list var_args)
g_mutex_lock (self->lock);
if ((prop = gst_controller_find_controlled_property (self, name))) {
self->properties = g_list_remove (self->properties, prop);
g_signal_handler_disconnect (self->object, prop->notify_handler_id);
gst_controlled_property_free (prop);
} else {
res = FALSE;
@ -712,7 +720,7 @@ gst_controller_sink_values (GstController * self, GstClockTime timestamp)
value = prop->get (prop, timestamp);
prop->last_value.timestamp = timestamp;
g_value_copy (value, &prop->last_value.value);
g_object_set_property (prop->object, prop->name, value);
g_object_set_property (self->object, prop->name, value);
}
}
g_mutex_unlock (self->lock);
@ -864,16 +872,21 @@ _gst_controller_finalize (GObject * object)
{
GstController *self = GST_CONTROLLER (object);
GList *node;
GstControlledProperty *prop;
// free list of properties
/* free list of properties */
if (self->properties) {
for (node = self->properties; node; node = g_list_next (node)) {
gst_controlled_property_free (node->data);
prop = node->data;
g_signal_handler_disconnect (self->object, prop->notify_handler_id);
gst_controlled_property_free (prop);
}
g_list_free (self->properties);
self->properties = NULL;
}
g_mutex_free (self->lock);
/* remove controller from objects qdata list */
g_object_set_qdata (self->object, controller_key, NULL);
if (G_OBJECT_CLASS (parent_class)->finalize)
(G_OBJECT_CLASS (parent_class)->finalize) (object);

View file

@ -110,7 +110,6 @@ typedef struct _GstInterpolateMethod
typedef struct _GstControlledProperty
{
gchar *name; // name of the property
GObject *object; // the object we control
GType type; // type of the handled property
GValue default_value; // default value for the handled property
GValue result_value; // result value location for the interpolation method
@ -160,6 +159,7 @@ struct _GstController
GList *properties; // List of GstControlledProperty
GMutex *lock; // Secure property access, elements will access from threads
GObject *object; // the object we control
};
struct _GstControllerClass
@ -207,17 +207,17 @@ gboolean gst_controller_set_interpolation_mode (GstController * self,
/* GObject convenience functions */
GstController *g_object_control_properties (GObject * object, ...);
gboolean g_object_uncontrol_properties (GObject * object, ...);
GstController *gst_object_control_properties (GObject * object, ...);
gboolean gst_object_uncontrol_properties (GObject * object, ...);
GstController *g_object_get_controller (GObject * object);
gboolean g_object_set_controller (GObject * object, GstController * controller);
GstController *gst_object_get_controller (GObject * object);
gboolean gst_object_set_controller (GObject * object, GstController * controller);
gboolean g_object_sink_values (GObject * object, GstClockTime timestamp);
gboolean gst_object_sink_values (GObject * object, GstClockTime timestamp);
gboolean g_object_get_value_arrays (GObject * object,
gboolean gst_object_get_value_arrays (GObject * object,
GstClockTime timestamp, GSList * value_arrays);
gboolean g_object_get_value_array (GObject * object,
gboolean gst_object_get_value_array (GObject * object,
GstClockTime timestamp, GstValueArray * value_array);
/* lib init/done */

View file

@ -14,7 +14,7 @@ GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
extern GQuark controller_key;
/**
* g_object_control_properties:
* gst_object_control_properties:
* @object: the object of which some properties should be controlled
* @var_args: %NULL terminated list of property names that should be controlled
*
@ -28,7 +28,7 @@ extern GQuark controller_key;
* one or more of the given properties aren't available, or cannot be controlled, for the given element.
*/
GstController *
g_object_control_properties (GObject * object, ...)
gst_object_control_properties (GObject * object, ...)
{
GstController *ctrl;
@ -43,7 +43,7 @@ g_object_control_properties (GObject * object, ...)
}
/**
* g_object_uncontrol_properties:
* gst_object_uncontrol_properties:
* @object: the object of which some properties should not be controlled anymore
* @var_args: %NULL terminated list of property names that should be controlled
*
@ -55,7 +55,7 @@ g_object_control_properties (GObject * object, ...)
* controller, %TRUE otherwise
*/
gboolean
g_object_uncontrol_properties (GObject * object, ...)
gst_object_uncontrol_properties (GObject * object, ...)
{
gboolean res = FALSE;
GstController *ctrl;
@ -73,14 +73,14 @@ g_object_uncontrol_properties (GObject * object, ...)
}
/**
* g_object_get_controller:
* gst_object_get_controller:
* @object: the object that has controlled properties
*
* Returns: the controller handling some of the given element's properties,
* %NULL if no controller
*/
GstController *
g_object_get_controller (GObject * object)
gst_object_get_controller (GObject * object)
{
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
@ -88,7 +88,7 @@ g_object_get_controller (GObject * object)
}
/**
* g_object_set_controller:
* gst_object_set_controller:
* @object: the object that should get the controller
* @controller: the controller object to plug in
*
@ -97,7 +97,7 @@ g_object_get_controller (GObject * object)
* Returns: %FALSE if the GObject already has an controller, %TRUE otherwise
*/
gboolean
g_object_set_controller (GObject * object, GstController * controller)
gst_object_set_controller (GObject * object, GstController * controller)
{
GstController *ctrl;
@ -111,7 +111,7 @@ g_object_set_controller (GObject * object, GstController * controller)
}
/**
* g_object_sink_values:
* gst_object_sink_values:
* @object: the object that has controlled properties
* @timestamp: the time that should be processed
*
@ -120,7 +120,7 @@ g_object_set_controller (GObject * object, GstController * controller)
* Returns: same thing as gst_controller_sink_values()
*/
gboolean
g_object_sink_values (GObject * object, GstClockTime timestamp)
gst_object_sink_values (GObject * object, GstClockTime timestamp)
{
GstController *ctrl = NULL;
@ -133,7 +133,7 @@ g_object_sink_values (GObject * object, GstClockTime timestamp)
}
/**
* g_object_get_value_arrays:
* gst_object_get_value_arrays:
* @object: the object that has controlled properties
* @timestamp: the time that should be processed
* @value_arrays: list to return the control-values in
@ -150,7 +150,7 @@ g_object_sink_values (GObject * object, GstClockTime timestamp)
* Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
*/
gboolean
g_object_get_value_arrays (GObject * object, GstClockTime timestamp,
gst_object_get_value_arrays (GObject * object, GstClockTime timestamp,
GSList * value_arrays)
{
GstController *ctrl;
@ -164,7 +164,7 @@ g_object_get_value_arrays (GObject * object, GstClockTime timestamp,
}
/**
* g_object_get_value_array:
* gst_object_get_value_array:
* @self: the object that has controlled properties
* @timestamp: the time that should be processed
* @value_array: array to put control-values in
@ -179,7 +179,7 @@ g_object_get_value_arrays (GObject * object, GstClockTime timestamp,
* Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
*/
gboolean
g_object_get_value_array (GObject * object, GstClockTime timestamp,
gst_object_get_value_array (GObject * object, GstClockTime timestamp,
GstValueArray * value_array)
{
GstController *ctrl;

View file

@ -30,7 +30,7 @@ enum
{
ARG_ULONG = 1,
ARG_DOUBLE,
ARG_SWITCH,
ARG_BOOLEAN,
ARG_COUNT
};
@ -47,6 +47,9 @@ typedef struct _GstTestMonoSourceClass GstTestMonoSourceClass;
struct _GstTestMonoSource
{
GstElement parent;
gulong val_ulong;
gdouble val_double;
gboolean val_bool;
};
struct _GstTestMonoSourceClass
{
@ -59,14 +62,17 @@ static void
gst_test_mono_source_get_property (GObject * object,
guint property_id, GValue * value, GParamSpec * pspec)
{
//GstTestMonoSource *self = GST_TEST_MONO_SOURCE(object);
GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
switch (property_id) {
case ARG_ULONG:
g_value_set_ulong (value, self->val_ulong);
break;
default:{
case ARG_DOUBLE:
g_value_set_double (value, self->val_double);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
break;
}
}
@ -75,14 +81,17 @@ static void
gst_test_mono_source_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec)
{
//GstTestMonoSource *self = GST_TEST_MONO_SOURCE(object);
GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
switch (property_id) {
case ARG_ULONG:
self->val_ulong = g_value_get_ulong (value);
break;
default:{
case ARG_DOUBLE:
self->val_double = g_value_get_double (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
break;
}
}
@ -100,6 +109,12 @@ gst_test_mono_source_class_init (GstTestMonoSourceClass * klass)
"ulong prop",
"ulong number parameter for the test_mono_source",
0, G_MAXULONG, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_DOUBLE,
g_param_spec_double ("double",
"double prop",
"double number parameter for the test_mono_source",
0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
}
static void
@ -177,17 +192,13 @@ GST_START_TEST (controller_new_fail)
ctrl = gst_controller_new (G_OBJECT (elem), "_schrompf_", NULL);
fail_unless (ctrl == NULL, NULL);
/* that property exists, but is not controllable */
ASSERT_CRITICAL (ctrl = gst_controller_new (G_OBJECT (elem), "name", NULL));
fail_unless (ctrl == NULL, NULL);
g_object_unref (elem);
}
GST_END_TEST;
/* tests for an element with controlled params */
GST_START_TEST (controller_new_okay)
GST_START_TEST (controller_new_okay1)
{
GstController *ctrl;
GstElement *elem;
@ -204,6 +215,121 @@ GST_START_TEST (controller_new_okay)
GST_END_TEST;
/* controlling several params should return the same controller */
GST_START_TEST (controller_new_okay2)
{
GstController *ctrl1, *ctrl2;
GstElement *elem;
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl1 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
fail_unless (ctrl1 != NULL, NULL);
/* that property should exist and should be controllable */
ctrl2 = gst_controller_new (G_OBJECT (elem), "double", NULL);
fail_unless (ctrl2 != NULL, NULL);
fail_unless (ctrl1 == ctrl2, NULL);
g_object_unref (ctrl2);
g_object_unref (ctrl1);
g_object_unref (elem);
}
GST_END_TEST;
/* controlling a params twice should be handled */
GST_START_TEST (controller_param_twice)
{
GstController *ctrl;
GstElement *elem;
gboolean res;
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "ulong", NULL);
fail_unless (ctrl != NULL, NULL);
/* it should have been added at least once, let remove it */
res = gst_controller_remove_properties (ctrl, "ulong", NULL);
fail_unless (res, NULL);
/* removing it agian should not work */
res = gst_controller_remove_properties (ctrl, "ulong", NULL);
fail_unless (!res, NULL);
g_object_unref (ctrl);
g_object_unref (elem);
}
GST_END_TEST;
/* tests if we cleanup properly */
GST_START_TEST (controller_finalize)
{
GstController *ctrl;
GstElement *elem;
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
fail_unless (ctrl != NULL, NULL);
/* free the controller */
g_object_unref (ctrl);
/* object shouldn't have a controller anymore */
ctrl = gst_object_get_controller (G_OBJECT (elem));
fail_unless (ctrl == NULL, NULL);
g_object_unref (elem);
}
GST_END_TEST;
/* test timed value handling without interpolation */
GST_START_TEST (controller_interpolate_none)
{
GstController *ctrl;
GstElement *elem;
gboolean res;
GValue val_ulong = { 0, };
elem = gst_element_factory_make ("testmonosource", "test_source");
/* that property should exist and should be controllable */
ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
fail_unless (ctrl != NULL, NULL);
/* set interpolation mode */
gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
/* set control values */
g_value_init (&val_ulong, G_TYPE_ULONG);
g_value_set_ulong (&val_ulong, 0);
res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
fail_unless (res, NULL);
g_value_set_ulong (&val_ulong, 100);
res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
fail_unless (res, NULL);
/* now pull in values for some timestamps */
gst_controller_sink_values (ctrl, 0 * GST_SECOND);
fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
gst_controller_sink_values (ctrl, 1 * GST_SECOND);
fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
gst_controller_sink_values (ctrl, 2 * GST_SECOND);
fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
g_object_unref (ctrl);
g_object_unref (elem);
}
GST_END_TEST;
/* @TODO write more tests (using an internal element that has controlable params)
*/
Suite *
@ -215,7 +341,11 @@ gst_controller_suite (void)
suite_add_tcase (s, tc);
tcase_add_test (tc, controller_init);
tcase_add_test (tc, controller_new_fail);
tcase_add_test (tc, controller_new_okay);
tcase_add_test (tc, controller_new_okay1);
tcase_add_test (tc, controller_new_okay2);
tcase_add_test (tc, controller_param_twice);
tcase_add_test (tc, controller_finalize);
tcase_add_test (tc, controller_interpolate_none);
return s;
}