gst/parse/: Add delayed set-property. This allows to set properties on dynamicaly...
authorStefan Kost <ensonic@users.sourceforge.net>
Fri, 1 Feb 2008 12:10:17 +0000 (12:10 +0000)
committerStefan Kost <ensonic@users.sourceforge.net>
Fri, 1 Feb 2008 12:10:17 +0000 (12:10 +0000)
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).

ChangeLog
gst/parse/grammar.tab.pre.c
gst/parse/grammar.tab.pre.h
gst/parse/grammar.y
gst/parse/lex._gst_parse_yy.pre.c

index 00c13e0..cdeefc5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
index d4bb7e7..b060a50 100644 (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
@@ -377,12 +385,47 @@ G_STMT_START { \
 } 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"
 
 
 
index 5da6a17..7238f6e 100644 (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;
index d833b42..b99cde8 100644 (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 { 
-    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); 
index 45f2343..7fee3d9 100644 (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);
@@ -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;