diff --git a/ChangeLog b/ChangeLog index 00c13e0542..cdeefc557e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-02-01 Stefan Kost + + * 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 * gst/gstutils.c: diff --git a/gst/parse/grammar.tab.pre.c b/gst/parse/grammar.tab.pre.c index d4bb7e7b08..b060a50227 100644 --- a/gst/parse/grammar.tab.pre.c +++ b/gst/parse/grammar.tab.pre.c @@ -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 { - SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY, - _("no property \"%s\" in element \"%s\""), value, - GST_ELEMENT_NAME (element)); + /* 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" diff --git a/gst/parse/grammar.tab.pre.h b/gst/parse/grammar.tab.pre.h index 5da6a1758e..7238f6e7a3 100644 --- a/gst/parse/grammar.tab.pre.h +++ b/gst/parse/grammar.tab.pre.h @@ -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; diff --git a/gst/parse/grammar.y b/gst/parse/grammar.y index d833b42113..b99cde8107 100644 --- a/gst/parse/grammar.y +++ b/gst/parse/grammar.y @@ -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 { - SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY, \ - _("no property \"%s\" in element \"%s\""), value, \ - GST_ELEMENT_NAME (element)); + /* 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); diff --git a/gst/parse/lex._gst_parse_yy.pre.c b/gst/parse/lex._gst_parse_yy.pre.c index 45f2343b7c..7fee3d9420 100644 --- a/gst/parse/lex._gst_parse_yy.pre.c +++ b/gst/parse/lex._gst_parse_yy.pre.c @@ -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); @@ -1172,22 +1174,23 @@ YY_DECL { BEGIN (INITIAL); return REF; } - YY_BREAK case 4: + YY_BREAK case 4: /* rule 4 can match eol */ - YY_RULE_SETUP + YY_RULE_SETUP #line 96 "parse.l" { gchar *pos = yytext; while (!g_ascii_isspace (*pos) && (*pos != '.')) - pos++; - *pos = '\0'; - PRINT ("BINREF: %s", yytext); - yylval->s = gst_parse_strdup (yytext); - BEGIN (INITIAL); - return BINREF; + pos++; + *pos = '\0'; + PRINT ("BINREF: %s", yytext); + yylval->s = gst_parse_strdup (yytext); + 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); @@ -1195,17 +1198,16 @@ YY_DECL { BEGIN (INITIAL); return IDENTIFIER; } - YY_BREAK case 6: + YY_BREAK case 6: /* rule 6 can match eol */ - YY_RULE_SETUP + YY_RULE_SETUP #line 113 "parse.l" { gchar *c = yytext; - PRINT ("LINK: %s", yytext); - c++; - if (*c) - { + PRINT ("LINK: %s", yytext); + c++; + if (*c) { while (g_ascii_isspace (*c)) c++; c = yylval->s = gst_parse_strdup (c); @@ -1215,16 +1217,15 @@ YY_DECL { g_assert_not_reached (); while (g_ascii_isspace (*--c)); *++c = '\0'; - } else - { + } else { yylval->s = NULL; } BEGIN (INITIAL); return LINK; } - YY_BREAK case 7: + YY_BREAK case 7: /* rule 7 can match eol */ - YY_RULE_SETUP + YY_RULE_SETUP #line 131 "parse.l" { PRINT ("URL: %s", yytext); @@ -1233,29 +1234,31 @@ 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); return *yytext; } - YY_BREAK case 9: + YY_BREAK case 9: /* rule 9 can match eol */ - YY_RULE_SETUP + YY_RULE_SETUP #line 141 "parse.l" { 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; - + 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;