check/gst/gstvalue.c: Add a deserialisation test for fractions

Original commit message from CVS:
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
Add a deserialisation test for fractions
* examples/metadata/read-metadata.c: (message_loop),
(make_pipeline), (main):
Fix up metadata reading sample.
* gst/base/gstbasesink.c: (gst_base_sink_do_sync):
Debug format fix
* gst/base/gstbasesrc.c: (gst_base_src_default_negotiate):
Don't try and fixate empty caps
* gst/gst_private.h:
Wrap in G_BEGIN_DECLS/G_END_DECLS
* gst/gstvalue.c: (gst_value_collect_fraction),
(gst_value_set_fraction), (gst_value_get_fraction_denominator),
(gst_value_transform_string_fraction),
(gst_value_compare_fraction):
Add some extra guards to ensure that we don't end up
with an invalid denominator of 0 in a gstfraction and
that fractions always get reduced.
This commit is contained in:
Jan Schmidt 2005-11-20 17:12:49 +00:00
parent 1bd557806e
commit c05ba2d666
11 changed files with 240 additions and 212 deletions

View file

@ -1,3 +1,24 @@
2005-11-20 Jan Schmidt <thaytan@mad.scientist.com>
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
Add a deserialisation test for fractions
* examples/metadata/read-metadata.c: (message_loop),
(make_pipeline), (main):
Fix up metadata reading sample.
* gst/base/gstbasesink.c: (gst_base_sink_do_sync):
Debug format fix
* gst/base/gstbasesrc.c: (gst_base_src_default_negotiate):
Don't try and fixate empty caps
* gst/gst_private.h:
Wrap in G_BEGIN_DECLS/G_END_DECLS
* gst/gstvalue.c: (gst_value_collect_fraction),
(gst_value_set_fraction), (gst_value_get_fraction_denominator),
(gst_value_transform_string_fraction),
(gst_value_compare_fraction):
Add some extra guards to ensure that we don't end up
with an invalid denominator of 0 in a gstfraction and
that fractions always get reduced.
2005-11-20 Wim Taymans <wim@fluendo.com> 2005-11-20 Wim Taymans <wim@fluendo.com>
* docs/gst/gstreamer-sections.txt: * docs/gst/gstreamer-sections.txt:

View file

@ -61,7 +61,43 @@ GST_START_TEST (test_deserialize_gint64)
"could not deserialize %s (%d)", strings[i], i); "could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_int64 (&value) == results[i], fail_unless (g_value_get_int64 (&value) == results[i],
"resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT "resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT
", for string %s (%d)", value, results[i], strings[i], i); ", for string %s (%d)", g_value_get_int64 (&value),
results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_gstfraction)
{
GValue value = { 0 };
const char *strings[] = {
"4/5",
"-8/9"
};
gint64 result_numers[] = {
4,
-8
};
gint64 result_denoms[] = {
5,
9
};
int i;
g_value_init (&value, GST_TYPE_FRACTION);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (gst_value_get_fraction_numerator (&value) == result_numers[i],
"resulting numerator value is %d, not %d"
", for string %s (%d)", gst_value_get_fraction_numerator (&value),
result_numers[i], strings[i], i);
fail_unless (gst_value_get_fraction_denominator (&value) ==
result_denoms[i], "resulting denominator value is %d, not %d"
", for string %s (%d)", gst_value_get_fraction_denominator (&value),
result_denoms[i], strings[i], i);
} }
} }
@ -994,6 +1030,7 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_deserialize_guint); tcase_add_test (tc_chain, test_deserialize_guint);
tcase_add_test (tc_chain, test_deserialize_guint_failures); tcase_add_test (tc_chain, test_deserialize_guint_failures);
tcase_add_test (tc_chain, test_deserialize_gint64); tcase_add_test (tc_chain, test_deserialize_gint64);
tcase_add_test (tc_chain, test_deserialize_gstfraction);
tcase_add_test (tc_chain, test_string); tcase_add_test (tc_chain, test_string);
tcase_add_test (tc_chain, test_deserialize_string); tcase_add_test (tc_chain, test_deserialize_string);
tcase_add_test (tc_chain, test_value_compare); tcase_add_test (tc_chain, test_value_compare);

