mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 12:41:05 +00:00
25b9d5e292
Original commit message from CVS: fixed a few typos, relabeled introductionary list of types more notes abut dparam changes many comments and notes on dparam implementation new dparams are were not initialized to the default value from param specs
386 lines
11 KiB
C
386 lines
11 KiB
C
/* GStreamer
|
|
* Copyright (C) 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
|
|
*
|
|
* gstdparam.c: Dynamic Parameter
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <gst/gstinfo.h>
|
|
|
|
#include "dparam.h"
|
|
#include "dparammanager.h"
|
|
#include <gst/gstmarshal.h>
|
|
|
|
GST_DEBUG_CATEGORY_EXTERN (_gst_control_debug);
|
|
#define GST_CAT_DEFAULT _gst_control_debug
|
|
|
|
static void gst_dparam_class_init (GstDParamClass * klass);
|
|
static void gst_dparam_init (GstDParam * dparam);
|
|
static void gst_dparam_dispose (GObject * object);
|
|
static void gst_dparam_get_property (GObject * object, guint prop_id,
|
|
GValue * value, GParamSpec * pspec);
|
|
static void gst_dparam_set_property (GObject * object, guint prop_id,
|
|
const GValue * value, GParamSpec * pspec);
|
|
|
|
enum
|
|
{
|
|
ARG_0,
|
|
ARG_VALUE_FLOAT,
|
|
ARG_VALUE_DOUBLE,
|
|
ARG_VALUE_INT,
|
|
ARG_VALUE_INT64,
|
|
};
|
|
|
|
enum
|
|
{
|
|
VALUE_CHANGED,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint gst_dparam_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
GType
|
|
gst_dparam_get_type (void)
|
|
{
|
|
static GType dparam_type = 0;
|
|
|
|
if (!dparam_type) {
|
|
static const GTypeInfo dparam_info = {
|
|
sizeof (GstDParamClass),
|
|
NULL,
|
|
NULL,
|
|
(GClassInitFunc) gst_dparam_class_init,
|
|
NULL,
|
|
NULL,
|
|
sizeof (GstDParam),
|
|
0,
|
|
(GInstanceInitFunc) gst_dparam_init,
|
|
};
|
|
|
|
dparam_type =
|
|
g_type_register_static (GST_TYPE_OBJECT, "GstDParam", &dparam_info, 0);
|
|
}
|
|
return dparam_type;
|
|
}
|
|
|
|
static void
|
|
gst_dparam_class_init (GstDParamClass * klass)
|
|
{
|
|
GObjectClass *gobject_class;
|
|
GstDParamClass *dparam_class;
|
|
GstObjectClass *gstobject_class;
|
|
|
|
gobject_class = (GObjectClass *) klass;
|
|
dparam_class = (GstDParamClass *) klass;
|
|
gstobject_class = (GstObjectClass *) klass;
|
|
|
|
gobject_class->get_property = gst_dparam_get_property;
|
|
gobject_class->set_property = gst_dparam_set_property;
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VALUE_FLOAT,
|
|
g_param_spec_float ("value_float", "Float Value",
|
|
"The value that should be changed if gfloat is the type",
|
|
-G_MAXFLOAT, G_MAXFLOAT, 0.0F, G_PARAM_READWRITE));
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VALUE_DOUBLE,
|
|
g_param_spec_double ("value_double", "Double Value",
|
|
"The value that should be changed if gdouble is the type",
|
|
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE));
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VALUE_INT,
|
|
g_param_spec_int ("value_int", "Integer Value",
|
|
"The value that should be changed if gint is the type",
|
|
G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VALUE_INT64,
|
|
g_param_spec_int64 ("value_int64", "64 bit Integer Value",
|
|
"The value that should be changed if gint64 is the type",
|
|
G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE));
|
|
|
|
gobject_class->dispose = gst_dparam_dispose;
|
|
|
|
gst_dparam_signals[VALUE_CHANGED] =
|
|
g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass),
|
|
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDParamClass, value_changed), NULL,
|
|
NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
|
/*gstobject_class->save_thyself = gst_dparam_save_thyself; */
|
|
|
|
}
|
|
|
|
static void
|
|
gst_dparam_init (GstDParam * dparam)
|
|
{
|
|
g_return_if_fail (dparam != NULL);
|
|
GST_DPARAM_TYPE (dparam) = 0;
|
|
GST_DPARAM_NEXT_UPDATE_TIMESTAMP (dparam) = 0LL;
|
|
GST_DPARAM_LAST_UPDATE_TIMESTAMP (dparam) = 0LL;
|
|
GST_DPARAM_READY_FOR_UPDATE (dparam) = FALSE;
|
|
dparam->lock = g_mutex_new ();
|
|
}
|
|
|
|
/**
|
|
* gst_dparam_new:
|
|
* @type: the type that this dparam will store
|
|
*
|
|
* Create a new dynamic parameter controller.
|
|
*
|
|
* Returns: a new instance of GstDParam
|
|
*/
|
|
GstDParam *
|
|
gst_dparam_new (GType type)
|
|
{
|
|
GstDParam *dparam;
|
|
|
|
dparam = g_object_new (gst_dparam_get_type (), NULL);
|
|
dparam->do_update_func = gst_dparam_do_update_default;
|
|
|
|
GST_DPARAM_TYPE (dparam) = type;
|
|
|
|
return dparam;
|
|
}
|
|
|
|
|
|
static void
|
|
gst_dparam_get_property (GObject * object, guint prop_id, GValue * value,
|
|
GParamSpec * pspec)
|
|
{
|
|
GstDParam *dparam;
|
|
|
|
g_return_if_fail (GST_IS_DPARAM (object));
|
|
dparam = GST_DPARAM (object);
|
|
|
|
switch (prop_id) {
|
|
case ARG_VALUE_FLOAT:
|
|
g_value_set_float (value, dparam->value_float);
|
|
break;
|
|
|
|
case ARG_VALUE_DOUBLE:
|
|
g_value_set_double (value, dparam->value_double);
|
|
break;
|
|
|
|
case ARG_VALUE_INT:
|
|
g_value_set_int (value, dparam->value_int);
|
|
break;
|
|
|
|
case ARG_VALUE_INT64:
|
|
g_value_set_int64 (value, dparam->value_int64);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gst_dparam_set_property (GObject * object, guint prop_id, const GValue * value,
|
|
GParamSpec * pspec)
|
|
{
|
|
GstDParam *dparam;
|
|
|
|
g_return_if_fail (GST_IS_DPARAM (object));
|
|
dparam = GST_DPARAM (object);
|
|
GST_DPARAM_LOCK (dparam);
|
|
|
|
switch (prop_id) {
|
|
case ARG_VALUE_FLOAT:
|
|
GST_DEBUG ("setting value from %g to %g", dparam->value_float,
|
|
g_value_get_float (value));
|
|
dparam->value_float = g_value_get_float (value);
|
|
GST_DPARAM_NEXT_UPDATE_TIMESTAMP (dparam) =
|
|
GST_DPARAM_LAST_UPDATE_TIMESTAMP (dparam);
|
|
GST_DPARAM_READY_FOR_UPDATE (dparam) = TRUE;
|
|
break;
|
|
|
|
case ARG_VALUE_DOUBLE:
|
|
GST_DEBUG ("setting value from %g to %g",
|
|
dparam->value_double, g_value_get_double (value));
|
|
dparam->value_double = g_value_get_double (value);
|
|
GST_DPARAM_NEXT_UPDATE_TIMESTAMP (dparam) =
|
|
GST_DPARAM_LAST_UPDATE_TIMESTAMP (dparam);
|
|
GST_DPARAM_READY_FOR_UPDATE (dparam) = TRUE;
|
|
break;
|
|
|
|
case ARG_VALUE_INT:
|
|
GST_DEBUG ("setting value from %d to %d", dparam->value_int,
|
|
g_value_get_int (value));
|
|
dparam->value_int = g_value_get_int (value);
|
|
GST_DPARAM_NEXT_UPDATE_TIMESTAMP (dparam) =
|
|
GST_DPARAM_LAST_UPDATE_TIMESTAMP (dparam);
|
|
GST_DPARAM_READY_FOR_UPDATE (dparam) = TRUE;
|
|
break;
|
|
|
|
case ARG_VALUE_INT64:
|
|
GST_DEBUG ("setting value from %"
|
|
G_GINT64_FORMAT " to %"
|
|
G_GINT64_FORMAT, dparam->value_int64, g_value_get_int64 (value));
|
|
dparam->value_int64 = g_value_get_int64 (value);
|
|
GST_DPARAM_NEXT_UPDATE_TIMESTAMP (dparam) =
|
|
GST_DPARAM_LAST_UPDATE_TIMESTAMP (dparam);
|
|
GST_DPARAM_READY_FOR_UPDATE (dparam) = TRUE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* note that this signal is sent while we still have the lock. */
|
|
g_signal_emit (G_OBJECT (dparam), gst_dparam_signals[VALUE_CHANGED], 0);
|
|
GST_DPARAM_UNLOCK (dparam);
|
|
}
|
|
|
|
/**
|
|
* gst_dparam_do_update_default:
|
|
* @dparam: the parameter to update
|
|
* @timestamp: when should the update take place
|
|
* @value: the new value
|
|
* @update_info: unused here
|
|
*
|
|
* Default implementation for changing a dynamic parameter.
|
|
* Subclasses might overwrite the behaviour of this.
|
|
*
|
|
*/
|
|
void
|
|
gst_dparam_do_update_default (GstDParam * dparam, gint64 timestamp,
|
|
GValue * value, GstDParamUpdateInfo update_info)
|
|
{
|
|
GST_DPARAM_LOCK (dparam);
|
|
|
|
g_return_if_fail (G_VALUE_TYPE (value) == GST_DPARAM_TYPE (dparam));
|
|
GST_DEBUG ("updating value for %s(%p)", GST_DPARAM_NAME (dparam), dparam);
|
|
|
|
switch (G_VALUE_TYPE (value)) {
|
|
case G_TYPE_FLOAT:
|
|
g_value_set_float (value, dparam->value_float);
|
|
break;
|
|
|
|
case G_TYPE_DOUBLE:
|
|
g_value_set_double (value, dparam->value_double);
|
|
break;
|
|
|
|
case G_TYPE_INT:
|
|
g_value_set_int (value, dparam->value_int);
|
|
break;
|
|
|
|
case G_TYPE_INT64:
|
|
g_value_set_int64 (value, dparam->value_int64);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
GST_DPARAM_LAST_UPDATE_TIMESTAMP (dparam) = timestamp;
|
|
GST_DPARAM_NEXT_UPDATE_TIMESTAMP (dparam) = timestamp;
|
|
GST_DPARAM_READY_FOR_UPDATE (dparam) = FALSE;
|
|
|
|
GST_DPARAM_UNLOCK (dparam);
|
|
}
|
|
|
|
static void
|
|
gst_dparam_dispose (GObject * object)
|
|
{
|
|
GstDParam *dparam = GST_DPARAM (object);
|
|
gchar *dparam_name = g_strdup (GST_DPARAM_NAME (dparam));
|
|
|
|
GST_DEBUG ("disposing of %s", dparam_name);
|
|
if (GST_DPARAM_MANAGER (dparam)) {
|
|
gst_dpman_detach_dparam (GST_DPARAM_MANAGER (dparam), dparam_name);
|
|
}
|
|
g_free (dparam_name);
|
|
}
|
|
|
|
/**
|
|
* gst_dparam_attach
|
|
* @dparam: GstDParam instance
|
|
* @manager: the GstDParamManager that this dparam belongs to
|
|
* @param_spec: the specification for the parameter
|
|
* @unit_name: the name of the unit
|
|
*
|
|
* Adding the parameter controller to the manager using the
|
|
* supplied specs and unit.
|
|
* See also gst_dpman_attach_dparam().
|
|
*/
|
|
void
|
|
gst_dparam_attach (GstDParam * dparam, GstDParamManager * manager,
|
|
GParamSpec * param_spec, gchar * unit_name)
|
|
{
|
|
GValue value = { 0, };
|
|
|
|
g_return_if_fail (dparam != NULL);
|
|
g_return_if_fail (GST_IS_DPARAM (dparam));
|
|
g_return_if_fail (manager != NULL);
|
|
g_return_if_fail (GST_IS_DPMAN (manager));
|
|
g_return_if_fail (param_spec != NULL);
|
|
g_return_if_fail (unit_name != NULL);
|
|
g_return_if_fail (G_IS_PARAM_SPEC (param_spec));
|
|
g_return_if_fail (G_PARAM_SPEC_VALUE_TYPE (param_spec) ==
|
|
GST_DPARAM_TYPE (dparam));
|
|
|
|
gst_object_set_name (GST_OBJECT (dparam), g_param_spec_get_name (param_spec));
|
|
GST_DPARAM_PARAM_SPEC (dparam) = param_spec;
|
|
GST_DPARAM_MANAGER (dparam) = manager;
|
|
GST_DPARAM_UNIT_NAME (dparam) = 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);
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gst_dparam_detach
|
|
* @dparam: GstDParam instance
|
|
*
|
|
* Removes a previousely added parameter controller.
|
|
*/
|
|
void
|
|
gst_dparam_detach (GstDParam * dparam)
|
|
{
|
|
|
|
g_return_if_fail (dparam != NULL);
|
|
g_return_if_fail (GST_IS_DPARAM (dparam));
|
|
|
|
GST_DEBUG ("detaching %s from dparam %p", GST_DPARAM_NAME (dparam), dparam);
|
|
|
|
gst_object_set_name (GST_OBJECT (dparam), NULL);
|
|
GST_DPARAM_PARAM_SPEC (dparam) = NULL;
|
|
GST_DPARAM_MANAGER (dparam) = NULL;
|
|
}
|