mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 20:42:30 +00:00
hacking. Add value_compare, value_union, and value_intersect functions
Original commit message from CVS: hacking. Add value_compare, value_union, and value_intersect functions
This commit is contained in:
parent
b940244e53
commit
91b0389731
4 changed files with 290 additions and 4 deletions
|
@ -565,6 +565,28 @@ gst_structure_n_fields(GstStructure *structure)
|
|||
return structure->fields->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_structure_field_foreach:
|
||||
* @structure: a #GstStructure
|
||||
* @func: a function to call for each field
|
||||
* @user_data: private data
|
||||
*
|
||||
* Calls the provided function once for each field in the #GstStructure.
|
||||
*/
|
||||
void
|
||||
gst_structure_field_foreach (GstStructure *structure,
|
||||
GstStructureForeachFunc func, gpointer user_data)
|
||||
{
|
||||
int i;
|
||||
GstStructureField *field;
|
||||
|
||||
for(i=0;i<structure->fields->len;i++){
|
||||
field = GST_STRUCTURE_FIELD(structure, i);
|
||||
|
||||
func (structure, field->name, &field->value, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_structure_has_field:
|
||||
* @structure: a #GstStructure
|
||||
|
|
|
@ -28,6 +28,9 @@ G_BEGIN_DECLS
|
|||
typedef struct _GstStructure GstStructure;
|
||||
typedef struct _GstStructureField GstStructureField;
|
||||
|
||||
typedef void (*GstStructureForeachFunc) (GstStructure *structure,
|
||||
GQuark field_id, GValue *value, gpointer user_data);
|
||||
|
||||
struct _GstStructure {
|
||||
int len;
|
||||
|
||||
|
@ -76,6 +79,8 @@ void gst_structure_remove_field(GstStructure *structure, const gchar *field);
|
|||
|
||||
GType gst_structure_get_field_type(GstStructure *structure,
|
||||
const gchar *field);
|
||||
void gst_structure_field_foreach (GstStructure *structure,
|
||||
GstStructureForeachFunc func, gpointer user_data);
|
||||
gint gst_structure_n_fields(GstStructure *structure);
|
||||
gboolean gst_structure_has_field(GstStructure *structure, const gchar *field);
|
||||
gboolean gst_structure_has_field_typed(GstStructure *structure,
|
||||
|
|
256
gst/gstvalue.c
256
gst/gstvalue.c
|
@ -20,15 +20,40 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gobject/gvaluecollector.h>
|
||||
|
||||
typedef struct _GstValueCompareInfo GstValueCompareInfo;
|
||||
struct _GstValueCompareInfo {
|
||||
GType type;
|
||||
GstValueCompareFunc func;
|
||||
};
|
||||
|
||||
typedef struct _GstValueUnionInfo GstValueUnionInfo;
|
||||
struct _GstValueUnionInfo {
|
||||
GType type1;
|
||||
GType type2;
|
||||
GstValueUnionFunc func;
|
||||
};
|
||||
|
||||
typedef struct _GstValueIntersectInfo GstValueIntersectInfo;
|
||||
struct _GstValueIntersectInfo {
|
||||
GType type1;
|
||||
GType type2;
|
||||
GstValueIntersectFunc func;
|
||||
};
|
||||
|
||||
GType gst_type_fourcc;
|
||||
GType gst_type_int_range;
|
||||
GType gst_type_double_range;
|
||||
|
||||
GArray *gst_value_compare_funcs;
|
||||
GArray *gst_value_union_funcs;
|
||||
GArray *gst_value_intersect_funcs;
|
||||
|
||||
|
||||
static void
|
||||
gst_value_init_fourcc (GValue *value)
|
||||
{
|
||||
|
@ -129,7 +154,7 @@ gst_value_set_int_range (GValue *value, int start, int end)
|
|||
}
|
||||
|
||||
int
|
||||
gst_value_get_int_range_start (const GValue *value)
|
||||
gst_value_get_int_range_min (const GValue *value)
|
||||
{
|
||||
g_return_val_if_fail (GST_VALUE_HOLDS_FOURCC (value), 0);
|
||||
|
||||
|
@ -137,7 +162,7 @@ gst_value_get_int_range_start (const GValue *value)
|
|||
}
|
||||
|
||||
int
|
||||
gst_value_get_int_range_end (const GValue *value)
|
||||
gst_value_get_int_range_max (const GValue *value)
|
||||
{
|
||||
g_return_val_if_fail (GST_VALUE_HOLDS_FOURCC (value), 0);
|
||||
|
||||
|
@ -160,6 +185,214 @@ gst_value_transform_int_range_string (const GValue *src_value,
|
|||
(int)src_value->data[0].v_long, (int)src_value->data[1].v_long);
|
||||
}
|
||||
|
||||
/* comparison functions */
|
||||
|
||||
static int
|
||||
gst_value_compare_int (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
return value2->data[0].v_int - value1->data[0].v_int;
|
||||
}
|
||||
|
||||
static int
|
||||
gst_value_compare_double (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
return (value2->data[0].v_double > value1->data[0].v_double) -
|
||||
(value2->data[0].v_double < value1->data[0].v_double);
|
||||
}
|
||||
|
||||
static int
|
||||
gst_value_compare_string (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
return strcmp(value1->data[0].v_pointer, value2->data[0].v_pointer);
|
||||
}
|
||||
|
||||
static int
|
||||
gst_value_compare_fourcc (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
return value2->data[0].v_int - value1->data[0].v_int;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_value_can_compare (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
GstValueCompareInfo *compare_info;
|
||||
int i;
|
||||
|
||||
if(G_VALUE_TYPE(value1) != G_VALUE_TYPE(value2))return FALSE;
|
||||
for(i=0;i<gst_value_compare_funcs->len;i++){
|
||||
compare_info = &g_array_index(gst_value_compare_funcs,
|
||||
GstValueCompareInfo, i);
|
||||
if(compare_info->type == G_VALUE_TYPE(value1)) return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
gst_value_compare (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
GstValueCompareInfo *compare_info;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail(G_VALUE_TYPE(value1) == G_VALUE_TYPE(value2), 0);
|
||||
for(i=0;i<gst_value_compare_funcs->len;i++){
|
||||
compare_info = &g_array_index(gst_value_compare_funcs,
|
||||
GstValueCompareInfo, i);
|
||||
if(compare_info->type != G_VALUE_TYPE(value1)) continue;
|
||||
|
||||
return compare_info->func(value1, value2);
|
||||
}
|
||||
|
||||
g_return_val_if_fail(0 /* type not found */, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gst_value_register_compare_func (GType type, GstValueCompareFunc func)
|
||||
{
|
||||
GstValueCompareInfo compare_info;
|
||||
|
||||
compare_info.type = type;
|
||||
compare_info.func = func;
|
||||
|
||||
g_array_append_val(gst_value_compare_funcs, compare_info);
|
||||
}
|
||||
|
||||
/* union */
|
||||
|
||||
gboolean
|
||||
gst_value_can_union (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
GstValueUnionInfo *union_info;
|
||||
int i;
|
||||
|
||||
for(i=0;i<gst_value_union_funcs->len;i++){
|
||||
union_info = &g_array_index(gst_value_union_funcs, GstValueUnionInfo, i);
|
||||
if(union_info->type1 == G_VALUE_TYPE(value1) &&
|
||||
union_info->type2 == G_VALUE_TYPE(value2)) return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_value_union (GValue *dest, const GValue *value1, const GValue *value2)
|
||||
{
|
||||
GstValueUnionInfo *union_info;
|
||||
int i;
|
||||
|
||||
for(i=0;i<gst_value_union_funcs->len;i++){
|
||||
union_info = &g_array_index(gst_value_union_funcs, GstValueUnionInfo, i);
|
||||
if(union_info->type1 == G_VALUE_TYPE(value1) &&
|
||||
union_info->type2 == G_VALUE_TYPE(value2)) {
|
||||
union_info->func(dest, value1, value2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_value_register_union_func (GType type1, GType type2, GstValueUnionFunc func)
|
||||
{
|
||||
GstValueUnionInfo union_info;
|
||||
|
||||
union_info.type1 = type1;
|
||||
union_info.type2 = type2;
|
||||
union_info.func = func;
|
||||
|
||||
g_array_append_val(gst_value_union_funcs, union_info);
|
||||
}
|
||||
|
||||
/* intersection */
|
||||
|
||||
static gboolean
|
||||
gst_value_intersect_int_int_range (GValue *dest, const GValue *src1,
|
||||
const GValue *src2)
|
||||
{
|
||||
g_return_val_if_fail(G_VALUE_TYPE(src1) == G_TYPE_INT, FALSE);
|
||||
g_return_val_if_fail(G_VALUE_TYPE(src2) == GST_TYPE_INT_RANGE, FALSE);
|
||||
|
||||
if (src2->data[0].v_long <= src1->data[0].v_int &&
|
||||
src2->data[1].v_long >= src1->data[0].v_int){
|
||||
g_value_copy(src1, dest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_value_intersect_int_range_int_range (GValue *dest, const GValue *src1,
|
||||
const GValue *src2)
|
||||
{
|
||||
int min;
|
||||
int max;
|
||||
|
||||
g_return_val_if_fail(G_VALUE_TYPE(src1) == GST_TYPE_INT_RANGE, FALSE);
|
||||
g_return_val_if_fail(G_VALUE_TYPE(src2) == GST_TYPE_INT_RANGE, FALSE);
|
||||
|
||||
min = MAX(src1->data[0].v_long, src2->data[0].v_long);
|
||||
max = MIN(src1->data[1].v_long, src2->data[1].v_long);
|
||||
|
||||
if(min < max){
|
||||
g_value_init(dest, GST_TYPE_INT_RANGE);
|
||||
gst_value_set_int_range(dest, min, max);
|
||||
return TRUE;
|
||||
}
|
||||
if(min == max){
|
||||
g_value_init(dest, G_TYPE_INT);
|
||||
g_value_set_int(dest, min);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_value_can_intersect (const GValue *value1, const GValue *value2)
|
||||
{
|
||||
GstValueIntersectInfo *intersect_info;
|
||||
int i;
|
||||
|
||||
for(i=0;i<gst_value_intersect_funcs->len;i++){
|
||||
intersect_info = &g_array_index(gst_value_intersect_funcs,
|
||||
GstValueIntersectInfo, i);
|
||||
if(intersect_info->type1 == G_VALUE_TYPE(value1) &&
|
||||
intersect_info->type2 == G_VALUE_TYPE(value2)) return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_value_intersect (GValue *dest, const GValue *value1, const GValue *value2)
|
||||
{
|
||||
GstValueIntersectInfo *intersect_info;
|
||||
int i;
|
||||
|
||||
for(i=0;i<gst_value_intersect_funcs->len;i++){
|
||||
intersect_info = &g_array_index(gst_value_intersect_funcs,
|
||||
GstValueIntersectInfo, i);
|
||||
if(intersect_info->type1 == G_VALUE_TYPE(value1) &&
|
||||
intersect_info->type2 == G_VALUE_TYPE(value2)) {
|
||||
intersect_info->func(dest, value1, value2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_value_register_intersect_func (GType type1, GType type2,
|
||||
GstValueIntersectFunc func)
|
||||
{
|
||||
GstValueIntersectInfo intersect_info;
|
||||
|
||||
intersect_info.type1 = type1;
|
||||
intersect_info.type2 = type2;
|
||||
intersect_info.func = func;
|
||||
|
||||
g_array_append_val(gst_value_intersect_funcs, intersect_info);
|
||||
}
|
||||
|
||||
void
|
||||
_gst_value_initialize (void)
|
||||
|
@ -212,6 +445,25 @@ _gst_value_initialize (void)
|
|||
gst_value_transform_fourcc_string);
|
||||
g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
|
||||
gst_value_transform_int_range_string);
|
||||
|
||||
gst_value_compare_funcs = g_array_new(FALSE, FALSE,
|
||||
sizeof(GstValueCompareInfo));
|
||||
|
||||
gst_value_register_compare_func (G_TYPE_INT, gst_value_compare_int);
|
||||
gst_value_register_compare_func (G_TYPE_DOUBLE, gst_value_compare_double);
|
||||
gst_value_register_compare_func (G_TYPE_STRING, gst_value_compare_string);
|
||||
gst_value_register_compare_func (GST_TYPE_FOURCC, gst_value_compare_fourcc);
|
||||
|
||||
gst_value_union_funcs = g_array_new(FALSE, FALSE,
|
||||
sizeof(GstValueUnionInfo));
|
||||
|
||||
gst_value_intersect_funcs = g_array_new(FALSE, FALSE,
|
||||
sizeof(GstValueIntersectInfo));
|
||||
|
||||
gst_value_register_intersect_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
|
||||
gst_value_intersect_int_int_range);
|
||||
gst_value_register_intersect_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
|
||||
gst_value_intersect_int_range_int_range);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef int (* GstValueCompareFunc) (const GValue *value1,
|
||||
const GValue *value2);
|
||||
typedef int (* GstValueUnionFunc) (GValue *dest, const GValue *value1,
|
||||
const GValue *value2);
|
||||
typedef int (* GstValueIntersectFunc) (GValue *dest, const GValue *value1,
|
||||
const GValue *value2);
|
||||
|
||||
#define GST_VALUE_HOLDS_FOURCC(x) TRUE
|
||||
|
||||
#define GST_TYPE_FOURCC gst_type_fourcc
|
||||
|
@ -38,8 +45,8 @@ void gst_value_set_fourcc (GValue *value, guint32 fourcc);
|
|||
guint32 gst_value_get_fourcc (const GValue *value);
|
||||
|
||||
void gst_value_set_int_range (GValue *value, int start, int end);
|
||||
int gst_value_get_int_range_start (const GValue *value);
|
||||
int gst_value_get_int_range_end (const GValue *value);
|
||||
int gst_value_get_int_range_min (const GValue *value);
|
||||
int gst_value_get_int_range_max (const GValue *value);
|
||||
|
||||
void gst_value_set_double_range (GValue *value, double start, double end);
|
||||
double gst_value_get_double_range_start (const GValue *value);
|
||||
|
|
Loading…
Reference in a new issue