View file

@ -38,59 +38,38 @@ GstElement *source = NULL;
#define NEW_PIPE_PER_FILE #define NEW_PIPE_PER_FILE
static void static gboolean
message_loop (GstElement * element, GstTagList ** tags) message_loop (GstElement * element, GstTagList ** tags)
{ {
GstBus *bus; GstBus *bus;
gboolean done = FALSE; gboolean done = FALSE;
bus = gst_element_get_bus (element); bus = gst_element_get_bus (element);
g_return_if_fail (bus != NULL); g_return_val_if_fail (bus != NULL, FALSE);
g_return_if_fail (tags != NULL); g_return_val_if_fail (tags != NULL, FALSE);
while (!done) { while (!done) {
GstMessage *message; GstMessage *message;
GstMessageType revent;
revent = gst_bus_poll (bus, GST_MESSAGE_ANY, -1); message = gst_bus_poll (bus, GST_MESSAGE_ANY, 0);
if (revent == GST_MESSAGE_UNKNOWN) {
/* Messages ended */
gst_object_unref (bus);
return;
}
message = gst_bus_pop (bus);
if (message == NULL) if (message == NULL)
continue; /* All messages read, we're done */
break;
switch (GST_MESSAGE_TYPE (message)) { switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
case GST_MESSAGE_ERROR: case GST_MESSAGE_ERROR:
done = TRUE; case GST_MESSAGE_EOS:
break; gst_message_unref (message);
return TRUE;
case GST_MESSAGE_TAG: case GST_MESSAGE_TAG:
{ {
GstTagList *new_tags; GstTagList *new_tags;
gst_message_parse_tag (message, &new_tags); gst_message_parse_tag (message, &new_tags);
if (tags) { if (*tags)
if (*tags) *tags = gst_tag_list_merge (*tags, new_tags, GST_TAG_MERGE_KEEP_ALL);
*tags = else
gst_tag_list_merge (*tags, new_tags, GST_TAG_MERGE_KEEP_ALL); *tags = new_tags;
else
*tags = new_tags;
} else {
GST_WARNING ("Failed to extract tags list from message");
}
break;
}
case GST_MESSAGE_APPLICATION:
{
const GstStructure *s = gst_message_get_structure (message);
/* Application specific message used to mark end point */
if (strcmp (gst_structure_get_name (s), "gst-metadata-mark") == 0)
done = TRUE;
break; break;
} }
default: default:
@ -99,43 +78,26 @@ message_loop (GstElement * element, GstTagList ** tags)
gst_message_unref (message); gst_message_unref (message);
} }
gst_object_unref (bus); gst_object_unref (bus);
} return TRUE;
void
have_pad_handler (GstElement * decodebin, GstPad * pad, gboolean last,
GstElement * sink)
{
GST_DEBUG ("New pad %" GST_PTR_FORMAT " - attempting link", pad);
gst_pad_link (pad, gst_element_get_pad (sink, "sink"));
} }
static void static void
make_pipeline () make_pipeline ()
{ {
GstElement *decodebin, *fakesink; GstElement *decodebin;
if (pipeline != NULL) if (pipeline != NULL)
gst_object_unref (pipeline); gst_object_unref (pipeline);
pipeline = gst_pipeline_new (NULL); pipeline = gst_pipeline_new (NULL);
g_object_set (G_OBJECT (pipeline), "play-timeout",
(GstClockTime) 5 * GST_SECOND, NULL);
source = gst_element_factory_make ("filesrc", "source"); source = gst_element_factory_make ("filesrc", "source");
g_assert (GST_IS_ELEMENT (source)); g_assert (GST_IS_ELEMENT (source));
decodebin = gst_element_factory_make ("decodebin", "decodebin"); decodebin = gst_element_factory_make ("decodebin", "decodebin");
g_assert (GST_IS_ELEMENT (decodebin)); g_assert (GST_IS_ELEMENT (decodebin));
fakesink = gst_element_factory_make ("fakesink", "fakesink");
g_assert (GST_IS_ELEMENT (fakesink));
gst_bin_add_many (GST_BIN (pipeline), source, decodebin, fakesink, NULL); gst_bin_add_many (GST_BIN (pipeline), source, decodebin, NULL);
gst_element_link (source, decodebin); gst_element_link (source, decodebin);
/* Listen for pads from decodebin */
g_signal_connect (G_OBJECT (decodebin), "new-decoded-pad",
G_CALLBACK (have_pad_handler), fakesink);
} }
static void static void
@ -184,6 +146,7 @@ main (int argc, char *argv[])
while (i < argc) { while (i < argc) {
GstStateChangeReturn sret; GstStateChangeReturn sret;
GstState state; GstState state;
GstTagList *tags = NULL;
filename = argv[i]; filename = argv[i];
g_object_set (source, "location", filename, NULL); g_object_set (source, "location", filename, NULL);
@ -195,47 +158,42 @@ main (int argc, char *argv[])
sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED); sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
if (GST_STATE_CHANGE_ASYNC == sret) { if (GST_STATE_CHANGE_ASYNC == sret) {
if (GST_STATE_CHANGE_FAILURE == if (GST_STATE_CHANGE_SUCCESS !=
gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, NULL)) { gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
g_print ("State change failed. Aborting"); 5 * GST_SECOND)) {
g_print ("State change failed for %s. Aborting\n", filename);
break; break;
} }
} else if (sret != GST_STATE_CHANGE_SUCCESS) { } else if (sret != GST_STATE_CHANGE_SUCCESS) {
g_print ("%s - Could not read file\n", argv[i]); g_print ("%s - Could not read file\n", filename);
} else { goto next_file;
GstTagList *tags = NULL;
GstBus *bus;
/* Send message on the bus to mark end point of preroll. */
bus = gst_element_get_bus (GST_ELEMENT (pipeline));
if (bus) {
gst_bus_post (bus,
gst_message_new_application (NULL,
gst_structure_new ("gst-metadata-mark", NULL)));
gst_object_unref (bus);
}
message_loop (GST_ELEMENT (pipeline), &tags);
if (tags) {
g_print ("Metadata for %s:\n", argv[i]);
gst_tag_list_foreach (tags, print_tag, NULL);
gst_tag_list_free (tags);
tags = NULL;
} else
g_print ("No metadata found for %s\n", argv[i]);
sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
if (GST_STATE_CHANGE_ASYNC == sret) {
if (GST_STATE_CHANGE_FAILURE ==
gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, NULL))
{
g_print ("State change failed. Aborting");
break;
}
}
} }
if (!message_loop (GST_ELEMENT (pipeline), &tags)) {
g_print ("Failed in message reading for %s\n", argv[i]);
}
if (tags) {
g_print ("Metadata for %s:\n", argv[i]);
gst_tag_list_foreach (tags, print_tag, NULL);
gst_tag_list_free (tags);
tags = NULL;
} else
g_print ("No metadata found for %s\n", argv[i]);
sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
#ifndef NEW_PIPE_PER_FILE
if (GST_STATE_CHANGE_ASYNC == sret) {
if (GST_STATE_CHANGE_FAILURE ==
gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
GST_CLOCK_TIME_NONE)) {
g_print ("State change failed. Aborting");
break;
}
}
#endif
next_file:
i++; i++;
#ifdef NEW_PIPE_PER_FILE #ifdef NEW_PIPE_PER_FILE

