Merge branch 'master' into 0.11

This commit is contained in:
Sebastian Dröge 2011-05-27 13:58:26 +02:00
commit 30a7fd7b4d
8 changed files with 207 additions and 66 deletions

View file

@ -358,6 +358,7 @@ gst_caps_is_equal
gst_caps_is_equal_fixed
gst_caps_is_always_compatible
gst_caps_is_subset
gst_caps_is_subset_structure
gst_caps_can_intersect
gst_caps_intersect
gst_caps_intersect_full
@ -2240,6 +2241,7 @@ gst_structure_n_fields
gst_structure_has_field
gst_structure_has_field_typed
gst_structure_is_equal
gst_structure_is_subset
gst_structure_can_intersect
gst_structure_intersect
gst_structure_id_has_field

View file

@ -464,66 +464,6 @@ gst_caps_steal_structure (GstCaps * caps, guint index)
return gst_caps_remove_and_get_structure (caps, index);
}
static gboolean
gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
gpointer user_data)
{
GstStructure *subtract_from = user_data;
GValue subtraction = { 0, };
const GValue *other;
if (!(other = gst_structure_id_get_value (subtract_from, field_id)))
/* field is missing in one set */
return FALSE;
/* equal values are subset */
if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
return TRUE;
/*
* 1 - [1,2] = empty
* -> !subset
*
* [1,2] - 1 = 2
* -> 1 - [1,2] = empty
* -> subset
*
* [1,3] - [1,2] = 3
* -> [1,2] - [1,3] = empty
* -> subset
*
* {1,2} - {1,3} = 2
* -> {1,3} - {1,2} = 3
* -> !subset
*
* First caps subtraction needs to return a non-empty set, second
* subtractions needs to give en empty set.
*/
if (gst_value_subtract (&subtraction, other, value)) {
g_value_unset (&subtraction);
/* !empty result, swapping must be empty */
if (!gst_value_subtract (&subtraction, value, other))
return TRUE;
g_value_unset (&subtraction);
}
return FALSE;
}
static gboolean
gst_caps_structure_is_subset (const GstStructure * minuend,
const GstStructure * subtrahend)
{
if ((minuend->name != subtrahend->name)
|| (gst_structure_n_fields (minuend) !=
gst_structure_n_fields (subtrahend))) {
return FALSE;
}
return gst_structure_foreach ((GstStructure *) subtrahend,
gst_caps_structure_is_subset_field, (gpointer) minuend);
}
/**
* gst_caps_append:
* @caps1: the #GstCaps that will be appended to
@ -675,7 +615,7 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
for (i = caps->structs->len - 1; i >= 0; i--) {
structure1 = gst_caps_get_structure_unchecked (caps, i);
/* if structure is a subset of structure1, then skip it */
if (gst_caps_structure_is_subset (structure1, structure)) {
if (gst_structure_is_subset (structure, structure1)) {
unique = FALSE;
break;
}
@ -1014,8 +954,9 @@ gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
gboolean
gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
{
GstCaps *caps;
gboolean ret;
GstStructure *s1, *s2;
gboolean ret = TRUE;
gint i, j;
g_return_val_if_fail (subset != NULL, FALSE);
g_return_val_if_fail (superset != NULL, FALSE);
@ -1025,12 +966,65 @@ gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
return FALSE;
caps = gst_caps_subtract (subset, superset);
ret = CAPS_IS_EMPTY_SIMPLE (caps);
gst_caps_unref (caps);
for (i = subset->structs->len - 1; i >= 0; i--) {
for (j = superset->structs->len - 1; j >= 0; j--) {
s1 = gst_caps_get_structure_unchecked (subset, i);
s2 = gst_caps_get_structure_unchecked (superset, j);
if (gst_structure_is_subset (s1, s2)) {
/* If we found a superset, continue with the next
* subset structure */
break;
}
}
/* If we found no superset for this subset structure
* we return FALSE immediately */
if (j == -1) {
ret = FALSE;
break;
}
}
return ret;
}
/**
* gst_caps_is_subset_structure:
* @caps: a #GstCaps
* @structure: a potential #GstStructure subset of @caps
*
* Checks if @structure is a subset of @caps. See gst_caps_is_subset()
* for more information.
*
* Returns: %TRUE if @structure is a subset of @caps
*
* Since: 0.10.35
*/
gboolean
gst_caps_is_subset_structure (const GstCaps * caps,
const GstStructure * structure)
{
GstStructure *s;
gint i;
g_return_val_if_fail (caps != NULL, FALSE);
g_return_val_if_fail (structure != NULL, FALSE);
if (CAPS_IS_ANY (caps))
return TRUE;
if (CAPS_IS_EMPTY (caps))
return FALSE;
for (i = caps->structs->len - 1; i >= 0; i--) {
s = gst_caps_get_structure_unchecked (caps, i);
if (gst_structure_is_subset (structure, s)) {
/* If we found a superset return TRUE */
return TRUE;
}
}
return FALSE;
}
/**
* gst_caps_is_equal:
* @caps1: a #GstCaps

View file

@ -338,6 +338,8 @@ gboolean gst_caps_is_always_compatible (const GstCaps *caps1,
const GstCaps *caps2);
gboolean gst_caps_is_subset (const GstCaps *subset,
const GstCaps *superset);
gboolean gst_caps_is_subset_structure (const GstCaps *caps,
const GstStructure *structure);
gboolean gst_caps_is_equal (const GstCaps *caps1,
const GstCaps *caps2);
gboolean gst_caps_is_equal_fixed (const GstCaps *caps1,

View file

@ -3122,3 +3122,74 @@ gst_structure_can_intersect (const GstStructure * struct1,
return TRUE;
}
static gboolean
gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
gpointer user_data)
{
GstStructure *superset = user_data;
GValue subtraction = { 0, };
const GValue *other;
if (!(other = gst_structure_id_get_value (superset, field_id)))
/* field is missing in the superset => is subset */
return TRUE;
/* equal values are subset */
if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
return TRUE;
/*
* 1 - [1,2] = empty
* -> !subset
*
* [1,2] - 1 = 2
* -> 1 - [1,2] = empty
* -> subset
*
* [1,3] - [1,2] = 3
* -> [1,2] - [1,3] = empty
* -> subset
*
* {1,2} - {1,3} = 2
* -> {1,3} - {1,2} = 3
* -> !subset
*
* First caps subtraction needs to return a non-empty set, second
* subtractions needs to give en empty set.
*/
if (gst_value_subtract (&subtraction, other, value)) {
g_value_unset (&subtraction);
/* !empty result, swapping must be empty */
if (!gst_value_subtract (&subtraction, value, other))
return TRUE;
g_value_unset (&subtraction);
}
return FALSE;
}
/**
* gst_structure_is_subset:
* @subset: a #GstStructure
* @superset: a potentially greater #GstStructure
*
* Checks if @subset is a subset of @superset, i.e. has the same
* structure name and for all fields that are existing in @superset,
* @subset has a value that is a subset of the value in @superset.
*
* Returns: %TRUE if @subset is a subset of @superset
*
* Since: 0.10.35
*/
gboolean
gst_structure_is_subset (const GstStructure * subset,
const GstStructure * superset)
{
if ((superset->name != subset->name) ||
(gst_structure_n_fields (superset) > gst_structure_n_fields (subset)))
return FALSE;
return gst_structure_foreach ((GstStructure *) subset,
gst_caps_structure_is_subset_field, (gpointer) superset);
}

