Commit 91b03897 authored by David Schleef's avatar David Schleef
Browse files

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
parent b940244e
......@@ -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,
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment