a few internal changes:

Original commit message from CVS:
a few internal changes:
- put last_update_timestamp into GstDParam
- added a GstDParamUpdateInfo enum to the update function so that dparams know what context they are updating in (for example, the first update since the pipeline was started)
- rewrote bogus next_timestamp calculation in GstDParamSmooth
This commit is contained in:
Steve Baker 2002-05-05 15:39:37 +00:00
parent 4321f75fbd
commit b4d1d31ded
6 changed files with 68 additions and 55 deletions

View file

@ -99,6 +99,7 @@ gst_dparam_init (GstDParam *dparam)
g_return_if_fail (dparam != NULL); g_return_if_fail (dparam != NULL);
GST_DPARAM_TYPE(dparam) = 0; GST_DPARAM_TYPE(dparam) = 0;
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam)=0LL; GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam)=0LL;
GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam)=0LL;
GST_DPARAM_READY_FOR_UPDATE(dparam)=FALSE; GST_DPARAM_READY_FOR_UPDATE(dparam)=FALSE;
dparam->lock = g_mutex_new (); dparam->lock = g_mutex_new ();
} }
@ -150,18 +151,21 @@ gst_dparam_set_property (GObject *object, guint prop_id, const GValue *value, GP
GST_DEBUG(GST_CAT_PARAMS, "setting value from %f to %f", dparam->value_float, g_value_get_float (value)); GST_DEBUG(GST_CAT_PARAMS, "setting value from %f to %f", dparam->value_float, g_value_get_float (value));
dparam->value_float = g_value_get_float (value); dparam->value_float = g_value_get_float (value);
GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam);
break; break;
case ARG_VALUE_INT: case ARG_VALUE_INT:
GST_DEBUG(GST_CAT_PARAMS, "setting value from %d to %d", dparam->value_int, g_value_get_int (value)); GST_DEBUG(GST_CAT_PARAMS, "setting value from %d to %d", dparam->value_int, g_value_get_int (value));
dparam->value_int = g_value_get_int (value); dparam->value_int = g_value_get_int (value);
GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam);
break; break;
case ARG_VALUE_INT64: case ARG_VALUE_INT64:
GST_DEBUG(GST_CAT_PARAMS, "setting value from %lld to %lld", dparam->value_int64, g_value_get_int64 (value)); GST_DEBUG(GST_CAT_PARAMS, "setting value from %lld to %lld", dparam->value_int64, g_value_get_int64 (value));
dparam->value_int64 = g_value_get_int (value); dparam->value_int64 = g_value_get_int (value);
GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam);
break; break;
default: default:
@ -171,7 +175,7 @@ gst_dparam_set_property (GObject *object, guint prop_id, const GValue *value, GP
} }
void void
gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value) gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info)
{ {
GST_DPARAM_LOCK(dparam); GST_DPARAM_LOCK(dparam);
@ -196,6 +200,8 @@ gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value
} }
GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE;
GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp;
GST_DPARAM_UNLOCK(dparam); GST_DPARAM_UNLOCK(dparam);
} }

View file

