gst/parse/: Add delayed set-property. This allows to set properties on dynamicaly created objects (pads in videomxer).

Original commit message from CVS:
* gst/parse/grammar.tab.pre.c:
* gst/parse/grammar.tab.pre.h:
* gst/parse/grammar.y:
* gst/parse/lex._gst_parse_yy.pre.c:
Add delayed set-property. This allows to set properties on dynamicaly
created objects (pads in videomxer).
This commit is contained in:
Stefan Kost 2008-02-01 12:10:17 +00:00
parent c595a566d9
commit a9b5a4d56c
5 changed files with 199 additions and 82 deletions

View file

@ -1,3 +1,12 @@
2008-02-01 Stefan Kost <ensonic@users.sf.net>
* gst/parse/grammar.tab.pre.c:
* gst/parse/grammar.tab.pre.h:
* gst/parse/grammar.y:
* gst/parse/lex._gst_parse_yy.pre.c:
Add delayed set-property. This allows to set properties on dynamicaly
created objects (pads in videomxer).
2008-02-01 Thijs Vermeir <thijsvermeir@gmail.com>
* gst/gstutils.c:

View file

@ -218,6 +218,14 @@ typedef struct
* but there is no such signal */
} DelayedLink;
typedef struct
{
GstElement *parent;
gchar *name;
gchar *value_str;
gulong signal_id;
} DelayedSet;
/*** define SET_ERROR and ERROR macros/functions */
#ifdef G_HAVE_ISO_VARARGS
@ -376,13 +384,48 @@ G_STMT_START { \
MAKE_LINK (link, NULL, _src, pads, NULL, NULL, NULL); \
} G_STMT_END
static void
gst_parse_new_child (GstChildProxy * child_proxy, GObject * object,
gpointer data)
{
DelayedSet *set = (DelayedSet *) data;
GParamSpec *pspec;
GValue v = { 0, };
GstObject *target = NULL;
GType value_type;
if (gst_child_proxy_lookup (GST_OBJECT (set->parent), set->name, &target,
&pspec)) {
value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
GST_CAT_LOG (GST_CAT_PIPELINE,
"parsing delayed property %s as a %s from %s", pspec->name,
g_type_name (value_type), set->value_str);
g_value_init (&v, value_type);
if (gst_value_deserialize (&v, set->value_str)) {
g_object_set_property (G_OBJECT (target), pspec->name, &v);
}
g_signal_handler_disconnect (child_proxy, set->signal_id);
g_free (set->name);
g_free (set->value_str);
g_free (set);
}
if (G_IS_VALUE (&v))
g_value_unset (&v);
if (target)
gst_object_unref (target);
return;
}
static void
gst_parse_element_set (gchar * value, GstElement * element, graph_t * graph)
{
GParamSpec *pspec;
gchar *pos = value;
GValue v = { 0, };
GstObject *target;
GstObject *target = NULL;
GType value_type;
/* parse the string, so the property name is null-terminated an pos points
@ -414,21 +457,33 @@ gst_parse_element_set (gchar * value, GstElement * element, graph_t * graph)
if (!gst_value_deserialize (&v, pos))
goto error;
g_object_set_property (G_OBJECT (target), pspec->name, &v);
gst_object_unref (target);
} else {
/* do a delayed set */
if (GST_IS_CHILD_PROXY (element)) {
DelayedSet *data = g_new (DelayedSet, 1);
data->parent = element;
data->name = g_strdup (value);
data->value_str = g_strdup (pos);
data->signal_id =
g_signal_connect (GST_OBJECT (element), "child-added",
G_CALLBACK (gst_parse_new_child), data);
} else {
SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY,
_("no property \"%s\" in element \"%s\""), value,
GST_ELEMENT_NAME (element));
}
}
out:
gst_parse_strfree (value);
if (G_IS_VALUE (&v))
g_value_unset (&v);
if (target)
gst_object_unref (target);
return;
error:
gst_object_unref (target);
SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY,
_("could not set property \"%s\" in element \"%s\" to \"%s\""),
value, GST_ELEMENT_NAME (element), pos);
@ -608,7 +663,7 @@ static int yyerror (void *scanner, graph_t * graph, const char *s);
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 471 "./grammar.y"
#line 521 "./grammar.y"
{
gchar *s;
chain_t *c;
@ -618,7 +673,7 @@ typedef union YYSTYPE
graph_t *g;
}
/* Line 187 of yacc.c. */
#line 601 "grammar.tab.c"
#line 651 "grammar.tab.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -632,7 +687,7 @@ YYSTYPE;
/* Line 216 of yacc.c. */
#line 614 "grammar.tab.c"
#line 664 "grammar.tab.c"
#ifdef short
# undef short
@ -921,10 +976,10 @@ static const yytype_int8 yyrhs[] = {
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] = {
0, 506, 506, 514, 518, 519, 521, 522, 525, 528,
533, 534, 538, 539, 542, 543, 546, 547, 548, 551,
564, 565, 566, 569, 574, 575, 610, 638, 639, 653,
673, 698, 701
0, 556, 556, 564, 568, 569, 571, 572, 575, 578,
583, 584, 588, 589, 592, 593, 596, 597, 598, 601,
614, 615, 616, 619, 624, 625, 660, 688, 689, 703,
723, 748, 751
};
#endif
@ -1867,7 +1922,7 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn) {
case 2:
#line 506 "./grammar.y"
#line 556 "./grammar.y"
{
(yyval.e) = gst_element_factory_make ((yyvsp[(1) - (1)].s), NULL);
if ((yyval.e) == NULL) {
@ -1882,7 +1937,7 @@ yyreduce:
break;
case 3:
#line 514 "./grammar.y"
#line 564 "./grammar.y"
{
gst_parse_element_set ((yyvsp[(2) - (2)].s), (yyvsp[(1) - (2)].e), graph);
(yyval.e) = (yyvsp[(1) - (2)].e);
@ -1891,21 +1946,21 @@ yyreduce:
break;
case 4:
#line 518 "./grammar.y"
#line 568 "./grammar.y"
{
(yyval.p) = NULL;;
}
break;
case 5:
#line 519 "./grammar.y"
#line 569 "./grammar.y"
{
(yyval.p) = g_slist_prepend ((yyvsp[(1) - (2)].p), (yyvsp[(2) - (2)].s));;
}
break;
case 6:
#line 521 "./grammar.y"
#line 571 "./grammar.y"
{
GST_BIN_MAKE ((yyval.c), "bin", (yyvsp[(3) - (4)].c),
(yyvsp[(2) - (4)].p), FALSE);;
@ -1913,7 +1968,7 @@ yyreduce:
break;
case 7:
#line 522 "./grammar.y"
#line 572 "./grammar.y"
{
GST_BIN_MAKE ((yyval.c), (yyvsp[(1) - (4)].s), (yyvsp[(3) - (4)].c),
(yyvsp[(2) - (4)].p), TRUE);
@ -1923,7 +1978,7 @@ yyreduce:
break;
case 8:
#line 525 "./grammar.y"
#line 575 "./grammar.y"
{
GST_BIN_MAKE ((yyval.c), (yyvsp[(1) - (3)].s), NULL, (yyvsp[(2) - (3)].p),
TRUE);
@ -1933,7 +1988,7 @@ yyreduce:
break;
case 9:
#line 528 "./grammar.y"
#line 578 "./grammar.y"
{
GST_BIN_MAKE ((yyval.c), (yyvsp[(1) - (4)].s), NULL, (yyvsp[(2) - (4)].p),
TRUE);
@ -1943,14 +1998,14 @@ yyreduce:
break;
case 10:
#line 533 "./grammar.y"
#line 583 "./grammar.y"
{
(yyval.p) = g_slist_prepend (NULL, (yyvsp[(1) - (1)].s));;
}
break;
case 11:
#line 534 "./grammar.y"
#line 584 "./grammar.y"
{
(yyval.p) = (yyvsp[(2) - (2)].p);
(yyval.p) = g_slist_prepend ((yyval.p), (yyvsp[(1) - (2)].s));
@ -1959,56 +2014,56 @@ yyreduce:
break;
case 12:
#line 538 "./grammar.y"
#line 588 "./grammar.y"
{
(yyval.p) = g_slist_prepend (NULL, (yyvsp[(2) - (2)].s));;
}
break;
case 13:
#line 539 "./grammar.y"
#line 589 "./grammar.y"
{
(yyval.p) = g_slist_prepend ((yyvsp[(3) - (3)].p), (yyvsp[(2) - (3)].s));;
}
break;
case 14:
#line 542 "./grammar.y"
#line 592 "./grammar.y"
{
MAKE_REF ((yyval.l), (yyvsp[(1) - (1)].s), NULL);;
}
break;
case 15:
#line 543 "./grammar.y"
#line 593 "./grammar.y"
{
MAKE_REF ((yyval.l), (yyvsp[(1) - (2)].s), (yyvsp[(2) - (2)].p));;
}
break;
case 16:
#line 546 "./grammar.y"
#line 596 "./grammar.y"
{
(yyval.l) = (yyvsp[(1) - (1)].l);;
}
break;
case 17:
#line 547 "./grammar.y"
#line 597 "./grammar.y"
{
MAKE_REF ((yyval.l), NULL, (yyvsp[(1) - (1)].p));;
}
break;
case 18:
#line 548 "./grammar.y"
#line 598 "./grammar.y"
{
MAKE_REF ((yyval.l), NULL, NULL);;
}
break;
case 19:
#line 551 "./grammar.y"
#line 601 "./grammar.y"
{
(yyval.l) = (yyvsp[(1) - (3)].l);
if ((yyvsp[(2) - (3)].s)) {
@ -2026,28 +2081,28 @@ yyreduce:
break;
case 20:
#line 564 "./grammar.y"
#line 614 "./grammar.y"
{
(yyval.p) = g_slist_prepend (NULL, (yyvsp[(1) - (1)].l));;
}
break;
case 21:
#line 565 "./grammar.y"
#line 615 "./grammar.y"
{
(yyval.p) = g_slist_prepend ((yyvsp[(2) - (2)].p), (yyvsp[(1) - (2)].l));;
}
break;
case 22:
#line 566 "./grammar.y"
#line 616 "./grammar.y"
{
(yyval.p) = (yyvsp[(1) - (2)].p);;
}
break;
case 23:
#line 569 "./grammar.y"
#line 619 "./grammar.y"
{
(yyval.c) = gst_parse_chain_new ();
(yyval.c)->first = (yyval.c)->last = (yyvsp[(1) - (1)].e);
@ -2058,14 +2113,14 @@ yyreduce:
break;
case 24:
#line 574 "./grammar.y"
#line 624 "./grammar.y"
{
(yyval.c) = (yyvsp[(1) - (1)].c);;
}
break;
case 25:
#line 575 "./grammar.y"
#line 625 "./grammar.y"
{
if ((yyvsp[(1) - (2)].c)->back && (yyvsp[(2) - (2)].c)->front) {
if (!(yyvsp[(1) - (2)].c)->back->sink_name) {
@ -2116,7 +2171,7 @@ yyreduce:
break;
case 26:
#line 610 "./grammar.y"
#line 660 "./grammar.y"
{
GSList *walk;
@ -2157,14 +2212,14 @@ yyreduce:
break;
case 27:
#line 638 "./grammar.y"
#line 688 "./grammar.y"
{
(yyval.c) = (yyvsp[(1) - (2)].c);;
}
break;
case 28:
#line 639 "./grammar.y"
#line 689 "./grammar.y"
{
if ((yyvsp[(2) - (2)].c)->front) {
if (!(yyvsp[(2) - (2)].c)->front->src_name) {
@ -2187,7 +2242,7 @@ yyreduce:
break;
case 29:
#line 653 "./grammar.y"
#line 703 "./grammar.y"
{
(yyval.c) = (yyvsp[(2) - (2)].c);
if ((yyval.c)->front) {
@ -2214,7 +2269,7 @@ yyreduce:
break;
case 30:
#line 673 "./grammar.y"
#line 723 "./grammar.y"
{
GstElement *element =
gst_element_make_from_uri (GST_URI_SINK, (yyvsp[(2) - (2)].s), NULL);
@ -2246,7 +2301,7 @@ yyreduce:
break;
case 31:
#line 698 "./grammar.y"
#line 748 "./grammar.y"
{
SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_EMPTY,
_("empty pipeline not allowed"));
@ -2256,7 +2311,7 @@ yyreduce:
break;
case 32:
#line 701 "./grammar.y"
#line 751 "./grammar.y"
{
(yyval.g) = (graph_t *) graph;
if ((yyvsp[(1) - (1)].c)->front) {
@ -2288,7 +2343,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
#line 2202 "grammar.tab.c"
#line 2252 "grammar.tab.c"
default:
break;
}
@ -2488,7 +2543,7 @@ yyreturn:
}
#line 724 "./grammar.y"
#line 774 "./grammar.y"

View file

@ -62,7 +62,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 471 "./grammar.y"
#line 521 "./grammar.y"
{
gchar *s;
chain_t *c;

View file

@ -107,6 +107,13 @@ typedef struct {
* but there is no such signal */
} DelayedLink;
typedef struct {
GstElement *parent;
gchar *name;
gchar *value_str;
gulong signal_id;
} DelayedSet;
/*** define SET_ERROR and ERROR macros/functions */
#ifdef G_HAVE_ISO_VARARGS
@ -265,13 +272,45 @@ G_STMT_START { \
MAKE_LINK (link, NULL, _src, pads, NULL, NULL, NULL); \
} G_STMT_END
static void gst_parse_new_child(GstChildProxy *child_proxy, GObject *object,
gpointer data)
{
DelayedSet *set = (DelayedSet *) data;
GParamSpec *pspec;
GValue v = { 0, };
GstObject *target = NULL;
GType value_type;
if (gst_child_proxy_lookup (GST_OBJECT (set->parent), set->name, &target, &pspec)) {
value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
GST_CAT_LOG (GST_CAT_PIPELINE, "parsing delayed property %s as a %s from %s", pspec->name,
g_type_name (value_type), set->value_str);
g_value_init (&v, value_type);
if (gst_value_deserialize (&v, set->value_str)) {
g_object_set_property (G_OBJECT (target), pspec->name, &v);
}
g_signal_handler_disconnect (child_proxy, set->signal_id);
g_free(set->name);
g_free(set->value_str);
g_free(set);
}
if (G_IS_VALUE (&v))
g_value_unset (&v);
if (target)
gst_object_unref (target);
return;
}
static void
gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph)
{
GParamSpec *pspec;
gchar *pos = value;
GValue v = { 0, };
GstObject *target;
GstObject *target = NULL;
GType value_type;
/* parse the string, so the property name is null-terminated an pos points
@ -300,21 +339,32 @@ gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph)
if (!gst_value_deserialize (&v, pos))
goto error;
g_object_set_property (G_OBJECT (target), pspec->name, &v);
gst_object_unref (target);
} else {
/* do a delayed set */
if (GST_IS_CHILD_PROXY (element)) {
DelayedSet *data = g_new (DelayedSet, 1);
data->parent = element;
data->name = g_strdup(value);
data->value_str = g_strdup(pos);
data->signal_id = g_signal_connect(GST_OBJECT (element),"child-added", G_CALLBACK (gst_parse_new_child), data);
}
else {
SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY, \
_("no property \"%s\" in element \"%s\""), value, \
GST_ELEMENT_NAME (element));
}
}
out:
gst_parse_strfree (value);
if (G_IS_VALUE (&v))
g_value_unset (&v);
if (target)
gst_object_unref (target);
return;
error:
gst_object_unref (target);
SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY,
_("could not set property \"%s\" in element \"%s\" to \"%s\""),
value, GST_ELEMENT_NAME (element), pos);

View file

@ -1155,7 +1155,8 @@ YY_DECL {
BEGIN (INITIAL);
return ASSIGNMENT;
}
YY_BREAK case 2:YY_RULE_SETUP
YY_BREAK case 2:
YY_RULE_SETUP
#line 81 "parse.l"
{
yytext++;
@ -1164,7 +1165,8 @@ YY_DECL {
BEGIN (INITIAL);
return PADREF;
}
YY_BREAK case 3:YY_RULE_SETUP
YY_BREAK case 3:
YY_RULE_SETUP
#line 89 "parse.l"
{
PRINT ("REF: %s", yytext);
@ -1187,7 +1189,8 @@ YY_DECL {
BEGIN (INITIAL);
return BINREF;
}
YY_BREAK case 5:YY_RULE_SETUP
YY_BREAK case 5:
YY_RULE_SETUP
#line 106 "parse.l"
{
PRINT ("IDENTIFIER: %s", yytext);
@ -1204,8 +1207,7 @@ YY_DECL {
PRINT ("LINK: %s", yytext);
c++;
if (*c)
{
if (*c) {
while (g_ascii_isspace (*c))
c++;
c = yylval->s = gst_parse_strdup (c);
@ -1215,8 +1217,7 @@ YY_DECL {
g_assert_not_reached ();
while (g_ascii_isspace (*--c));
*++c = '\0';
} else
{
} else {
yylval->s = NULL;
}
BEGIN (INITIAL);
@ -1233,7 +1234,8 @@ YY_DECL {
BEGIN (INITIAL);
return PARSE_URL;
}
YY_BREAK case 8:YY_RULE_SETUP
YY_BREAK case 8:
YY_RULE_SETUP
#line 139 "parse.l"
{
PRINT ("OPERATOR: [%s]", yytext);
@ -1246,16 +1248,17 @@ YY_DECL {
{
PRINT ("SPACE: [%s]", yytext);
}
YY_BREAK case 10:YY_RULE_SETUP
YY_BREAK case 10:
YY_RULE_SETUP
#line 143 "parse.l"
{
PRINT ("Invalid Lexer element: %s\n", yytext);
return *yytext;
}
YY_BREAK case 11:YY_RULE_SETUP
YY_BREAK case 11:
YY_RULE_SETUP
#line 148 "parse.l"
ECHO;
YY_BREAK
#line 1266 "lex._gst_parse_yy.c"
case YY_STATE_EOF (INITIAL):
@ -2437,7 +2440,7 @@ enum yytokentype
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 471 "./grammar.y"
#line 521 "./grammar.y"
{
gchar *s;
chain_t *c;