mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
many changes including:
Original commit message from CVS: many changes including: - now the rate needs to be set explicitly, instead of from a pad - asynchronous mode has been implemented - and it even works - some refactoring of the process code - a plugin api change, GST_DPMAN_PREPROCESS and GST_DPMAN_PROCESS have changed a bit they are now *a lot* simpler to use, more flexible, and optimised so that the process func is never called if nothing changes - all in all worth the api breakage. UPDATE YOUR PLUGINS PEOPLE!
This commit is contained in:
parent
fc7a6ad8c9
commit
2caef6eec9
2 changed files with 358 additions and 129 deletions
|
@ -34,13 +34,20 @@ enum {
|
|||
static void gst_dpman_class_init (GstDParamManagerClass *klass);
|
||||
static void gst_dpman_init (GstDParamManager *dpman);
|
||||
static void gst_dpman_dispose (GObject *object);
|
||||
static GstDParamWrapper* gst_dpman_new_wrapper(GstDParamManager *dpman, GParamSpec *param_spec, gchar *unit_name, GstDPMUpdateMethod update_method);
|
||||
static GstDParamWrapper* gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name);
|
||||
static GstDParamWrapper* gst_dpman_new_wrapper(GstDParamManager *dpman, GParamSpec *param_spec, gchar *unit_name, GstDPMUpdateMethod update_method);
|
||||
static GstDParamWrapper* gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name);
|
||||
static void gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, GstDParamManager *dpman);
|
||||
static void gst_dpman_caps_changed (GstPad *pad, GstCaps *caps, GstDParamManager *dpman);
|
||||
static guint gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
static guint gst_dpman_preprocess_noop(GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
static guint gst_dpman_process_noop(GstDParamManager *dpman, guint frame_count);
|
||||
static gboolean gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
static gboolean gst_dpman_preprocess_asynchronous(GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
static gboolean gst_dpman_process_asynchronous(GstDParamManager *dpman, guint frame_count);
|
||||
static gboolean gst_dpman_preprocess_noop(GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
static gboolean gst_dpman_process_noop(GstDParamManager *dpman, guint frame_count);
|
||||
static void gst_dpman_setup_synchronous(GstDParamManager *dpman);
|
||||
static void gst_dpman_setup_asynchronous(GstDParamManager *dpman);
|
||||
static void gst_dpman_setup_disabled(GstDParamManager *dpman);
|
||||
static void gst_dpman_teardown_synchronous(GstDParamManager *dpman);
|
||||
static void gst_dpman_teardown_asynchronous(GstDParamManager *dpman);
|
||||
static void gst_dpman_teardown_disabled(GstDParamManager *dpman);
|
||||
|
||||
static GObjectClass *parent_class;
|
||||
static guint gst_dpman_signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -91,11 +98,14 @@ gst_dpman_class_init (GstDParamManagerClass *klass)
|
|||
klass->modes = g_hash_table_new(g_str_hash,g_str_equal);
|
||||
|
||||
gst_dpman_register_mode (klass, "synchronous",
|
||||
gst_dpman_preprocess_synchronous, gst_dpman_process_noop, NULL, NULL);
|
||||
gst_dpman_preprocess_synchronous, gst_dpman_process_noop,
|
||||
gst_dpman_setup_synchronous, gst_dpman_teardown_synchronous);
|
||||
gst_dpman_register_mode (klass, "asynchronous",
|
||||
gst_dpman_preprocess_noop, gst_dpman_process_noop, NULL, NULL);
|
||||
gst_dpman_preprocess_asynchronous, gst_dpman_process_asynchronous,
|
||||
gst_dpman_setup_asynchronous, gst_dpman_teardown_asynchronous);
|
||||
gst_dpman_register_mode (klass, "disabled",
|
||||
gst_dpman_preprocess_noop, gst_dpman_process_noop, NULL, NULL);
|
||||
gst_dpman_preprocess_noop, gst_dpman_process_noop,
|
||||
gst_dpman_setup_disabled, gst_dpman_teardown_disabled);
|
||||
|
||||
|
||||
gst_dpman_signals[NEW_REQUIRED_DPARAM] =
|
||||
|
@ -115,7 +125,6 @@ gst_dpman_init (GstDParamManager *dpman)
|
|||
GST_DPMAN_PARENT(dpman) = NULL;
|
||||
GST_DPMAN_MODE_NAME(dpman) = NULL;
|
||||
GST_DPMAN_MODE(dpman) = NULL;
|
||||
GST_DPMAN_MODE_DATA(dpman) = NULL;
|
||||
GST_DPMAN_RATE(dpman) = 0;
|
||||
}
|
||||
|
||||
|
@ -274,7 +283,7 @@ gst_dpman_remove_required_dparam (GstDParamManager *dpman, gchar *dparam_name)
|
|||
GST_DEBUG(GST_CAT_PARAMS, "removing required dparam: %s", dparam_name);
|
||||
|
||||
g_hash_table_remove(GST_DPMAN_DPARAMS(dpman), dparam_name);
|
||||
GST_DPMAN_DPARAMS_LIST(dpman) = g_slist_remove(GST_DPMAN_DPARAMS_LIST(dpman), dpwrap);
|
||||
GST_DPMAN_DPARAMS_LIST(dpman) = g_list_remove(GST_DPMAN_DPARAMS_LIST(dpman), dpwrap);
|
||||
|
||||
g_free(dpwrap->value);
|
||||
g_free(dpwrap);
|
||||
|
@ -383,21 +392,21 @@ GParamSpec**
|
|||
gst_dpman_list_dparam_specs(GstDParamManager *dpman)
|
||||
{
|
||||
GstDParamWrapper* dpwrap;
|
||||
GSList *dpwraps;
|
||||
GList *dwraps;
|
||||
GParamSpec** param_specs;
|
||||
guint x = 0;
|
||||
|
||||
g_return_val_if_fail (dpman != NULL, NULL);
|
||||
g_return_val_if_fail (GST_IS_DPMAN (dpman), NULL);
|
||||
|
||||
dpwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
|
||||
param_specs = g_new0(GParamSpec*, g_slist_length(dpwraps) + 1);
|
||||
param_specs = g_new0(GParamSpec*, g_list_length(dwraps) + 1);
|
||||
|
||||
while (dpwraps){
|
||||
dpwrap = (GstDParamWrapper*)dpwraps->data;
|
||||
while (dwraps){
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
param_specs[x++] = dpwrap->param_spec;
|
||||
dpwraps = g_slist_next(dpwraps);
|
||||
dwraps = g_list_next(dwraps);
|
||||
}
|
||||
return param_specs;
|
||||
}
|
||||
|
@ -415,6 +424,13 @@ gst_dpman_get_param_spec (GstDParamManager *dpman, gchar *dparam_name)
|
|||
return dpwrap->param_spec;
|
||||
}
|
||||
|
||||
void
|
||||
gst_dpman_set_rate (GstDParamManager *dpman, gint rate)
|
||||
{
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
GST_DPMAN_RATE(dpman) = rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_dpman_register_mode
|
||||
* @klass: GstDParamManagerClass class instance
|
||||
|
@ -529,24 +545,6 @@ gst_dpman_get_manager (GstElement *parent)
|
|||
return dpman;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_dpman_set_rate_change_pad
|
||||
* @dpman: GstDParamManager instance
|
||||
* @pad: the pad which may have a "rate" caps property
|
||||
*
|
||||
*/
|
||||
void
|
||||
gst_dpman_set_rate_change_pad(GstDParamManager *dpman, GstPad *pad)
|
||||
{
|
||||
g_return_if_fail (dpman != NULL);
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
g_return_if_fail (pad != NULL);
|
||||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
|
||||
g_signal_connect(G_OBJECT(pad), "caps_changed",
|
||||
G_CALLBACK (gst_dpman_caps_changed), dpman);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_dpman_bypass_dparam:
|
||||
* @dpman: GstDParamManager instance
|
||||
|
@ -610,7 +608,7 @@ gst_dpman_new_wrapper(GstDParamManager *dpman,
|
|||
dpwrap->unit_name = unit_name;
|
||||
|
||||
g_hash_table_insert(GST_DPMAN_DPARAMS(dpman), dparam_name, dpwrap);
|
||||
GST_DPMAN_DPARAMS_LIST(dpman) = g_slist_append(GST_DPMAN_DPARAMS_LIST(dpman), dpwrap);
|
||||
GST_DPMAN_DPARAMS_LIST(dpman) = g_list_append(GST_DPMAN_DPARAMS_LIST(dpman), dpwrap);
|
||||
|
||||
return dpwrap;
|
||||
}
|
||||
|
@ -619,7 +617,7 @@ gst_dpman_new_wrapper(GstDParamManager *dpman,
|
|||
static void
|
||||
gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, GstDParamManager *dpman)
|
||||
{
|
||||
GSList *dwraps;
|
||||
GList *dwraps;
|
||||
GstDParam *dparam;
|
||||
GstDParamWrapper *dpwrap;
|
||||
|
||||
|
@ -629,8 +627,6 @@ gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, Gst
|
|||
if (new_state == GST_STATE_PLAYING){
|
||||
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 */
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
|
@ -642,115 +638,335 @@ gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, Gst
|
|||
GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
|
||||
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = 0LL;
|
||||
}
|
||||
dwraps = g_slist_next(dwraps);
|
||||
/* some dparams treat the first update after the pipeline starts differently */
|
||||
dpwrap->update_info = GST_DPARAM_UPDATE_FIRST;
|
||||
dwraps = g_list_next(dwraps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_caps_changed (GstPad *pad, GstCaps *caps, GstDParamManager *dpman)
|
||||
{
|
||||
gint rate;
|
||||
|
||||
g_return_if_fail (caps != NULL);
|
||||
g_return_if_fail (dpman != NULL);
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
gst_caps_get_int (caps, "rate", &rate);
|
||||
GST_DPMAN_RATE(dpman) = rate;
|
||||
|
||||
GST_DEBUG(GST_CAT_PARAMS, "got caps change %d", GST_DPMAN_RATE(dpman));
|
||||
static inline void
|
||||
gst_dpman_inline_direct_update(GValue *value, gpointer data){
|
||||
switch (G_VALUE_TYPE(value)){
|
||||
case G_TYPE_INT:
|
||||
*(gint*)data = g_value_get_int(value);
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
*(gint64*)data = g_value_get_int64(value);
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
*(gfloat*)data = g_value_get_float(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
static gboolean
|
||||
gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 timestamp)
|
||||
{
|
||||
GSList *dwraps;
|
||||
GstDParam *dparam;
|
||||
GList *dwraps;
|
||||
GstDParamWrapper *dpwrap;
|
||||
|
||||
g_return_val_if_fail (dpman != NULL, frames);
|
||||
g_return_val_if_fail (GST_IS_DPMAN (dpman), frames);
|
||||
g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE);
|
||||
|
||||
/* now check whether any passive dparams are ready for an update */
|
||||
/* this basically means don't call GST_DPMAN_PREPROCESS at all */
|
||||
dpman->next_update_frame = frames;
|
||||
dpman->frames_to_process = frames;
|
||||
|
||||
/* now check whether any dparams are ready for an update */
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
while (dwraps){
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
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) &&
|
||||
(GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp))){
|
||||
if (dpwrap->dparam &&
|
||||
GST_DPARAM_READY_FOR_UPDATE(dpwrap->dparam) &&
|
||||
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dpwrap->dparam) <= timestamp){
|
||||
|
||||
switch (dpwrap->update_method) {
|
||||
|
||||
/* direct method - set the value directly in the struct of the element */
|
||||
case GST_DPMAN_DIRECT:
|
||||
GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value, dpman->update_info);
|
||||
GST_DPARAM_DO_UPDATE(dpwrap->dparam, timestamp, dpwrap->value, dpwrap->update_info);
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing direct update");
|
||||
switch (G_VALUE_TYPE(dpwrap->value)){
|
||||
case G_TYPE_INT:
|
||||
*(gint*)dpwrap->update_data = g_value_get_int(dpwrap->value);
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
*(gint64*)dpwrap->update_data = g_value_get_int64(dpwrap->value);
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
*(gfloat*)dpwrap->update_data = g_value_get_float(dpwrap->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gst_dpman_inline_direct_update(dpwrap->value, dpwrap->update_data);
|
||||
break;
|
||||
|
||||
/* callback method - call the element's callback so it can do what it likes */
|
||||
case GST_DPMAN_CALLBACK:
|
||||
GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value, dpman->update_info);
|
||||
GST_DPARAM_DO_UPDATE(dpwrap->dparam, timestamp, dpwrap->value, dpwrap->update_info);
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing callback update");
|
||||
GST_DPMAN_DO_UPDATE(dpwrap);
|
||||
|
||||
GST_DPMAN_CALLBACK_UPDATE(dpwrap, dpwrap->value);
|
||||
break;
|
||||
|
||||
/* array method - generate an array of the right size */
|
||||
/* with each value being the same (in synchronous update mode) */
|
||||
case GST_DPMAN_ARRAY:
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing array update");
|
||||
switch (G_VALUE_TYPE(dpwrap->value)){
|
||||
case G_TYPE_INT:
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
/* FIXME do array method checking here */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
dwraps = g_slist_next(dwraps);
|
||||
}
|
||||
|
||||
if (dpman->update_info == GST_DPARAM_UPDATE_FIRST){
|
||||
if (dpwrap->update_info == GST_DPARAM_UPDATE_FIRST){
|
||||
/* it is not the first update anymore */
|
||||
dpman->update_info = GST_DPARAM_UPDATE_NORMAL;
|
||||
dpwrap->update_info = GST_DPARAM_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
dwraps = g_list_next(dwraps);
|
||||
}
|
||||
|
||||
return frames;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
static gint
|
||||
gst_dpman_dpwrap_compare (const GstDParamWrapper *a, const GstDParamWrapper *b)
|
||||
{
|
||||
if (a->next_update_frame > b->next_update_frame) return 1;
|
||||
return (a->next_update_frame < b->next_update_frame) ? -1 : 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_dpman_preprocess_asynchronous(GstDParamManager *dpman, guint frames, gint64 timestamp)
|
||||
{
|
||||
GList *dwraps;
|
||||
GstDParamWrapper *dpwrap;
|
||||
gint64 current_time;
|
||||
gboolean updates_pending;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE);
|
||||
|
||||
|
||||
if (GST_DPMAN_RATE(dpman) == 0){
|
||||
g_warning("The element hasn't given GstDParamManager a frame rate");
|
||||
return FALSE;
|
||||
}
|
||||
dpman->rate_ratio = (guint)(1000000000LL / (gint64)GST_DPMAN_RATE(dpman));
|
||||
|
||||
dpman->time_buffer_starts = timestamp;
|
||||
dpman->time_buffer_ends = timestamp + ((gint64)frames * (gint64)dpman->rate_ratio);
|
||||
dpman->num_frames = frames;
|
||||
|
||||
updates_pending = FALSE;
|
||||
|
||||
/* now check whether any dparams are ready for an update */
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
while (dwraps){
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
|
||||
dpwrap->next_update_frame = frames;
|
||||
|
||||
if (dpwrap->dparam &&
|
||||
GST_DPARAM_READY_FOR_UPDATE(dpwrap->dparam)){
|
||||
|
||||
current_time = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dpwrap->dparam);
|
||||
if (current_time > dpman->time_buffer_ends){
|
||||
/* not due for an update in this buffer */
|
||||
dwraps = g_list_next(dwraps);
|
||||
continue;
|
||||
}
|
||||
if (current_time < timestamp){
|
||||
current_time = timestamp;
|
||||
}
|
||||
|
||||
if (current_time == timestamp){
|
||||
/* we are overdue for an update. lets do it now */
|
||||
|
||||
GST_DPARAM_DO_UPDATE(dpwrap->dparam, current_time, dpwrap->value, dpwrap->update_info);
|
||||
|
||||
if (dpwrap->update_info == GST_DPARAM_UPDATE_FIRST){
|
||||
/* it is not the first update anymore */
|
||||
dpwrap->update_info = GST_DPARAM_UPDATE_NORMAL;
|
||||
}
|
||||
|
||||
switch (dpwrap->update_method) {
|
||||
|
||||
/* direct method - set the value directly in the struct of the element */
|
||||
case GST_DPMAN_DIRECT:
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing direct update");
|
||||
gst_dpman_inline_direct_update(dpwrap->value, dpwrap->update_data);
|
||||
break;
|
||||
|
||||
/* callback method - call the element's callback so it can do what it likes */
|
||||
case GST_DPMAN_CALLBACK:
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing callback update");
|
||||
GST_DPMAN_CALLBACK_UPDATE(dpwrap, dpwrap->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
current_time = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dpwrap->dparam);
|
||||
|
||||
if (!GST_DPARAM_READY_FOR_UPDATE(dpwrap->dparam) ||
|
||||
current_time > dpman->time_buffer_ends){
|
||||
/* not due for an update in this buffer */
|
||||
dwraps = g_list_next(dwraps);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dpwrap->next_update_frame = (guint)(current_time - timestamp) / dpman->rate_ratio;
|
||||
updates_pending = TRUE;
|
||||
|
||||
GST_DEBUG(GST_CAT_PARAMS, "timestamp start: %lld end: %lld current: %lld",
|
||||
timestamp, dpman->time_buffer_ends, current_time);
|
||||
|
||||
}
|
||||
dwraps = g_list_next(dwraps);
|
||||
}
|
||||
if (updates_pending){
|
||||
GST_DPMAN_DPARAMS_LIST(dpman) = g_list_sort(GST_DPMAN_DPARAMS_LIST(dpman), (GCompareFunc)gst_dpman_dpwrap_compare);
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
|
||||
dpman->next_update_frame = dpwrap->next_update_frame;
|
||||
dpman->frames_to_process = dpman->next_update_frame;
|
||||
|
||||
GST_DEBUG(GST_CAT_PARAMS, "next update frame %u, frames to process %u", dpman->next_update_frame, dpman->frames_to_process);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
dpman->next_update_frame = frames;
|
||||
dpman->frames_to_process = frames;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_dpman_process_asynchronous(GstDParamManager *dpman, guint frame_count)
|
||||
{
|
||||
GstDParamWrapper *dpwrap;
|
||||
GList *dwraps;
|
||||
gint64 current_time;
|
||||
gboolean needs_resort = FALSE;
|
||||
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
|
||||
GST_DEBUG(GST_CAT_PARAMS, "in gst_dpman_process_asynchronous");
|
||||
|
||||
if (frame_count >= dpman->num_frames){
|
||||
g_warning("there is no more buffer to process");
|
||||
dpman->next_update_frame = dpman->num_frames;
|
||||
dpman->frames_to_process = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (frame_count != dpwrap->next_update_frame){
|
||||
g_warning("frame count %u does not match update frame %u",
|
||||
frame_count, dpwrap->next_update_frame);
|
||||
}
|
||||
|
||||
while (dpwrap){
|
||||
|
||||
current_time = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dpwrap->dparam);
|
||||
GST_DPARAM_DO_UPDATE(dpwrap->dparam, current_time, dpwrap->value, dpwrap->update_info);
|
||||
switch (dpwrap->update_method) {
|
||||
|
||||
/* direct method - set the value directly in the struct of the element */
|
||||
case GST_DPMAN_DIRECT:
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing direct update");
|
||||
gst_dpman_inline_direct_update(dpwrap->value, dpwrap->update_data);
|
||||
break;
|
||||
|
||||
/* callback method - call the element's callback so it can do what it likes */
|
||||
case GST_DPMAN_CALLBACK:
|
||||
GST_DEBUG(GST_CAT_PARAMS, "doing callback update");
|
||||
GST_DPMAN_CALLBACK_UPDATE(dpwrap, dpwrap->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dpwrap->next_update_frame = dpman->num_frames;
|
||||
needs_resort = TRUE;
|
||||
|
||||
if(GST_DPARAM_READY_FOR_UPDATE(dpwrap->dparam)){
|
||||
current_time = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dpwrap->dparam);
|
||||
if (current_time <= dpman->time_buffer_ends){
|
||||
dpwrap->next_update_frame = (guint)(current_time - dpman->time_buffer_starts) / dpman->rate_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dwraps = g_list_next(dwraps))){
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
if (frame_count == dpwrap->next_update_frame){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dpwrap = NULL;
|
||||
}
|
||||
|
||||
if (needs_resort && g_list_length(GST_DPMAN_DPARAMS_LIST(dpman)) > 1){
|
||||
GST_DPMAN_DPARAMS_LIST(dpman) = g_list_sort(GST_DPMAN_DPARAMS_LIST(dpman), (GCompareFunc)gst_dpman_dpwrap_compare);
|
||||
}
|
||||
|
||||
dwraps = GST_DPMAN_DPARAMS_LIST(dpman);
|
||||
dpwrap = (GstDParamWrapper*)dwraps->data;
|
||||
|
||||
if (dpwrap->next_update_frame == dpman->num_frames){
|
||||
dpman->next_update_frame = dpman->num_frames;
|
||||
dpman->frames_to_process = dpman->num_frames - frame_count;
|
||||
GST_DEBUG(GST_CAT_PARAMS, "no more updates, frames to process %u", dpman->frames_to_process);
|
||||
}
|
||||
else {
|
||||
dpman->next_update_frame = dpwrap->next_update_frame;
|
||||
dpman->frames_to_process = dpman->next_update_frame - frame_count;
|
||||
GST_DEBUG(GST_CAT_PARAMS, "next update frame %u, frames to process %u", dpman->next_update_frame, dpman->frames_to_process);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_dpman_preprocess_noop(GstDParamManager *dpman, guint frames, gint64 timestamp)
|
||||
{
|
||||
return frames;
|
||||
dpman->next_update_frame = frames;
|
||||
dpman->frames_to_process = frames;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
static gboolean
|
||||
gst_dpman_process_noop(GstDParamManager *dpman, guint frame_count)
|
||||
{
|
||||
return 0;
|
||||
g_warning("gst_dpman_process_noop should never be called - something might be wrong with your processing loop");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_setup_synchronous(GstDParamManager *dpman){
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_setup_asynchronous(GstDParamManager *dpman){
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_setup_disabled(GstDParamManager *dpman){
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_teardown_synchronous(GstDParamManager *dpman){
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_teardown_asynchronous(GstDParamManager *dpman){
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dpman_teardown_disabled(GstDParamManager *dpman){
|
||||
g_return_if_fail (GST_IS_DPMAN (dpman));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,9 @@ extern "C" {
|
|||
|
||||
#define GST_DPMAN_MODE_NAME(dpman) ((dpman)->mode_name)
|
||||
#define GST_DPMAN_MODE(dpman) ((dpman)->mode)
|
||||
#define GST_DPMAN_MODE_DATA(dpman) ((dpman)->mode_data)
|
||||
#define GST_DPMAN_RATE(dpman) ((dpman)->rate)
|
||||
#define GST_DPMAN_FRAMES_TO_PROCESS(dpman) ((dpman)->frames_to_process)
|
||||
#define GST_DPMAN_NEXT_UPDATE_FRAME(dpman) ((dpman)->next_update_frame)
|
||||
|
||||
typedef enum {
|
||||
GST_DPMAN_CALLBACK,
|
||||
|
@ -57,9 +58,10 @@ typedef enum {
|
|||
typedef struct _GstDParamManagerClass GstDParamManagerClass;
|
||||
typedef struct _GstDPMMode GstDPMMode;
|
||||
typedef struct _GstDParamWrapper GstDParamWrapper;
|
||||
typedef struct _GstDParamAsyncToUpdate GstDParamAsyncToUpdate;
|
||||
|
||||
typedef guint (*GstDPMModePreProcessFunction) (GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
typedef guint (*GstDPMModeProcessFunction) (GstDParamManager *dpman, guint frame_count);
|
||||
typedef gboolean (*GstDPMModePreProcessFunction) (GstDParamManager *dpman, guint frames, gint64 timestamp);
|
||||
typedef gboolean (*GstDPMModeProcessFunction) (GstDParamManager *dpman, guint frame_count);
|
||||
typedef void (*GstDPMModeSetupFunction) (GstDParamManager *dpman);
|
||||
typedef void (*GstDPMModeTeardownFunction) (GstDParamManager *dpman);
|
||||
|
||||
|
@ -69,22 +71,29 @@ struct _GstDParamManager {
|
|||
GstObject object;
|
||||
|
||||
GHashTable *dparams;
|
||||
GSList *dparams_list;
|
||||
GList *dparams_list;
|
||||
|
||||
gchar *mode_name;
|
||||
/* mode state */
|
||||
GstDPMMode* mode;
|
||||
gpointer mode_data;
|
||||
gchar *mode_name;
|
||||
|
||||
gint64 timestamp;
|
||||
guint rate;
|
||||
GstDParamUpdateInfo update_info;
|
||||
guint frames_to_process; /* the number of frames in the current buffer */
|
||||
guint next_update_frame; /* the frame when the next update is required */
|
||||
|
||||
/* the following data is only used for async mode */
|
||||
guint rate; /* the frame/sample rate - */
|
||||
guint rate_ratio; /* number used to convert between samples and time */
|
||||
guint num_frames; /* the number of frames in the current buffer */
|
||||
|
||||
gint64 time_buffer_ends;
|
||||
gint64 time_buffer_starts;
|
||||
};
|
||||
|
||||
struct _GstDParamManagerClass {
|
||||
GstObjectClass parent_class;
|
||||
void (*new_required_dparam) (GstDParamManager *dpman, gchar* dparam_name);
|
||||
GHashTable *modes;
|
||||
/* signal callbacks */
|
||||
void (*new_required_dparam) (GstDParamManager *dpman, gchar* dparam_name);
|
||||
};
|
||||
|
||||
struct _GstDPMMode {
|
||||
|
@ -98,10 +107,21 @@ struct _GstDParamWrapper {
|
|||
GParamSpec* param_spec;
|
||||
GValue *value;
|
||||
GstDParam *dparam;
|
||||
|
||||
guint next_update_frame;
|
||||
|
||||
GstDPMUpdateMethod update_method;
|
||||
gpointer update_data;
|
||||
GstDPMUpdateFunction update_func;
|
||||
|
||||
gchar *unit_name;
|
||||
GstDParamUpdateInfo update_info;
|
||||
};
|
||||
|
||||
struct _GstDParamAsyncToUpdate {
|
||||
guint frame;
|
||||
GValue *value;
|
||||
GstDParamWrapper *dpwrap;
|
||||
};
|
||||
|
||||
#define GST_DPMAN_PREPROCESSFUNC(dpman) (((dpman)->mode)->preprocessfunc)
|
||||
|
@ -113,17 +133,10 @@ struct _GstDParamWrapper {
|
|||
(GST_DPMAN_PREPROCESSFUNC(dpman)(dpman, buffer_size, timestamp))
|
||||
|
||||
#define GST_DPMAN_PROCESS(dpman, frame_count) \
|
||||
(GST_DPMAN_PROCESSFUNC(dpman)(dpman, frame_count))
|
||||
(frame_count < dpman->next_update_frame || \
|
||||
(dpman->next_update_frame < dpman->num_frames && (GST_DPMAN_PROCESSFUNC(dpman)(dpman, frame_count))))
|
||||
|
||||
#define GST_DPMAN_PROCESS_COUNTDOWN(dpman, frame_countdown, frame_count) \
|
||||
(frame_countdown-- || \
|
||||
(frame_countdown = GST_DPMAN_PROCESS(dpman, frame_count)))
|
||||
|
||||
#define GST_DPMAN_PROCESS_CHUNK(dpman, frames_to_process, frame_count) \
|
||||
(frames_to_process || \
|
||||
(frames_to_process = GST_DPMAN_PROCESS(dpman, frame_count)))
|
||||
|
||||
#define GST_DPMAN_DO_UPDATE(dpwrap) ((dpwrap->update_func)(dpwrap->value, dpwrap->update_data))
|
||||
#define GST_DPMAN_CALLBACK_UPDATE(dpwrap, value) ((dpwrap->update_func)(value, dpwrap->update_data))
|
||||
|
||||
void _gst_dpman_initialize();
|
||||
GType gst_dpman_get_type (void);
|
||||
|
@ -156,7 +169,7 @@ GParamSpec** gst_dpman_list_dparam_specs(GstDParamManager *dpman);
|
|||
GParamSpec* gst_dpman_get_param_spec (GstDParamManager *dpman, gchar *dparam_name);
|
||||
void gst_dpman_dparam_spec_has_changed (GstDParamManager *dpman, gchar *dparam_name);
|
||||
|
||||
void gst_dpman_set_rate_change_pad(GstDParamManager *dpman, GstPad *pad);
|
||||
void gst_dpman_set_rate(GstDParamManager *dpman, gint rate);
|
||||
void gst_dpman_bypass_dparam(GstDParamManager *dpman, gchar *dparam_name);
|
||||
|
||||
gboolean gst_dpman_set_mode(GstDParamManager *dpman, gchar *modename);
|
||||
|
|
Loading…
Reference in a new issue