View file

@ -1085,7 +1085,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
GST_LOG_OBJECT (basesink, GST_LOG_OBJECT (basesink,
"waiting for clock, base time %" GST_TIME_FORMAT "waiting for clock, base time %" GST_TIME_FORMAT
"stream_start %" GST_TIME_FORMAT, " stream_start %" GST_TIME_FORMAT,
GST_TIME_ARGS (base_time), GST_TIME_ARGS (stream_start)); GST_TIME_ARGS (base_time), GST_TIME_ARGS (stream_start));
/* also save end_time of this buffer so that we can wait /* also save end_time of this buffer so that we can wait

View file

@ -1204,19 +1204,21 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
gst_caps_truncate (caps); gst_caps_truncate (caps);
/* now fixate */ /* now fixate */
gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps); if (!gst_caps_is_empty (caps)) {
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps); gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
if (gst_caps_is_any (caps)) { if (gst_caps_is_any (caps)) {
/* hmm, still anything, so element can do anything and /* hmm, still anything, so element can do anything and
* nego is not needed */ * nego is not needed */
gst_caps_unref (caps); gst_caps_unref (caps);
result = TRUE; result = TRUE;
} else if (gst_caps_is_fixed (caps)) { } else if (gst_caps_is_fixed (caps)) {
/* yay, fixed caps, use those then */ /* yay, fixed caps, use those then */
gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps); gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
gst_caps_unref (caps); gst_caps_unref (caps);
result = TRUE; result = TRUE;
}
} }
} }
return result; return result;