@ -51,13 +51,20 @@ extern "C" {
#define GST_DPARAM_READY_FOR_UPDATE(dparam) ((dparam)->ready_for_update) #define GST_DPARAM_READY_FOR_UPDATE(dparam) ((dparam)->ready_for_update)
#define GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) ((dparam)->next_update_timestamp) #define GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) ((dparam)->next_update_timestamp)
#define GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) ((dparam)->last_update_timestamp)
#define GST_DPARAM_DO_UPDATE(dparam, timestamp, value) \ #define GST_DPARAM_DO_UPDATE(dparam, timestamp, value, update_info) \
((dparam->do_update_func)(dparam, timestamp, value)) ((dparam->do_update_func)(dparam, timestamp, value, update_info))
typedef struct _GstDParamClass GstDParamClass; typedef struct _GstDParamClass GstDParamClass;
typedef void (*GstDParamDoUpdateFunction) (GstDParam *dparam, gint64 timestamp, GValue *value);
typedef enum {
GST_DPARAM_UPDATE_FIRST,
GST_DPARAM_UPDATE_NORMAL,
} GstDParamUpdateInfo;
typedef void (*GstDParamDoUpdateFunction) (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info);
struct _GstDParam { struct _GstDParam {
GstObject object; GstObject object;
@ -76,6 +83,7 @@ struct _GstDParam {
gboolean ready_for_update; gboolean ready_for_update;
gint64 next_update_timestamp; gint64 next_update_timestamp;
gint64 last_update_timestamp;
gchar *unit_name; gchar *unit_name;
gboolean is_log; gboolean is_log;
}; };
@ -91,7 +99,7 @@ GType gst_dparam_get_type (void);
GstDParam* gst_dparam_new (GType type); GstDParam* gst_dparam_new (GType type);
void gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gchar *unit_name); void gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gchar *unit_name);
void gst_dparam_detach (GstDParam *dparam); void gst_dparam_detach (GstDParam *dparam);
void gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value); void gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -30,8 +30,7 @@ static void gst_dpsmooth_class_init (GstDParamSmoothClass *klass);
static void gst_dpsmooth_init (GstDParamSmooth *dparam); static void gst_dpsmooth_init (GstDParamSmooth *dparam);
static void gst_dpsmooth_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_dpsmooth_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static gint64 gst_dpsmooth_time_since_last_update(GstDParam *dparam, gint64 timestamp); static void gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info);
static void gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value);
enum { enum {
ARG_0, ARG_0,
@ -132,7 +131,6 @@ gst_dpsmooth_new (GType type)
dparam->do_update_func = gst_dparam_do_update_default; dparam->do_update_func = gst_dparam_do_update_default;
break; break;
} }
dpsmooth->last_update_timestamp = 0LL;
return dparam; return dparam;
} }
@ -199,35 +197,8 @@ gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParam
} }
} }
static gint64
gst_dpsmooth_time_since_last_update(GstDParam *dparam, gint64 timestamp)
{
gint64 time_diff, last_update_diff, num_update_periods;
GstDParamSmooth *dpsmooth = GST_DPSMOOTH(dparam);
last_update_diff = timestamp - dpsmooth->last_update_timestamp;
time_diff = MIN(dpsmooth->update_period, last_update_diff);
GST_DEBUG(GST_CAT_PARAMS, "last_update_diff:%lld",last_update_diff);
GST_DEBUG(GST_CAT_PARAMS, "time_diff:%lld",time_diff);
dpsmooth->last_update_timestamp = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam);
if(GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp && dpsmooth->update_period > 0LL){
GST_DEBUG(GST_CAT_PARAMS, "dpsmooth->update_period:%lld",dpsmooth->update_period);
num_update_periods = last_update_diff / dpsmooth->update_period;
GST_DEBUG(GST_CAT_PARAMS, "num_update_periods:%lld",num_update_periods);
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = dpsmooth->update_period * (num_update_periods + 1LL);
}
GST_DEBUG(GST_CAT_PARAMS, "last:%lld current:%lld next:%lld",
dpsmooth->last_update_timestamp, timestamp, GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam));
return time_diff;
}
static void static void
gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value) gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info)
{ {
gint64 time_diff; gint64 time_diff;
gfloat time_ratio; gfloat time_ratio;
@ -238,9 +209,21 @@ gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value
GST_DPARAM_LOCK(dparam); GST_DPARAM_LOCK(dparam);
time_diff = gst_dpsmooth_time_since_last_update(dparam, timestamp); if (update_info == GST_DPARAM_UPDATE_FIRST){
/*this is the first update since the pipeline started.
* the value won't be smoothed, it will be updated immediately
*/
g_value_set_float(value, dparam->value_float);
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);
return;
}
time_diff = timestamp - GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam);
target = dparam->value_float; target = dparam->value_float;
current = g_value_get_float(value); current = g_value_get_float(value);
@ -255,7 +238,6 @@ gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value
if (current == 0.0F){ if (current == 0.0F){
/* this shouldn't happen, so forget about smoothing and just set the value */ /* this shouldn't happen, so forget about smoothing and just set the value */
final_val = target; final_val = target;
GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE;
} }
else { else {
gfloat current_log; gfloat current_log;
@ -265,27 +247,34 @@ gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value
GST_DEBUG(GST_CAT_PARAMS, "current_log:%f",current_log); GST_DEBUG(GST_CAT_PARAMS, "current_log:%f",current_log);
GST_DEBUG(GST_CAT_PARAMS, "current_diff:%f",current_diff); GST_DEBUG(GST_CAT_PARAMS, "current_diff:%f",current_diff);
if (current_diff > max_change) if (current_diff > max_change){
final_val = (target < current) ? exp(current_log-max_change) : exp(current_log+max_change); final_val = (target < current) ? exp(current_log-max_change) : exp(current_log+max_change);
else
final_val = target;
GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE;
} }
else {
final_val = target;
}
}
} }
else { else {
current_diff = ABS (current - target); current_diff = ABS (current - target);
if (current_diff > max_change) if (current_diff > max_change){
final_val = (target < current) ? current-max_change : current+max_change; final_val = (target < current) ? current-max_change : current+max_change;
else }
else {
final_val = target; final_val = target;
GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; }
} }
GST_DPARAM_READY_FOR_UPDATE(dparam) = (current_diff > max_change); GST_DPARAM_READY_FOR_UPDATE(dparam) = (final_val != target);
g_value_set_float(value, final_val); if (GST_DPARAM_READY_FOR_UPDATE(dparam)){
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp + dpsmooth->update_period;
}
GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;
g_value_set_float(value, final_val);
GST_DEBUG(GST_CAT_PARAMS, "target:%f current:%f final:%f actual:%f", target, current, final_val, g_value_get_float(value)); GST_DEBUG(GST_CAT_PARAMS, "target:%f current:%f final:%f actual:%f", target, current, final_val, g_value_get_float(value));
GST_DPARAM_UNLOCK(dparam); GST_DPARAM_UNLOCK(dparam);
} }

