s/ffmpegcolorspace/videoconvert/ in a few places
[platform/upstream/gstreamer.git] / pwg-building-args.md
1 ---
2 title: Adding Properties
3 ...
4
5 # Adding Properties
6
7 The primary and most important way of controlling how an element
8 behaves, is through GObject properties. GObject properties are defined
9 in the `_class_init ()` function. The element optionally implements a
10 `_get_property ()` and a `_set_property ()` function. These functions
11 will be notified if an application changes or requests the value of a
12 property, and can then fill in the value or take action required for
13 that property to change value internally.
14
15 You probably also want to keep an instance variable around with the
16 currently configured value of the property that you use in the get and
17 set functions. Note that `GObject` will not automatically set your
18 instance variable to the default value, you will have to do that in the
19 `_init ()` function of your element.
20
21 ``` c
22
23 /* properties */
24 enum {
25   PROP_0,
26   PROP_SILENT
27   /* FILL ME */
28 };
29
30 static void gst_my_filter_set_property  (GObject      *object,
31                          guint         prop_id,
32                          const GValue *value,
33                          GParamSpec   *pspec);
34 static void gst_my_filter_get_property  (GObject      *object,
35                          guint         prop_id,
36                          GValue       *value,
37                          GParamSpec   *pspec);
38
39 static void
40 gst_my_filter_class_init (GstMyFilterClass *klass)
41 {
42   GObjectClass *object_class = G_OBJECT_CLASS (klass);
43
44   /* define virtual function pointers */
45   object_class->set_property = gst_my_filter_set_property;
46   object_class->get_property = gst_my_filter_get_property;
47
48   /* define properties */
49   g_object_class_install_property (object_class, PROP_SILENT,
50     g_param_spec_boolean ("silent", "Silent",
51               "Whether to be very verbose or not",
52               FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
53 }
54
55 static void
56 gst_my_filter_set_property (GObject      *object,
57                 guint         prop_id,
58                 const GValue *value,
59                 GParamSpec   *pspec)
60 {
61   GstMyFilter *filter = GST_MY_FILTER (object);
62
63   switch (prop_id) {
64     case PROP_SILENT:
65       filter->silent = g_value_get_boolean (value);
66       g_print ("Silent argument was changed to %s\n",
67            filter->silent ? "true" : "false");
68       break;
69     default:
70       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
71       break;
72   }
73 }
74
75 static void
76 gst_my_filter_get_property (GObject    *object,
77                 guint       prop_id,
78                 GValue     *value,
79                 GParamSpec *pspec)
80 {
81   GstMyFilter *filter = GST_MY_FILTER (object);
82                                                                                 
83   switch (prop_id) {
84     case PROP_SILENT:
85       g_value_set_boolean (value, filter->silent);
86       break;
87     default:
88       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
89       break;
90   }
91 }
92 ```
93
94 The above is a very simple example of how properties are used. Graphical
95 applications will use these properties and will display a
96 user-controllable widget with which these properties can be changed.
97 This means that - for the property to be as user-friendly as possible -
98 you should be as exact as possible in the definition of the property.
99 Not only in defining ranges in between which valid properties can be
100 located (for integers, floats, etc.), but also in using very descriptive
101 (better yet: internationalized) strings in the definition of the
102 property, and if possible using enums and flags instead of integers. The
103 GObject documentation describes these in a very complete way, but below,
104 we'll give a short example of where this is useful. Note that using
105 integers here would probably completely confuse the user, because they
106 make no sense in this context. The example is stolen from videotestsrc.
107
108 ``` c
109 typedef enum {
110   GST_VIDEOTESTSRC_SMPTE,
111   GST_VIDEOTESTSRC_SNOW,
112   GST_VIDEOTESTSRC_BLACK
113 } GstVideotestsrcPattern;
114
115 [..]
116
117 #define GST_TYPE_VIDEOTESTSRC_PATTERN (gst_videotestsrc_pattern_get_type ())
118 static GType
119 gst_videotestsrc_pattern_get_type (void)
120 {
121   static GType videotestsrc_pattern_type = 0;
122
123   if (!videotestsrc_pattern_type) {
124     static GEnumValue pattern_types[] = {
125       { GST_VIDEOTESTSRC_SMPTE, "SMPTE 100% color bars",    "smpte" },
126       { GST_VIDEOTESTSRC_SNOW,  "Random (television snow)", "snow"  },
127       { GST_VIDEOTESTSRC_BLACK, "0% Black",                 "black" },
128       { 0, NULL, NULL },
129     };
130
131     videotestsrc_pattern_type =
132     g_enum_register_static ("GstVideotestsrcPattern",
133                 pattern_types);
134   }
135
136   return videotestsrc_pattern_type;
137 }
138
139 [..]
140
141 static void
142 gst_videotestsrc_class_init (GstvideotestsrcClass *klass)
143 {
144 [..]
145   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATTERN,
146     g_param_spec_enum ("pattern", "Pattern",
147                "Type of test pattern to generate",
148                        GST_TYPE_VIDEOTESTSRC_PATTERN, GST_VIDEOTESTSRC_SMPTE,
149                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 [..]
151 }
152   
153 ```
154