View file

@ -37,6 +37,8 @@ extern const char *g_log_domain_gstreamer;
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
G_BEGIN_DECLS
gboolean __gst_in_valgrind (void); gboolean __gst_in_valgrind (void);
/*** debugging categories *****************************************************/ /*** debugging categories *****************************************************/
@ -108,4 +110,5 @@ extern GstDebugCategory *GST_CAT_REGISTRY;
#endif #endif
G_END_DECLS
#endif /* __GST_PRIVATE_H__ */ #endif /* __GST_PRIVATE_H__ */

View file

@ -2734,8 +2734,8 @@ static gchar *
gst_value_collect_fraction (GValue * value, guint n_collect_values, gst_value_collect_fraction (GValue * value, guint n_collect_values,
GTypeCValue * collect_values, guint collect_flags) GTypeCValue * collect_values, guint collect_flags)
{ {
value->data[0].v_int = collect_values[0].v_int; gst_value_set_fraction (value,
value->data[1].v_int = collect_values[1].v_int; collect_values[0].v_int, collect_values[1].v_int);
return NULL; return NULL;
} }
@ -2792,6 +2792,9 @@ gst_value_set_fraction (GValue * value, gint numerator, gint denominator)
numerator /= gcd; numerator /= gcd;
denominator /= gcd; denominator /= gcd;
} }
g_assert (denominator > 0);
value->data[0].v_int = numerator; value->data[0].v_int = numerator;
value->data[1].v_int = denominator; value->data[1].v_int = denominator;
} }
@ -2823,7 +2826,7 @@ gst_value_get_fraction_numerator (const GValue * value)
int int
gst_value_get_fraction_denominator (const GValue * value) gst_value_get_fraction_denominator (const GValue * value)
{ {
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (value), 0); g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (value), 1);
return value->data[1].v_int; return value->data[1].v_int;
} }
@ -2913,7 +2916,11 @@ static void
gst_value_transform_string_fraction (const GValue * src_value, gst_value_transform_string_fraction (const GValue * src_value,
GValue * dest_value) GValue * dest_value)
{ {
gst_value_deserialize_fraction (dest_value, src_value->data[0].v_pointer); if (!gst_value_deserialize_fraction (dest_value,
src_value->data[0].v_pointer))
/* If the deserialize fails, ensure we leave the fraction in a
* valid, if incorrect, state */
gst_value_set_fraction (dest_value, 0, 1);
} }
#define MAX_TERMS 30 #define MAX_TERMS 30
@ -3031,6 +3038,9 @@ gst_value_compare_fraction (const GValue * value1, const GValue * value2)
if (new_num_1 > new_num_2) if (new_num_1 > new_num_2)
return GST_VALUE_GREATER_THAN; return GST_VALUE_GREATER_THAN;
/* new_num_1 == new_num_2 implies that both denominators must have
* been 0, beause otherwise simplification would have caught the
* equivalence */
g_assert_not_reached (); g_assert_not_reached ();
return GST_VALUE_UNORDERED; return GST_VALUE_UNORDERED;
} }

View file

@ -1085,7 +1085,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
GST_LOG_OBJECT (basesink, GST_LOG_OBJECT (basesink,
"waiting for clock, base time %" GST_TIME_FORMAT "waiting for clock, base time %" GST_TIME_FORMAT
"stream_start %" GST_TIME_FORMAT, " stream_start %" GST_TIME_FORMAT,
GST_TIME_ARGS (base_time), GST_TIME_ARGS (stream_start)); GST_TIME_ARGS (base_time), GST_TIME_ARGS (stream_start));
/* also save end_time of this buffer so that we can wait /* also save end_time of this buffer so that we can wait

View file

@ -1204,19 +1204,21 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
gst_caps_truncate (caps); gst_caps_truncate (caps);
/* now fixate */ /* now fixate */
gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps); if (!gst_caps_is_empty (caps)) {
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps); gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
if (gst_caps_is_any (caps)) { if (gst_caps_is_any (caps)) {
/* hmm, still anything, so element can do anything and /* hmm, still anything, so element can do anything and
* nego is not needed */ * nego is not needed */
gst_caps_unref (caps); gst_caps_unref (caps);
result = TRUE; result = TRUE;
} else if (gst_caps_is_fixed (caps)) { } else if (gst_caps_is_fixed (caps)) {
/* yay, fixed caps, use those then */ /* yay, fixed caps, use those then */
gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps); gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
gst_caps_unref (caps); gst_caps_unref (caps);
result = TRUE; result = TRUE;
}
} }
} }
return result; return result;

View file

@ -61,7 +61,43 @@ GST_START_TEST (test_deserialize_gint64)
"could not deserialize %s (%d)", strings[i], i); "could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_int64 (&value) == results[i], fail_unless (g_value_get_int64 (&value) == results[i],
"resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT "resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT
", for string %s (%d)", value, results[i], strings[i], i); ", for string %s (%d)", g_value_get_int64 (&value),
results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_gstfraction)
{
GValue value = { 0 };
const char *strings[] = {
"4/5",
"-8/9"
};
gint64 result_numers[] = {
4,
-8
};
gint64 result_denoms[] = {
5,
9
};
int i;
g_value_init (&value, GST_TYPE_FRACTION);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (gst_value_get_fraction_numerator (&value) == result_numers[i],
"resulting numerator value is %d, not %d"
", for string %s (%d)", gst_value_get_fraction_numerator (&value),
result_numers[i], strings[i], i);
fail_unless (gst_value_get_fraction_denominator (&value) ==
result_denoms[i], "resulting denominator value is %d, not %d"
", for string %s (%d)", gst_value_get_fraction_denominator (&value),
result_denoms[i], strings[i], i);
} }
} }
@ -994,6 +1030,7 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_deserialize_guint); tcase_add_test (tc_chain, test_deserialize_guint);
tcase_add_test (tc_chain, test_deserialize_guint_failures); tcase_add_test (tc_chain, test_deserialize_guint_failures);
tcase_add_test (tc_chain, test_deserialize_gint64); tcase_add_test (tc_chain, test_deserialize_gint64);
tcase_add_test (tc_chain, test_deserialize_gstfraction);
tcase_add_test (tc_chain, test_string); tcase_add_test (tc_chain, test_string);
tcase_add_test (tc_chain, test_deserialize_string); tcase_add_test (tc_chain, test_deserialize_string);
tcase_add_test (tc_chain, test_value_compare); tcase_add_test (tc_chain, test_value_compare);