View file

@ -245,6 +245,8 @@ gboolean gst_structure_fixate_field_nearest_fraction (GstStructu
gboolean gst_structure_is_equal(const GstStructure *structure1,
const GstStructure *structure2);
gboolean gst_structure_is_subset(const GstStructure *subset,
const GstStructure *superset);
gboolean gst_structure_can_intersect(const GstStructure *struct1,
const GstStructure *struct2);
GstStructure* gst_structure_intersect (const GstStructure *struct1,

View file

@ -1984,6 +1984,7 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
GstBaseSrcClass *bclass;
GstFormat format;
gint64 stop;
gboolean updated = FALSE;
bclass = GST_BASE_SRC_GET_CLASS (src);
@ -2039,10 +2040,33 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
/* keep track of current position and update duration.
* segment is in bytes, we checked that above. */
GST_OBJECT_LOCK (src);
updated = (src->segment.duration != size);
src->segment.duration = size;
src->segment.position = offset;
GST_OBJECT_UNLOCK (src);
/* If we updated the duration and doing forward playback, we
* have to update the downstream segments to update the stop
* position */
if (updated && src->segment.rate >= 0.0) {
gint64 stop;
GstEvent *event;
/* for deriving a stop position for the playback segment from the seek
* segment, we must take the duration when the stop is not set */
if ((stop = src->segment.stop) == -1)
stop = src->segment.duration;
GST_DEBUG_OBJECT (src, "Sending update newsegment from %" G_GINT64_FORMAT
" to %" G_GINT64_FORMAT, src->segment.start, stop);
event =
gst_event_new_new_segment_full (TRUE,
src->segment.rate, src->segment.applied_rate, src->segment.format,
src->segment.start, stop, src->segment.time);
gst_pad_push_event (src->srcpad, event);
}
return TRUE;
/* ERRORS */

View file

@ -327,6 +327,29 @@ GST_START_TEST (test_truncate)
GST_END_TEST;
GST_START_TEST (test_subset)
{
GstCaps *c1, *c2;
c1 = gst_caps_from_string ("video/x-raw-yuv; video/x-raw-rgb");
c2 = gst_caps_from_string ("video/x-raw-yuv, format=(fourcc)YUY2");
fail_unless (gst_caps_is_subset (c2, c1));
fail_if (gst_caps_is_subset (c1, c2));
gst_caps_unref (c1);
gst_caps_unref (c2);
c1 = gst_caps_from_string
("audio/x-raw-int, channels=(int)[ 1, 2 ], rate=(int)44100");
c2 = gst_caps_from_string
("audio/x-raw-int, channels=(int)1, rate=(int)44100");
fail_unless (gst_caps_is_subset (c2, c1));
fail_if (gst_caps_is_subset (c1, c2));
gst_caps_unref (c1);
gst_caps_unref (c2);
}
GST_END_TEST;
GST_START_TEST (test_merge_fundamental)
{
GstCaps *c1, *c2;
@ -552,6 +575,26 @@ GST_START_TEST (test_merge_subset)
fail_unless (gst_caps_is_subset (test, c2));
gst_caps_unref (test);
gst_caps_unref (c2);
c2 = gst_caps_from_string ("audio/x-raw-int");
c1 = gst_caps_from_string ("audio/x-raw-int,channels=1");
gst_caps_merge (c2, c1);
GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
fail_unless (gst_caps_get_size (c2) == 1, NULL);
test = gst_caps_from_string ("audio/x-raw-int");
fail_unless (gst_caps_is_equal (c2, test));
gst_caps_unref (c2);
gst_caps_unref (test);
c2 = gst_caps_from_string ("audio/x-raw-int,channels=1");
c1 = gst_caps_from_string ("audio/x-raw-int");
gst_caps_merge (c2, c1);
GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
fail_unless (gst_caps_get_size (c2) == 2, NULL);
test = gst_caps_from_string ("audio/x-raw-int,channels=1; audio/x-raw-int");
fail_unless (gst_caps_is_equal (c2, test));
gst_caps_unref (c2);
gst_caps_unref (test);
}
GST_END_TEST;
@ -909,6 +952,7 @@ gst_caps_suite (void)
tcase_add_test (tc_chain, test_static_caps);
tcase_add_test (tc_chain, test_simplify);
tcase_add_test (tc_chain, test_truncate);
tcase_add_test (tc_chain, test_subset);
tcase_add_test (tc_chain, test_merge_fundamental);
tcase_add_test (tc_chain, test_merge_same);
tcase_add_test (tc_chain, test_merge_subset);

View file

@ -177,6 +177,7 @@ EXPORTS
gst_caps_is_equal_fixed
gst_caps_is_fixed
gst_caps_is_subset
gst_caps_is_subset_structure
gst_caps_make_writable
gst_caps_merge
gst_caps_merge_structure
@ -1005,6 +1006,7 @@ EXPORTS
gst_structure_id_take_value
gst_structure_intersect
gst_structure_is_equal
gst_structure_is_subset
gst_structure_map_in_place
gst_structure_n_fields
gst_structure_new