View file

@ -40,7 +40,6 @@ typedef struct _GstDParamSmooth GstDParamSmooth;
struct _GstDParamSmooth { struct _GstDParamSmooth {
GstDParam dparam; GstDParam dparam;
gint64 last_update_timestamp;
gint64 update_period; gint64 update_period;
gint64 slope_time; gint64 slope_time;
gfloat slope_delta_float; gfloat slope_delta_float;

View file

@ -628,6 +628,9 @@ gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, Gst
if (new_state == GST_STATE_PLAYING){ if (new_state == GST_STATE_PLAYING){
GST_DEBUG(GST_CAT_PARAMS, "initialising params"); GST_DEBUG(GST_CAT_PARAMS, "initialising params");
/* some dparams treat the first update after the pipeline starts differently */
dpman->update_info = GST_DPARAM_UPDATE_FIRST;
/* force all params to be updated */ /* force all params to be updated */
dwraps = GST_DPMAN_DPARAMS_LIST(dpman); dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
@ -637,9 +640,7 @@ gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, Gst
if (dparam){ if (dparam){
GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
/*if (dparam->spec){ GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = 0LL;
g_value_copy(dparam->spec->default_val, dpwrap->value);
}*/
} }
dwraps = g_slist_next(dwraps); dwraps = g_slist_next(dwraps);
} }
@ -676,7 +677,10 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t
while (dwraps){ while (dwraps){
dpwrap = (GstDParamWrapper*)dwraps->data; dpwrap = (GstDParamWrapper*)dwraps->data;
dparam = dpwrap->dparam; dparam = dpwrap->dparam;
/*g_print("timestamp %lld \n", timestamp);
if (dparam)
g_print("next update: %lld \n", GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam));*/
if (dparam && (GST_DPARAM_READY_FOR_UPDATE(dparam) && if (dparam && (GST_DPARAM_READY_FOR_UPDATE(dparam) &&
(GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp))){ (GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp))){
@ -684,7 +688,7 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t
/* direct method - set the value directly in the struct of the element */ /* direct method - set the value directly in the struct of the element */
case GST_DPMAN_DIRECT: case GST_DPMAN_DIRECT:
GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value); GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value, dpman->update_info);
GST_DEBUG(GST_CAT_PARAMS, "doing direct update"); GST_DEBUG(GST_CAT_PARAMS, "doing direct update");
switch (G_VALUE_TYPE(dpwrap->value)){ switch (G_VALUE_TYPE(dpwrap->value)){
case G_TYPE_INT: case G_TYPE_INT:
@ -703,7 +707,7 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t
/* callback method - call the element's callback so it can do what it likes */ /* callback method - call the element's callback so it can do what it likes */
case GST_DPMAN_CALLBACK: case GST_DPMAN_CALLBACK:
GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value); GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value, dpman->update_info);
GST_DEBUG(GST_CAT_PARAMS, "doing callback update"); GST_DEBUG(GST_CAT_PARAMS, "doing callback update");
GST_DPMAN_DO_UPDATE(dpwrap); GST_DPMAN_DO_UPDATE(dpwrap);
break; break;
@ -729,6 +733,12 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t
} }
dwraps = g_slist_next(dwraps); dwraps = g_slist_next(dwraps);
} }
if (dpman->update_info == GST_DPARAM_UPDATE_FIRST){
/* it is not the first update anymore */
dpman->update_info = GST_DPARAM_UPDATE_NORMAL;
}
return frames; return frames;
} }

View file

@ -77,6 +77,7 @@ struct _GstDParamManager {
gint64 timestamp; gint64 timestamp;
guint rate; guint rate;
GstDParamUpdateInfo update_info;
}; };
struct _GstDParamManagerClass { struct _GstDParamManagerClass {