View file

@ -38,59 +38,38 @@ GstElement *source = NULL;
#define NEW_PIPE_PER_FILE #define NEW_PIPE_PER_FILE
static void static gboolean
message_loop (GstElement * element, GstTagList ** tags) message_loop (GstElement * element, GstTagList ** tags)
{ {
GstBus *bus; GstBus *bus;
gboolean done = FALSE; gboolean done = FALSE;
bus = gst_element_get_bus (element); bus = gst_element_get_bus (element);
g_return_if_fail (bus != NULL); g_return_val_if_fail (bus != NULL, FALSE);
g_return_if_fail (tags != NULL); g_return_val_if_fail (tags != NULL, FALSE);
while (!done) { while (!done) {
GstMessage *message; GstMessage *message;
GstMessageType revent;
revent = gst_bus_poll (bus, GST_MESSAGE_ANY, -1); message = gst_bus_poll (bus, GST_MESSAGE_ANY, 0);
if (revent == GST_MESSAGE_UNKNOWN) {
/* Messages ended */
gst_object_unref (bus);
return;
}
message = gst_bus_pop (bus);
if (message == NULL) if (message == NULL)
continue; /* All messages read, we're done */
break;
switch (GST_MESSAGE_TYPE (message)) { switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
case GST_MESSAGE_ERROR: case GST_MESSAGE_ERROR:
done = TRUE; case GST_MESSAGE_EOS:
break; gst_message_unref (message);
return TRUE;
case GST_MESSAGE_TAG: case GST_MESSAGE_TAG:
{ {
GstTagList *new_tags; GstTagList *new_tags;
gst_message_parse_tag (message, &new_tags); gst_message_parse_tag (message, &new_tags);
if (tags) { if (*tags)
if (*tags) *tags = gst_tag_list_merge (*tags, new_tags, GST_TAG_MERGE_KEEP_ALL);
*tags = else
gst_tag_list_merge (*tags, new_tags, GST_TAG_MERGE_KEEP_ALL); *tags = new_tags;
else
*tags = new_tags;
} else {
GST_WARNING ("Failed to extract tags list from message");
}
break;
}
case GST_MESSAGE_APPLICATION:
{
const GstStructure *s = gst_message_get_structure (message);
/* Application specific message used to mark end point */
if (strcmp (gst_structure_get_name (s), "gst-metadata-mark") == 0)
done = TRUE;
break; break;
} }
default: default:
@ -99,43 +78,26 @@ message_loop (GstElement * element, GstTagList ** tags)
gst_message_unref (message); gst_message_unref (message);
} }
gst_object_unref (bus); gst_object_unref (bus);
} return TRUE;
void
have_pad_handler (GstElement * decodebin, GstPad * pad, gboolean last,
GstElement * sink)
{
GST_DEBUG ("New pad %" GST_PTR_FORMAT " - attempting link", pad);
gst_pad_link (pad, gst_element_get_pad (sink, "sink"));
} }
static void static void
make_pipeline () make_pipeline ()
{ {
GstElement *decodebin, *fakesink; GstElement *decodebin;
if (pipeline != NULL) if (pipeline != NULL)
gst_object_unref (pipeline); gst_object_unref (pipeline);
pipeline = gst_pipeline_new (NULL); pipeline = gst_pipeline_new (NULL);
g_object_set (G_OBJECT (pipeline), "play-timeout",
(GstClockTime) 5 * GST_SECOND, NULL);
source = gst_element_factory_make ("filesrc", "source"); source = gst_element_factory_make ("filesrc", "source");
g_assert (GST_IS_ELEMENT (source)); g_assert (GST_IS_ELEMENT (source));
decodebin = gst_element_factory_make ("decodebin", "decodebin"); decodebin = gst_element_factory_make ("decodebin", "decodebin");
g_assert (GST_IS_ELEMENT (decodebin)); g_assert (GST_IS_ELEMENT (decodebin));
fakesink = gst_element_factory_make ("fakesink", "fakesink");
g_assert (GST_IS_ELEMENT (fakesink));
gst_bin_add_many (GST_BIN (pipeline), source, decodebin, fakesink, NULL); gst_bin_add_many (GST_BIN (pipeline), source, decodebin, NULL);
gst_element_link (source, decodebin); gst_element_link (source, decodebin);
/* Listen for pads from decodebin */
g_signal_connect (G_OBJECT (decodebin), "new-decoded-pad",
G_CALLBACK (have_pad_handler), fakesink);
} }
static void static void
@ -184,6 +146,7 @@ main (int argc, char *argv[])
while (i < argc) { while (i < argc) {
GstStateChangeReturn sret; GstStateChangeReturn sret;
GstState state; GstState state;
GstTagList *tags = NULL;
filename = argv[i]; filename = argv[i];
g_object_set (source, "location", filename, NULL); g_object_set (source, "location", filename, NULL);
@ -195,47 +158,42 @@ main (int argc, char *argv[])
sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED); sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
if (GST_STATE_CHANGE_ASYNC == sret) { if (GST_STATE_CHANGE_ASYNC == sret) {
if (GST_STATE_CHANGE_FAILURE == if (GST_STATE_CHANGE_SUCCESS !=
gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, NULL)) { gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
g_print ("State change failed. Aborting"); 5 * GST_SECOND)) {
g_print ("State change failed for %s. Aborting\n", filename);
break; break;
} }
} else if (sret != GST_STATE_CHANGE_SUCCESS) { } else if (sret != GST_STATE_CHANGE_SUCCESS) {
g_print ("%s - Could not read file\n", argv[i]); g_print ("%s - Could not read file\n", filename);
} else { goto next_file;
GstTagList *tags = NULL;
GstBus *bus;
/* Send message on the bus to mark end point of preroll. */
bus = gst_element_get_bus (GST_ELEMENT (pipeline));
if (bus) {
gst_bus_post (bus,
gst_message_new_application (NULL,
gst_structure_new ("gst-metadata-mark", NULL)));
gst_object_unref (bus);
}
message_loop (GST_ELEMENT (pipeline), &tags);
if (tags) {
g_print ("Metadata for %s:\n", argv[i]);
gst_tag_list_foreach (tags, print_tag, NULL);
gst_tag_list_free (tags);
tags = NULL;
} else
g_print ("No metadata found for %s\n", argv[i]);
sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
if (GST_STATE_CHANGE_ASYNC == sret) {
if (GST_STATE_CHANGE_FAILURE ==
gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, NULL))
{
g_print ("State change failed. Aborting");
break;
}
}
} }
if (!message_loop (GST_ELEMENT (pipeline), &tags)) {
g_print ("Failed in message reading for %s\n", argv[i]);
}
if (tags) {
g_print ("Metadata for %s:\n", argv[i]);
gst_tag_list_foreach (tags, print_tag, NULL);
gst_tag_list_free (tags);
tags = NULL;
} else
g_print ("No metadata found for %s\n", argv[i]);
sret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
#ifndef NEW_PIPE_PER_FILE
if (GST_STATE_CHANGE_ASYNC == sret) {
if (GST_STATE_CHANGE_FAILURE ==
gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
GST_CLOCK_TIME_NONE)) {
g_print ("State change failed. Aborting");
break;
}
}
#endif
next_file:
i++; i++;
#ifdef NEW_PIPE_PER_FILE #ifdef NEW_PIPE_PER_FILE