mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
Merge branch 'master' into 0.11
This commit is contained in:
commit
30a7fd7b4d
8 changed files with 207 additions and 66 deletions
|
@ -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
|
||||
|
|
126
gst/gstcaps.c
126
gst/gstcaps.c
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue