From c2bb95250bf647c8f89879bd1c0a749c6fe38ecf Mon Sep 17 00:00:00 2001 From: Palana Date: Mon, 16 Jun 2014 21:13:32 +0200 Subject: [PATCH] Add obs-data autoselect functions These are meant to reflect auto-detection configuration changes that should not be written to the config, for example, frame rate changes for a camera where the (user-/config-file-)configured frame rate isn't available but a similar frame rate can be automatically chosen --- libobs/obs-data.c | 339 ++++++++++++++++++++++++++++++++++++++++++++-- libobs/obs-data.h | 68 ++++++++++ 2 files changed, 396 insertions(+), 11 deletions(-) diff --git a/libobs/obs-data.c b/libobs/obs-data.c index d4218dc42..f83fe879a 100644 --- a/libobs/obs-data.c +++ b/libobs/obs-data.c @@ -34,7 +34,9 @@ struct obs_data_item { size_t name_len; size_t data_len; size_t data_size; + size_t default_len; size_t default_size; + size_t autoselect_size; size_t capacity; }; @@ -91,7 +93,7 @@ static inline void *get_data_ptr(obs_data_item_t item) static inline void *get_item_data(struct obs_data_item *item) { - if (!item->data_size && !item->default_size) + if (!item->data_size && !item->default_size && !item->autoselect_size) return NULL; return get_data_ptr(item); } @@ -106,10 +108,20 @@ static inline void *get_item_default_data(struct obs_data_item *item) return item->default_size ? get_default_data_ptr(item) : NULL; } +static inline void *get_autoselect_data_ptr(obs_data_item_t item) +{ + return (uint8_t*)get_default_data_ptr(item) + item->default_len; +} + +static inline void *get_item_autoselect_data(struct obs_data_item *item) +{ + return item->autoselect_size ? get_autoselect_data_ptr(item) : NULL; +} + static inline size_t obs_data_item_total_size(struct obs_data_item *item) { return sizeof(struct obs_data_item) + item->name_len + - item->data_len + item->default_size; + item->data_len + item->default_len + item->autoselect_size; } static inline obs_data_t get_item_obj(struct obs_data_item *item) @@ -128,6 +140,14 @@ static inline obs_data_t get_item_default_obj(struct obs_data_item *item) return *(obs_data_t*)get_item_data(item); } +static inline obs_data_t get_item_autoselect_obj(struct obs_data_item *item) +{ + if (!item || !item->autoselect_size) + return NULL; + + return *(obs_data_t*)get_item_data(item); +} + static inline obs_data_array_t get_item_array(struct obs_data_item *item) { if (!item) @@ -145,6 +165,15 @@ static inline obs_data_array_t get_item_default_array( return *(obs_data_array_t*)get_item_data(item); } +static inline obs_data_array_t get_item_autoselect_array( + struct obs_data_item *item) +{ + if (!item || !item->autoselect_size) + return NULL; + + return *(obs_data_array_t*)get_item_data(item); +} + static inline void item_data_release(struct obs_data_item *item) { if (!obs_data_item_has_user_value(item)) @@ -172,6 +201,18 @@ static inline void item_default_data_release(struct obs_data_item *item) } } +static inline void item_autoselect_data_release(struct obs_data_item *item) +{ + if (item->type == OBS_DATA_OBJECT) { + obs_data_t obj = get_item_autoselect_obj(item); + obs_data_release(obj); + + } else if (item->type == OBS_DATA_ARRAY) { + obs_data_array_t array = get_item_autoselect_array(item); + obs_data_array_release(array); + } +} + static inline void item_data_addref(struct obs_data_item *item) { if (item->type == OBS_DATA_OBJECT) { @@ -199,9 +240,21 @@ static inline void item_default_data_addref(struct obs_data_item *item) } } +static inline void item_autoselect_data_addref(struct obs_data_item *item) +{ + if (item->type == OBS_DATA_OBJECT) { + obs_data_t obj = get_item_autoselect_obj(item); + obs_data_addref(obj); + + } else if (item->type == OBS_DATA_ARRAY) { + obs_data_array_t array = get_item_autoselect_array(item); + obs_data_array_addref(array); + } +} + static struct obs_data_item *obs_data_item_create(const char *name, const void *data, size_t size, enum obs_data_type type, - bool default_data) + bool default_data, bool autoselect_data) { struct obs_data_item *item; size_t name_size, total_size; @@ -220,8 +273,12 @@ static struct obs_data_item *obs_data_item_create(const char *name, item->ref = 1; if (default_data) { + item->default_len = size; item->default_size = size; + } else if (autoselect_data) { + item->autoselect_size = size; + } else { item->data_len = size; item->data_size = size; @@ -295,6 +352,7 @@ static inline void obs_data_item_destroy(struct obs_data_item *item) { item_data_release(item); item_default_data_release(item); + item_autoselect_data_release(item); obs_data_item_detach(item); bfree(item); } @@ -324,11 +382,11 @@ static inline void obs_data_item_setdata( item->data_size = size; item->type = type; - item->data_len = item->default_size ? + item->data_len = (item->default_size || item->autoselect_size) ? get_align_size(size) : size; item = obs_data_item_ensure_capacity(item); - if (item->default_size) + if (item->default_size || item->autoselect_size) move_data(*p_item, old_non_user_data, item, get_default_data_ptr(item), item->default_len + item->autoselect_size); @@ -349,14 +407,22 @@ static inline void obs_data_item_set_default_data( return; struct obs_data_item *item = *p_item; + void *old_autoselect_data = get_autoselect_data_ptr(item); item_default_data_release(item); item->type = type; item->default_size = size; + item->default_len = item->autoselect_size ? + get_align_size(size) : size; item->data_len = item->data_size ? get_align_size(item->data_size) : 0; item = obs_data_item_ensure_capacity(item); + if (item->autoselect_size) + move_data(*p_item, old_autoselect_data, item, + get_autoselect_data_ptr(item), + item->autoselect_size); + if (size) { memcpy(get_item_default_data(item), data, size); item_default_data_addref(item); @@ -365,6 +431,32 @@ static inline void obs_data_item_set_default_data( *p_item = item; } +static inline void obs_data_item_set_autoselect_data( + struct obs_data_item **p_item, const void *data, size_t size, + enum obs_data_type type) +{ + if (!p_item || !*p_item) + return; + + struct obs_data_item *item = *p_item; + item_autoselect_data_release(item); + + item->autoselect_size = size; + item->type = type; + item->data_len = item->data_size ? + get_align_size(item->data_size) : 0; + item->default_len = item->default_size ? + get_align_size(item->default_size) : 0; + item = obs_data_item_ensure_capacity(item); + + if (size) { + memcpy(get_item_autoselect_data(item), data, size); + item_autoselect_data_addref(item); + } + + *p_item = item; +} + /* ------------------------------------------------------------------------- */ static void obs_data_add_json_item(obs_data_t data, const char *key, @@ -609,13 +701,13 @@ static struct obs_data_item *get_item(struct obs_data *data, const char *name) static void set_item_data(struct obs_data *data, struct obs_data_item **item, const char *name, const void *ptr, size_t size, enum obs_data_type type, - bool default_data) + bool default_data, bool autoselect_data) { obs_data_item_t new_item = NULL; if ((!item || (item && !*item)) && data) { new_item = obs_data_item_create(name, ptr, size, type, - default_data); + default_data, autoselect_data); new_item->next = data->first_item; new_item->parent = data; @@ -623,6 +715,8 @@ static void set_item_data(struct obs_data *data, struct obs_data_item **item, } else if (default_data) { obs_data_item_set_default_data(item, ptr, size, type); + } else if (autoselect_data) { + obs_data_item_set_autoselect_data(item, ptr, size, type); } else { obs_data_item_setdata(item, ptr, size, type); } @@ -642,7 +736,7 @@ static inline void set_item(struct obs_data *data, obs_data_item_t *item, item = &actual_item; } - set_item_data(data, item, name, ptr, size, type, false); + set_item_data(data, item, name, ptr, size, type, false, false); } static inline void set_item_def(struct obs_data *data, obs_data_item_t *item, @@ -662,7 +756,24 @@ static inline void set_item_def(struct obs_data *data, obs_data_item_t *item, if (item && *item && (*item)->type == type) return; - set_item_data(data, item, name, ptr, size, type, true); + set_item_data(data, item, name, ptr, size, type, true, false); +} + +static inline void set_item_auto(struct obs_data *data, obs_data_item_t *item, + const char *name, + const void *ptr, size_t size, enum obs_data_type type) +{ + obs_data_item_t actual_item = NULL; + + if (!data && !item) + return; + + if (!item) { + actual_item = get_item(data, name); + item = &actual_item; + } + + set_item_data(data, item, name, ptr, size, type, false, true); } static inline void copy_item(struct obs_data *data, struct obs_data_item *item) @@ -809,6 +920,41 @@ void obs_data_set_default_obj(obs_data_t data, const char *name, obs_data_t obj) obs_set_obj(data, NULL, name, obj, set_item_def); } +void obs_data_set_autoselect_string(obs_data_t data, const char *name, + const char *val) +{ + obs_set_string(data, NULL, name, val, set_item_auto); +} + +void obs_data_set_autoselect_int(obs_data_t data, const char *name, + long long val) +{ + obs_set_int(data, NULL, name, val, set_item_auto); +} + +void obs_data_set_autoselect_double(obs_data_t data, const char *name, + double val) +{ + obs_set_double(data, NULL, name, val, set_item_auto); +} + +void obs_data_set_autoselect_bool(obs_data_t data, const char *name, bool val) +{ + obs_set_bool(data, NULL, name, val, set_item_auto); +} + +void obs_data_set_autoselect_obj(obs_data_t data, const char *name, + obs_data_t obj) +{ + obs_set_obj(data, NULL, name, obj, set_item_auto); +} + +void obs_data_set_autoselect_array(obs_data_t data, const char *name, + obs_data_array_t arr) +{ + obs_set_array(data, NULL, name, arr, set_item_auto); +} + const char *obs_data_getstring(obs_data_t data, const char *name) { return obs_data_item_getstring(get_item(data, name)); @@ -869,6 +1015,37 @@ obs_data_array_t obs_data_get_default_array(obs_data_t data, const char *name) return obs_data_item_get_default_array(get_item(data, name)); } +const char *obs_data_get_autoselect_string(obs_data_t data, const char *name) +{ + return obs_data_item_get_autoselect_string(get_item(data, name)); +} + +long long obs_data_get_autoselect_int(obs_data_t data, const char *name) +{ + return obs_data_item_get_autoselect_int(get_item(data, name)); +} + +double obs_data_get_autoselect_double(obs_data_t data, const char *name) +{ + return obs_data_item_get_autoselect_double(get_item(data, name)); +} + +bool obs_data_getautoselect_bool(obs_data_t data, const char *name) +{ + return obs_data_item_get_autoselect_bool(get_item(data, name)); +} + +obs_data_t obs_data_get_autoselect_obj(obs_data_t data, const char *name) +{ + return obs_data_item_get_autoselect_obj(get_item(data, name)); +} + +obs_data_array_t obs_data_get_autoselect_array(obs_data_t data, + const char *name) +{ + return obs_data_item_get_autoselect_array(get_item(data, name)); +} + obs_data_array_t obs_data_array_create() { struct obs_data_array *array = bzalloc(sizeof(struct obs_data_array)); @@ -960,6 +1137,11 @@ bool obs_data_has_default(obs_data_t data, const char *name) return data && obs_data_item_has_default(get_item(data, name)); } +bool obs_data_has_autoselect(obs_data_t data, const char *name) +{ + return data && obs_data_item_has_autoselect(get_item(data, name)); +} + bool obs_data_item_has_user_value(obs_data_item_t item) { return item && item->data_size; @@ -970,6 +1152,11 @@ bool obs_data_item_has_default(obs_data_item_t item) return item && item->default_size; } +bool obs_data_item_has_autoselect(obs_data_item_t item) +{ + return item && item->autoselect_size; +} + /* ------------------------------------------------------------------------- */ /* Clearing data values */ @@ -983,6 +1170,11 @@ void obs_data_unset_default_value(obs_data_t data, const char *name) obs_data_item_unset_default_value(get_item(data, name)); } +void obs_data_unset_autoselect_value(obs_data_t data, const char *name) +{ + obs_data_item_unset_autoselect_value(get_item(data, name)); +} + void obs_data_item_unset_user_value(obs_data_item_t item) { if (!item || !item->data_size) @@ -994,10 +1186,10 @@ void obs_data_item_unset_user_value(obs_data_item_t item) item->data_size = 0; item->data_len = 0; - if (item->default_size) + if (item->default_size || item->autoselect_size) move_data(item, old_non_user_data, item, get_default_data_ptr(item), - item->default_len); + item->default_len + item->autoselect_size); } void obs_data_item_unset_default_value(obs_data_item_t item) @@ -1005,9 +1197,25 @@ void obs_data_item_unset_default_value(obs_data_item_t item) if (!item || !item->default_size) return; + void *old_autoselect_data = get_autoselect_data_ptr(item); + item_default_data_release(item); item->default_size = 0; + item->default_len = 0; + if (item->autoselect_size) + move_data(item, old_autoselect_data, item, + get_autoselect_data_ptr(item), + item->autoselect_size); +} + +void obs_data_item_unset_autoselect_value(obs_data_item_t item) +{ + if (!item || !item->autoselect_size) + return; + + item_autoselect_data_release(item); + item->autoselect_size = 0; } /* ------------------------------------------------------------------------- */ @@ -1147,6 +1355,37 @@ void obs_data_item_set_default_array(obs_data_item_t *item, obs_set_array(NULL, item, NULL, val, set_item_def); } +void obs_data_item_set_autoselect_string(obs_data_item_t *item, const char *val) +{ + obs_set_string(NULL, item, NULL, val, set_item_auto); +} + +void obs_data_item_set_autoselect_int(obs_data_item_t *item, long long val) +{ + obs_set_int(NULL, item, NULL, val, set_item_auto); +} + +void obs_data_item_set_autoselect_double(obs_data_item_t *item, double val) +{ + obs_set_double(NULL, item, NULL, val, set_item_auto); +} + +void obs_data_item_set_autoselect_bool(obs_data_item_t *item, bool val) +{ + obs_set_bool(NULL, item, NULL, val, set_item_auto); +} + +void obs_data_item_set_autoselect_obj(obs_data_item_t *item, obs_data_t val) +{ + obs_set_obj(NULL, item, NULL, val, set_item_auto); +} + +void obs_data_item_set_autoselect_array(obs_data_item_t *item, + obs_data_array_t val) +{ + obs_set_array(NULL, item, NULL, val, set_item_auto); +} + static inline bool item_valid(struct obs_data_item *item, enum obs_data_type type) { @@ -1292,6 +1531,36 @@ obs_data_array_t obs_data_item_get_default_array(obs_data_item_t item) return data_item_get_array(item, get_item_array); } +const char *obs_data_item_get_autoselect_string(obs_data_item_t item) +{ + return data_item_get_string(item, get_item_autoselect_data); +} + +long long obs_data_item_get_autoselect_int(obs_data_item_t item) +{ + return data_item_get_int(item, get_item_autoselect_data); +} + +double obs_data_item_get_autoselect_double(obs_data_item_t item) +{ + return data_item_get_double(item, get_item_autoselect_data); +} + +bool obs_data_item_get_autoselect_bool(obs_data_item_t item) +{ + return data_item_get_bool(item, get_item_autoselect_data); +} + +obs_data_t obs_data_item_get_autoselect_obj(obs_data_item_t item) +{ + return data_item_get_obj(item, get_item_autoselect_obj); +} + +obs_data_array_t obs_data_item_get_autoselect_array(obs_data_item_t item) +{ + return data_item_get_array(item, get_item_autoselect_array); +} + /* ------------------------------------------------------------------------- */ /* Helper functions for certain structures */ @@ -1390,6 +1659,30 @@ void obs_data_set_default_quat(obs_data_t data, const char *name, set_quat(data, name, val, obs_data_set_default_obj); } +void obs_data_set_autoselect_vec2(obs_data_t data, const char *name, + const struct vec2 *val) +{ + set_vec2(data, name, val, obs_data_set_autoselect_obj); +} + +void obs_data_set_autoselect_vec3(obs_data_t data, const char *name, + const struct vec3 *val) +{ + set_vec3(data, name, val, obs_data_set_autoselect_obj); +} + +void obs_data_set_autoselect_vec4(obs_data_t data, const char *name, + const struct vec4 *val) +{ + set_vec4(data, name, val, obs_data_set_autoselect_obj); +} + +void obs_data_set_autoselect_quat(obs_data_t data, const char *name, + const struct quat *val) +{ + set_quat(data, name, val, obs_data_set_autoselect_obj); +} + static inline void get_vec2(obs_data_t obj, struct vec2 *val) { if (!obj) return; @@ -1474,3 +1767,27 @@ void obs_data_get_default_quat(obs_data_t data, const char *name, { get_quat(obs_data_get_default_obj(data, name), val); } + +void obs_data_get_autoselect_vec2(obs_data_t data, const char *name, + struct vec2 *val) +{ + get_vec2(obs_data_get_autoselect_obj(data, name), val); +} + +void obs_data_get_autoselect_vec3(obs_data_t data, const char *name, + struct vec3 *val) +{ + get_vec3(obs_data_get_autoselect_obj(data, name), val); +} + +void obs_data_get_autoselect_vec4(obs_data_t data, const char *name, + struct vec4 *val) +{ + get_vec4(obs_data_get_autoselect_obj(data, name), val); +} + +void obs_data_get_autoselect_quat(obs_data_t data, const char *name, + struct quat *val) +{ + get_quat(obs_data_get_autoselect_obj(data, name), val); +} diff --git a/libobs/obs-data.h b/libobs/obs-data.h index 0e48f6616..5bb27f425 100644 --- a/libobs/obs-data.h +++ b/libobs/obs-data.h @@ -96,6 +96,22 @@ EXPORT void obs_data_set_default_bool(obs_data_t data, const char *name, EXPORT void obs_data_set_default_obj(obs_data_t data, const char *name, obs_data_t obj); +/* + * Application overrides + * Use these to communicate the actual values of settings in case the user + * settings aren't appropriate + */ +EXPORT void obs_data_set_autoselect_string(obs_data_t data, const char *name, + const char *val); +EXPORT void obs_data_set_autoselect_int(obs_data_t data, const char *name, + long long val); +EXPORT void obs_data_set_autoselect_double(obs_data_t data, const char *name, + double val); +EXPORT void obs_data_set_autoselect_bool(obs_data_t data, const char *name, + bool val); +EXPORT void obs_data_set_autoselect_obj(obs_data_t data, const char *name, + obs_data_t obj); + /* * Get functions */ @@ -115,6 +131,16 @@ EXPORT obs_data_t obs_data_get_default_obj(obs_data_t data, const char *name); EXPORT obs_data_array_t obs_data_get_default_array(obs_data_t data, const char *name); +EXPORT const char *obs_data_get_autoselect_string(obs_data_t data, + const char *name); +EXPORT long long obs_data_get_autoselect_int(obs_data_t data, const char *name); +EXPORT double obs_data_get_autoselect_double(obs_data_t data, const char *name); +EXPORT bool obs_data_get_autoselect_bool(obs_data_t data, const char *name); +EXPORT obs_data_t obs_data_get_autoselect_obj(obs_data_t data, + const char *name); +EXPORT obs_data_array_t obs_data_get_autoselect_array(obs_data_t data, + const char *name); + /* Array functions */ EXPORT obs_data_array_t obs_data_array_create(); EXPORT void obs_data_array_addref(obs_data_array_t array); @@ -132,18 +158,22 @@ EXPORT void obs_data_array_erase(obs_data_array_t array, size_t idx); EXPORT bool obs_data_has_user_value(obs_data_t data, const char *name); EXPORT bool obs_data_has_default(obs_data_t data, const char *name); +EXPORT bool obs_data_has_autoselect(obs_data_t data, const char *name); EXPORT bool obs_data_item_has_user_value(obs_data_item_t data); EXPORT bool obs_data_item_has_default(obs_data_item_t data); +EXPORT bool obs_data_item_has_autoselect(obs_data_item_t data); /* ------------------------------------------------------------------------- */ /* Clearing data values */ EXPORT void obs_data_unset_user_value(obs_data_t data, const char *name); EXPORT void obs_data_unset_default_value(obs_data_t data, const char *name); +EXPORT void obs_data_unset_autoselect_value(obs_data_t data, const char *name); EXPORT void obs_data_item_unset_user_value(obs_data_item_t data); EXPORT void obs_data_item_unset_default_value(obs_data_item_t data); +EXPORT void obs_data_item_unset_autoselect_value(obs_data_item_t data); /* ------------------------------------------------------------------------- */ /* Item iteration */ @@ -176,6 +206,18 @@ EXPORT void obs_data_item_set_default_obj(obs_data_item_t *item, EXPORT void obs_data_item_set_default_array(obs_data_item_t *item, obs_data_array_t val); +EXPORT void obs_data_item_set_autoselect_string(obs_data_item_t *item, + const char *val); +EXPORT void obs_data_item_set_autoselect_int(obs_data_item_t *item, + long long val); +EXPORT void obs_data_item_set_autoselect_double(obs_data_item_t *item, + double val); +EXPORT void obs_data_item_set_autoselect_bool(obs_data_item_t *item, bool val); +EXPORT void obs_data_item_set_autoselect_obj(obs_data_item_t *item, + obs_data_t val); +EXPORT void obs_data_item_set_autoselect_array(obs_data_item_t *item, + obs_data_array_t val); + /* Item get functions */ EXPORT const char *obs_data_item_getstring(obs_data_item_t item); EXPORT long long obs_data_item_getint(obs_data_item_t item); @@ -191,6 +233,14 @@ EXPORT bool obs_data_item_get_default_bool(obs_data_item_t item); EXPORT obs_data_t obs_data_item_get_default_obj(obs_data_item_t item); EXPORT obs_data_array_t obs_data_item_get_default_array(obs_data_item_t item); +EXPORT const char *obs_data_item_get_autoselect_string(obs_data_item_t item); +EXPORT long long obs_data_item_get_autoselect_int(obs_data_item_t item); +EXPORT double obs_data_item_get_autoselect_double(obs_data_item_t item); +EXPORT bool obs_data_item_get_autoselect_bool(obs_data_item_t item); +EXPORT obs_data_t obs_data_item_get_autoselect_obj(obs_data_item_t item); +EXPORT obs_data_array_t obs_data_item_get_autoselect_array( + obs_data_item_t item); + /* ------------------------------------------------------------------------- */ /* Helper functions for certain structures */ EXPORT void obs_data_set_vec2(obs_data_t data, const char *name, @@ -211,6 +261,15 @@ EXPORT void obs_data_set_default_vec4(obs_data_t data, const char *name, EXPORT void obs_data_set_default_quat(obs_data_t data, const char *name, const struct quat *val); +EXPORT void obs_data_set_autoselect_vec2(obs_data_t data, const char *name, + const struct vec2 *val); +EXPORT void obs_data_set_autoselect_vec3(obs_data_t data, const char *name, + const struct vec3 *val); +EXPORT void obs_data_set_autoselect_vec4(obs_data_t data, const char *name, + const struct vec4 *val); +EXPORT void obs_data_set_autoselect_quat(obs_data_t data, const char *name, + const struct quat *val); + EXPORT void obs_data_get_vec2(obs_data_t data, const char *name, struct vec2 *val); EXPORT void obs_data_get_vec3(obs_data_t data, const char *name, @@ -229,6 +288,15 @@ EXPORT void obs_data_get_default_vec4(obs_data_t data, const char *name, EXPORT void obs_data_get_default_quat(obs_data_t data, const char *name, struct quat *val); +EXPORT void obs_data_get_autoselect_vec2(obs_data_t data, const char *name, + struct vec2 *val); +EXPORT void obs_data_get_autoselect_vec3(obs_data_t data, const char *name, + struct vec3 *val); +EXPORT void obs_data_get_autoselect_vec4(obs_data_t data, const char *name, + struct vec4 *val); +EXPORT void obs_data_get_autoselect_quat(obs_data_t data, const char *name, + struct quat *val); + /* ------------------------------------------------------------------------- */ /* OBS-specific functions */