mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +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;
|
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:
|
* gst_structure_has_field:
|
||||||
* @structure: a #GstStructure
|
* @structure: a #GstStructure
|
||||||
|
|
|
@ -28,6 +28,9 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstStructure GstStructure;
|
typedef struct _GstStructure GstStructure;
|
||||||
typedef struct _GstStructureField GstStructureField;
|
typedef struct _GstStructureField GstStructureField;
|
||||||
|
|
||||||
|
typedef void (*GstStructureForeachFunc) (GstStructure *structure,
|
||||||
|
GQuark field_id, GValue *value, gpointer user_data);
|
||||||
|
|
||||||
struct _GstStructure {
|
struct _GstStructure {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
@ -76,6 +79,8 @@ void gst_structure_remove_field(GstStructure *structure, const gchar *field);
|
||||||
|
|
||||||
GType gst_structure_get_field_type(GstStructure *structure,
|
GType gst_structure_get_field_type(GstStructure *structure,
|
||||||
const gchar *field);
|
const gchar *field);
|
||||||
|
void gst_structure_field_foreach (GstStructure *structure,
|
||||||
|
GstStructureForeachFunc func, gpointer user_data);
|
||||||
gint gst_structure_n_fields(GstStructure *structure);
|
gint gst_structure_n_fields(GstStructure *structure);
|
||||||
gboolean gst_structure_has_field(GstStructure *structure, const gchar *field);
|
gboolean gst_structure_has_field(GstStructure *structure, const gchar *field);
|
||||||
gboolean gst_structure_has_field_typed(GstStructure *structure,
|
gboolean gst_structure_has_field_typed(GstStructure *structure,
|
||||||
|
|
256
gst/gstvalue.c
256
gst/gstvalue.c
|
@ -20,15 +20,40 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gobject/gvaluecollector.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_fourcc;
|
||||||
GType gst_type_int_range;
|
GType gst_type_int_range;
|
||||||
GType gst_type_double_range;
|
GType gst_type_double_range;
|
||||||
|
|
||||||
|
GArray *gst_value_compare_funcs;
|
||||||
|
GArray *gst_value_union_funcs;
|
||||||
|
GArray *gst_value_intersect_funcs;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_value_init_fourcc (GValue *value)
|
gst_value_init_fourcc (GValue *value)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +154,7 @@ gst_value_set_int_range (GValue *value, int start, int end)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
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
|
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);
|
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);
|
(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
|
void
|
||||||
_gst_value_initialize (void)
|
_gst_value_initialize (void)
|
||||||
|
@ -212,6 +445,25 @@ _gst_value_initialize (void)
|
||||||
gst_value_transform_fourcc_string);
|
gst_value_transform_fourcc_string);
|
||||||
g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
|
g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
|
||||||
gst_value_transform_int_range_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
|
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_VALUE_HOLDS_FOURCC(x) TRUE
|
||||||
|
|
||||||
#define GST_TYPE_FOURCC gst_type_fourcc
|
#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);
|
guint32 gst_value_get_fourcc (const GValue *value);
|
||||||
|
|
||||||
void gst_value_set_int_range (GValue *value, int start, int end);
|
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_min (const GValue *value);
|
||||||
int gst_value_get_int_range_end (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);
|
void gst_value_set_double_range (GValue *value, double start, double end);
|
||||||
double gst_value_get_double_range_start (const GValue *value);
|
double gst_value_get_double_range_start (const GValue *value);
|
||||||
|
|
Loading…
Reference in a new issue