Examples¶
The following is a list of examples and their purpose. These examples exist in C and Python3.
The standard installation path for examples is /usr/share/theimagingsource/tiscamera/examples.
It may be neccessary to install additional development packages when using pre-compiled tiscamera packages. See Dependencies.
Build Instructions¶
Instructions to build applications using tiscamera.
Show sample code
1LIBS:=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config gstreamer-1.0 --libs)
2LIBS:=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config gstreamer-video-1.0 --libs)
3LIBS+=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config gobject-introspection-1.0 --libs)
4LIBS+=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config tcam --libs)
5
6# to build within the source tree
7# enable the following lines
8# and source build directory ./env.sh
9# LIBS+=-L./../../build/libs
10
11CFLAGS:=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config gstreamer-1.0 --cflags)
12CFLAGS:=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config gstreamer-video-1.0 --cflags)
13CFLAGS+=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config gobject-introspection-1.0 --cflags)
14CFLAGS+=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config tcam --cflags)
15
16# CFLAGS+=-I../../libs/tcam-property/src
17# CFLAGS+=-I../../src/gstreamer-1.0/tcamsrc
18
19.PHONY: all clean
20
21EXECS = 00-list-devices \
22 01-list-properties \
23 02-set-properties \
24 03-live-stream \
25 04-list-formats \
26 05-set-format \
27 06-softwaretrigger \
28 07-appsink \
29 08-save-stream \
30 09-device-lost \
31 10-metadata \
32 11-json-state \
33 12-tcam-properties \
34 13-gstquery
35
36all: $(EXECS)
37
38
39$(EXECS): %: %.c
40 $(CC) -g -DGST_DISABLE_DEPRECATED -Wall -Wextra -O0 $(CFLAGS) -o $@ $< $(LIBS)
41
42clean:
43 $(RM) *.o
44 $(RM) $(EXECS)
Automatically handled by gobject introspection.
For custom installations set GI_TYPELIB_PATH to where the file Tcam-1.0.typelib is installed.
00 - list-devices¶
Shows what cameras there are and how to identify them.
Show sample code
1
2/* This example will show you how to list information about the available devices */
3
4#include <gst/gst.h>
5#include <stdio.h> /* printf and putchar */
6
7
8void print_device(GstDevice* device)
9{
10
11 GstStructure* struc = gst_device_get_properties(device);
12
13 printf("\tmodel:\t%s\tserial:\t%s\ttype:\t%s\n",
14 gst_structure_get_string(struc, "model"),
15 gst_structure_get_string(struc, "serial"),
16 gst_structure_get_string(struc, "type"));
17
18 gst_structure_free(struc);
19
20}
21
22
23gboolean bus_function(GstBus* bus __attribute__((unused)), GstMessage* message, gpointer user_data __attribute__((unused)))
24{
25 GstDevice* device;
26
27 switch (GST_MESSAGE_TYPE(message))
28 {
29 case GST_MESSAGE_DEVICE_ADDED:
30 {
31 gst_message_parse_device_added(message, &device);
32
33 printf("NEW device\n");
34 print_device(device);
35 gst_object_unref(device);
36 break;
37 }
38 case GST_MESSAGE_DEVICE_REMOVED:
39 {
40 // this can also be used as an alternative to device-lost signals
41 gst_message_parse_device_removed(message, &device);
42 printf("REMOVED Device\n");
43 print_device(device);
44 gst_object_unref(device);
45 break;
46 }
47 /*
48 // not used by tiscamera
49 // requires gstreamer 1.16
50 case GST_MESSAGE_DEVICE_CHANGED:
51 */
52 default:
53 {
54 break;
55 }
56 }
57
58 // this means we want to continue
59 // to listen to device events
60 // to stop listening return G_SOURCE_REMOVE;
61 return G_SOURCE_CONTINUE;
62}
63
64
65int main(int argc, char* argv[])
66{
67 /* this line sets the gstreamer default logging level
68 it can be removed in normal applications
69 gstreamer logging can contain verry useful information
70 when debugging your application
71 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
72 for further details
73 */
74 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
75
76 gst_init(&argc, &argv); // init gstreamer
77
78 // The device monitor listens to device activities for us
79 GstDeviceMonitor* monitor = gst_device_monitor_new();
80 // We are only interested in devices that are in the categories
81 // Video and Source && tcam
82 gst_device_monitor_add_filter(monitor, "Video/Source/tcam", NULL);
83
84 //
85 // static query
86 // list all devices that are available right now
87 //
88
89 GList* devices = gst_device_monitor_get_devices(monitor);
90
91 for (GList* elem = devices; elem; elem = elem->next)
92 {
93 GstDevice* device = (GstDevice*) elem->data;
94
95 print_device(device);
96 }
97
98 g_list_free_full(devices, gst_object_unref);
99
100 //
101 // dynamic listing
102 // notify us on all device changes (add/remove/changed)
103 // all devices will appear once as ADDED
104 //
105
106 GstBus* bus = gst_device_monitor_get_bus(monitor);
107 gst_bus_add_watch(bus, bus_function, NULL);
108 gst_object_unref(bus);
109
110 // actually start the dynamic monitoring
111 gst_device_monitor_start(monitor);
112
113 printf("Now listening to device changes. Disconnect your camera to see a remove event. Connect it to see a connect event. Press Ctrl-C to end.\n");
114
115 // This is simply used to wait for events or the user to end this script
116 GMainLoop* loop = g_main_loop_new(NULL, FALSE);
117 g_main_loop_run(loop);
118 g_main_loop_unref(loop);
119
120 // has to be called when gst_device_monitor_start has been called
121 gst_device_monitor_stop(monitor);
122
123 // cleanup
124 gst_object_unref(monitor);
125
126 return 0;
127}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to list information about the available devices
5#
6
7import sys
8import gi
9
10gi.require_version("Gst", "1.0")
11gi.require_version("GLib", "2.0")
12
13from gi.repository import GLib, Gst
14
15
16def print_device(device):
17 """
18
19 """
20
21 # struc is a Gst.Structure
22 struc = device.get_properties()
23
24 print("\tmodel:\t{}\tserial:\t{}\ttype:\t{}".format(struc.get_string("model"),
25 struc.get_string("serial"),
26 struc.get_string("type")))
27
28
29def bus_function(bus, message, user_data):
30 """
31 Callback for the GstBus watch
32 """
33
34 if message.type == Gst.MessageType.DEVICE_ADDED:
35 device = message.parse_device_added()
36 print("NEW Device")
37 print_device(device)
38 elif message.type == Gst.MessageType.DEVICE_REMOVED:
39 device = message.parse_device_removed()
40 print("REMOVED Device")
41 print_device(device)
42
43 return True
44
45
46if __name__ == "__main__":
47
48 Gst.init(sys.argv) # init gstreamer
49
50 # this line sets the gstreamer default logging level
51 # it can be removed in normal applications
52 # gstreamer logging can contain verry useful information
53 # when debugging your application
54 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
55 # for further details
56 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
57
58 monitor = Gst.DeviceMonitor.new()
59
60 monitor.add_filter("Video/Source/tcam")
61
62 #
63 # static query
64 # list all devices that are available right now
65 #
66
67 for device in monitor.get_devices():
68
69 print_device(device)
70
71 #
72 # dynamic listing
73 # notify us on all device changes (add/remove/changed)
74 # all devices will appear once as ADDED
75 #
76
77 bus = monitor.get_bus()
78 bus.add_watch(GLib.PRIORITY_DEFAULT, bus_function, None)
79
80 monitor.start()
81 print("Now listening to device changes. Disconnect your camera to see a remove event. Connect it to see a connect event. Press Ctrl-C to end.\n")
82
83 # This is simply used to wait for events or the user to end this script
84 loop = GLib.MainLoop.new(None, False)
85 loop.run()
86
87 # has to be called when gst_device_monitor_start has been called
88 monitor.stop()
01 - list-properties¶
Shows the properties of a camera and their settings (range, current value, etc.).
Show sample code
1
2/* This example will show you how to list the available properties */
3
4#include "tcam-property-1.0.h" /* gobject introspection interface */
5
6#include <gst/gst.h>
7#include <stdio.h> /* printf and putchar */
8#include <string.h>
9#include <unistd.h>
10
11void print_flags(TcamPropertyBase* prop)
12{
13 printf("Available: ");
14 GError* err = NULL;
15 gboolean av = tcam_property_base_is_available(prop, &err);
16 if (av)
17 {
18 printf("yes");
19 }
20 else
21 {
22 printf("no");
23 }
24
25 printf("\tLocked: ");
26
27 gboolean lo = tcam_property_base_is_locked(prop, &err);
28
29 if (lo)
30 {
31 printf("yes");
32 }
33 else
34 {
35 printf("no");
36 }
37}
38
39
40void list_properties(GstElement* source)
41{
42
43 GError* err = NULL;
44 GSList* names = tcam_property_provider_get_tcam_property_names(TCAM_PROPERTY_PROVIDER(source), &err);
45
46 for (unsigned int i = 0; i < g_slist_length(names); ++i)
47 {
48 char* name = (char*)g_slist_nth(names, i)->data;
49
50 TcamPropertyBase* base_property = tcam_property_provider_get_tcam_property(TCAM_PROPERTY_PROVIDER(source), name, &err);
51
52 TcamPropertyType type = tcam_property_base_get_property_type(base_property);
53
54 switch(type)
55 {
56 case TCAM_PROPERTY_TYPE_INTEGER:
57 {
58 TcamPropertyInteger* integer = TCAM_PROPERTY_INTEGER(base_property);
59
60 gint64 def = tcam_property_integer_get_default(integer, &err);
61
62 gint64 min;
63 gint64 max;
64 gint64 step;
65 tcam_property_integer_get_range(integer, &min, &max, &step, &err);
66
67 if (err)
68 {
69 printf("%s\n", err->message);
70 g_error_free(err);
71 err = NULL;
72 break;
73 }
74
75 gint64 value = tcam_property_integer_get_value(integer, &err);
76
77 if (err)
78 {
79 printf("%s\n", err->message);
80 g_error_free(err);
81 err = NULL;
82 break;
83 }
84
85 const char* unit = "";
86 const char* tmp_unit = tcam_property_integer_get_unit(integer);
87
88 if (tmp_unit)
89 {
90 unit = tmp_unit;
91 }
92
93 printf("%s\ttype: Integer\t"
94 "Display Name: \"%s\" "
95 "Category: %s\n"
96 "\t\t\tDescription: %s\n"
97 "\t\t\tUnit: %s\n"
98 "\t\t\tVisibility: %s\n"
99 "\t\t\tPresentation: %s\n\t\t\t",
100 name,
101 tcam_property_base_get_display_name(base_property),
102 tcam_property_base_get_category(base_property),
103 tcam_property_base_get_description(base_property),
104 unit,
105 g_enum_to_string(tcam_property_visibility_get_type() , tcam_property_base_get_visibility(base_property)),
106 g_enum_to_string(tcam_property_intrepresentation_get_type(), tcam_property_integer_get_representation(integer)));
107 print_flags(base_property);
108 printf("\n\n"
109 "\t\t\tDefault: %ld\n"
110 "\t\t\tValue: %ld"
111 "\n\n", def, value);
112
113 break;
114
115 }
116 case TCAM_PROPERTY_TYPE_FLOAT:
117 {
118 TcamPropertyFloat* f = TCAM_PROPERTY_FLOAT(base_property);
119
120 gdouble def = tcam_property_float_get_default(f, &err);
121;
122 gdouble min;
123 gdouble max;
124 gdouble step;
125 tcam_property_float_get_range(f, &min, &max, &step, &err);
126
127 if (err)
128 {
129 printf("%s\n", err->message);
130 g_error_free(err);
131 err = NULL;
132 break;
133 }
134
135 gdouble value = tcam_property_float_get_value(f, &err);
136
137 if (err)
138 {
139 printf("%s\n", err->message);
140 g_error_free(err);
141 err = NULL;
142 break;
143 }
144
145
146 const char* unit = "";
147 const char* tmp_unit = tcam_property_float_get_unit(f);
148
149 if (tmp_unit)
150 {
151 unit = tmp_unit;
152 }
153
154 printf("%s\ttype: Float\t"
155 "Display Name: \"%s\" "
156 "Category: %s\n"
157 "\t\t\tDescription: %s\n"
158 "\t\t\tUnit: %s\n"
159 "\t\t\tVisibility: %s\n"
160 "\t\t\tPresentation: %s\n\t\t\t",
161 name,
162 tcam_property_base_get_display_name(base_property),
163 tcam_property_base_get_category(base_property),
164 tcam_property_base_get_description(base_property),
165 unit,
166 g_enum_to_string(tcam_property_visibility_get_type() , tcam_property_base_get_visibility(base_property)),
167 g_enum_to_string(tcam_property_intrepresentation_get_type(), tcam_property_float_get_representation(f)));
168 print_flags(base_property);
169 printf("\n\n"
170 "\t\t\tDefault: %f\n"
171 "\t\t\tValue: %f"
172 "\n\n", def, value);
173
174 break;
175 }
176 case TCAM_PROPERTY_TYPE_ENUMERATION:
177 {
178 TcamPropertyEnumeration* e = TCAM_PROPERTY_ENUMERATION(base_property);
179
180 const char* value = tcam_property_enumeration_get_value(e, &err);
181
182 if (err)
183 {
184 printf("%s\n", err->message);
185 g_error_free(err);
186 err = NULL;
187 break;
188 }
189
190 const char* def = tcam_property_enumeration_get_default(e, &err);
191
192 if (err)
193 {
194 printf("%s\n", err->message);
195 g_error_free(err);
196 err = NULL;
197 break;
198 }
199
200 printf("%s\ttype: Enumeration\t"
201 "Display Name: \"%s\" "
202 "Category: %s\n"
203 "\t\t\tDescription: %s\n"
204 "\t\t\tVisibility: %s\n"
205 "\t\t\t",
206 name, tcam_property_base_get_display_name(base_property),
207 tcam_property_base_get_category(base_property),
208 tcam_property_base_get_description(base_property),
209 g_enum_to_string(tcam_property_visibility_get_type() , tcam_property_base_get_visibility(base_property)));
210 print_flags(base_property);
211 printf("\n\n"
212 "\t\t\tEntries:");
213
214 GSList* enum_entries = tcam_property_enumeration_get_enum_entries(e, &err);
215
216 if (err)
217 {
218 printf("%s\n", err->message);
219 g_error_free(err);
220 break;
221 }
222
223 if (enum_entries)
224 {
225 for (GSList* entry = enum_entries; entry != NULL; entry = entry->next)
226 {
227 printf(" %s", (const char*)entry->data);
228 }
229
230 g_slist_free_full(enum_entries, g_free);
231 }
232 printf("\n\t\t\tDefault: %s\n"
233 "\t\t\tValue: %s\n\n\n", def, value);
234
235 break;
236 }
237 case TCAM_PROPERTY_TYPE_BOOLEAN:
238 {
239 TcamPropertyBoolean* b = TCAM_PROPERTY_BOOLEAN(base_property);
240 gboolean value = tcam_property_boolean_get_value(b, &err);
241 gboolean def = tcam_property_boolean_get_default(b, &err);
242
243 if (err)
244 {
245 printf("%s\n", err->message);
246 g_error_free(err);
247 err = NULL;
248 break;
249 }
250
251 const char* val_str = "false";
252 const char* def_str = "false";
253
254 if (value)
255 {
256 val_str = "true";
257 }
258
259 if (def)
260 {
261 def_str = "true";
262 }
263
264 printf("%s\ttype: Boolean\t"
265 "Display Name: \"%s\" "
266 "Category: %s\n"
267 "\t\t\tDescription: %s\n"
268 "\t\t\t",
269 name,
270 tcam_property_base_get_display_name(base_property),
271 tcam_property_base_get_category(base_property),
272 tcam_property_base_get_description(base_property)
273 );
274 print_flags(base_property);
275 printf("\n\n\t\t\tDefault: %s\n"
276 "\t\t\tValue: %s\n\n\n",
277 def_str, val_str);
278
279 break;
280 }
281 case TCAM_PROPERTY_TYPE_COMMAND:
282 {
283 printf("%s\ttype: Command\t"
284 "Display Name: \"%s\" "
285 "Category: %s\n"
286 "\t\t\tDescription: %s\n"
287 "\t\t\t",
288 name,
289 tcam_property_base_get_display_name(base_property),
290 tcam_property_base_get_category(base_property),
291 tcam_property_base_get_description(base_property));
292 print_flags(base_property);
293 printf("\n\n\n");
294 break;
295 }
296 default:
297 {
298 break;
299 }
300 printf("\n\n\n");
301 }
302 g_object_unref(base_property);
303 }
304 g_slist_free_full(names, g_free);
305}
306
307
308int main(int argc, char* argv[])
309{
310 /* this line sets the gstreamer default logging level
311 it can be removed in normal applications
312 gstreamer logging can contain verry useful information
313 when debugging your application
314 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
315 for further details
316 */
317 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
318
319 gst_init(&argc, &argv); // init gstreamer
320
321 GError* err = NULL;
322
323 // this is a placeholder definition
324 // normally your pipeline would be defined here
325 GstElement* pipeline = gst_parse_launch("tcambin name=source ! fakesink", &err);
326
327 if (pipeline == NULL)
328 {
329 printf("Unable to create pipeline: %s\n", err->message);
330 g_free(err);
331 return 1;
332 }
333
334 /* get the tcambin to retrieve device information */
335 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
336
337 const char* serial = NULL; // set this if you do not want the first found device
338
339 if (serial != NULL)
340 {
341 GValue val = {};
342 g_value_init(&val, G_TYPE_STRING);
343 g_value_set_static_string(&val, serial);
344
345 g_object_set_property(G_OBJECT(source), "serial", &val);
346 }
347
348 // in the READY state the camera will always be initialized
349 gst_element_set_state(pipeline, GST_STATE_READY);
350
351 list_properties(source);
352
353 // cleanup
354 gst_element_set_state(pipeline, GST_STATE_NULL);
355
356 gst_object_unref(source);
357 gst_object_unref(pipeline);
358
359 return 0;
360}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to list available properties
5#
6
7import sys
8import gi
9
10gi.require_version("Tcam", "1.0")
11gi.require_version("Gst", "1.0")
12gi.require_version("GLib", "2.0")
13
14from gi.repository import Tcam, Gst, GLib
15
16
17def flag_strings(prop):
18 """
19
20 """
21
22 ret = "Available: "
23
24 if prop.is_available():
25 ret += "yes"
26 else:
27 ret += "no"
28
29 ret += "\tLocked: "
30
31 if prop.is_locked():
32 ret += "yes"
33 else:
34 ret += "no"
35
36 return ret
37
38
39def list_properties(camera):
40
41 property_names = camera.get_tcam_property_names()
42
43 for name in property_names:
44 try:
45 base = camera.get_tcam_property(name)
46
47 if base.get_property_type() == Tcam.PropertyType.INTEGER:
48
49 default = base.get_default()
50 mini, maxi, step = base.get_range()
51
52 unit = base.get_unit()
53 if not unit:
54 unit = ""
55
56 print(("{name}\ttype: Integer\tDisplay Name: \"{disp_name}\"\tCategory: {cat}\n"
57 "\t\t\tDescription: {desc}\n"
58 "\t\t\tUnit: {unit}\n"
59 "\t\t\tVisibility: {vis}\n"
60 "\t\t\tPresentation: {pres}\n"
61 "\t\t\t{flags}\n\n"
62 "\t\t\tMin: {mini}\t Max: {maxi}\tStep: {step}\n"
63 "\t\t\tDefault: {default}\n"
64 "\t\t\tValue: {val}\n\n").format(name=name,
65 disp_name=base.get_display_name(),
66 cat=base.get_category(),
67 desc=base.get_description(),
68 unit=unit,
69 vis=base.get_visibility(),
70 pres=base.get_representation(),
71 flags=flag_strings(base),
72 mini=mini,
73 maxi=maxi,
74 step=step,
75 default=default,
76 val=base.get_value()))
77 elif base.get_property_type() == Tcam.PropertyType.FLOAT:
78
79 default = base.get_default()
80 mini, maxi, step = base.get_range()
81
82 unit = base.get_unit()
83 if not unit:
84 unit = ""
85
86 print(("{name}\ttype: Float\tDisplay Name: \"{disp_name}\"\tCategory: {cat}\n"
87 "\t\t\tDescription: {desc}\n"
88 "\t\t\tUnit: {unit}\n"
89 "\t\t\tVisibility: {vis}\n"
90 "\t\t\tPresentation: {pres}\n"
91 "\t\t\t{flags}\n\n"
92 "\t\t\tMin: {mini}\t Max: {maxi}\tStep: {step}\n"
93 "\t\t\tDefault: {default}\n"
94 "\t\t\tValue: {val}\n\n").format(name=name,
95 disp_name=base.get_display_name(),
96 cat=base.get_category(),
97 desc=base.get_description(),
98 unit=unit,
99 vis=base.get_visibility(),
100 pres=base.get_representation(),
101 flags=flag_strings(base),
102 mini=mini,
103 maxi=maxi,
104 step=step,
105 default=default,
106 val=base.get_value()))
107 elif base.get_property_type() == Tcam.PropertyType.ENUMERATION:
108 print(("{name}\ttype: Enumeration\tDisplay Name: \"{disp_name}\"\tCategory: {cat}\n"
109 "\t\t\tDescription: {desc}\n"
110 "\t\t\tVisibility: {vis}\n"
111 "\t\t\t{flags}\n\n"
112 "\t\t\tEntries: {entries}\n"
113 "\t\t\tDefault: {default}\n"
114 "\t\t\tValue: {val}\n\n").format(name=name,
115 disp_name=base.get_display_name(),
116 cat=base.get_category(),
117 desc=base.get_description(),
118 vis=base.get_visibility(),
119 flags=flag_strings(base),
120 entries=base.get_enum_entries(),
121 default=base.get_default(),
122 val=base.get_value()))
123 elif base.get_property_type() == Tcam.PropertyType.BOOLEAN:
124 print(("{name}\ttype: Boolean\tDisplay Name: \"{disp_name}\"\tCategory: {cat}\n"
125 "\t\t\tDescription: {desc}\n"
126 "\t\t\tVisibility: {vis}\n"
127 "\t\t\t{flags}\n\n"
128 "\t\t\tDefault: {default}\n"
129 "\t\t\tValue: {val}\n\n").format(name=name,
130 disp_name=base.get_display_name(),
131 cat=base.get_category(),
132 desc=base.get_description(),
133 vis=base.get_visibility(),
134 flags=flag_strings(base),
135 default=base.get_default(),
136 val=base.get_value()))
137 elif base.get_property_type() == Tcam.PropertyType.COMMAND:
138 print(("{name}\ttype: Command\tDisplay Name: \"{disp_name}\"\tCategory: {cat}\n"
139 "\t\t\tDescription: {desc}\n"
140 "\t\t\tVisibility: {vis}\n"
141 "\t\t\t{flags}\n\n").format(name=name,
142 disp_name=base.get_display_name(),
143 cat=base.get_category(),
144 desc=base.get_description(),
145 vis=base.get_visibility(),
146 flags=flag_strings(base)))
147 except GLib.Error as err:
148
149 print("Error for {}: {}".format(name, err.message))
150
151
152def block_until_playing(pipeline):
153
154 while True:
155 # wait 0.1 seconds for something to happen
156 change_return, state, pending = pipeline.get_state(100000000)
157 if change_return == Gst.StateChangeReturn.SUCCESS:
158 return True
159 elif change_return == Gst.StateChangeReturn.FAILURE:
160 print("Failed to change state {} {} {}".format(change_return,
161 state,
162 pending))
163 return False
164
165
166def main():
167 Gst.init(sys.argv) # init gstreamer
168
169 # this line sets the gstreamer default logging level
170 # it can be removed in normal applications
171 # gstreamer logging can contain verry useful information
172 # when debugging your application
173 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
174 # for further details
175 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
176
177 pipeline = Gst.parse_launch("tcambin name=source ! fakesink")
178
179 if not pipeline:
180 print("Unable to create pipeline")
181 return 1
182
183 # set this to a specific camera serial if you
184 # do not want to use the default camera
185 serial = None
186
187 # get the tcambin to retrieve a property list through it
188 source = pipeline.get_by_name("source")
189
190 # serial is defined, thus make the source open that device
191 if serial is not None:
192 source.set_property("serial", serial)
193
194 # the pipeline/tcamsrc/tcambin element must
195 # at least be in Gst.State.READY
196 # for a device to be open.
197 # with Gst.State.NULL
198 # no properties will be returned
199 pipeline.set_state(Gst.State.READY)
200
201 list_properties(source)
202
203 # This closes the device
204 # All properties are now invalid
205 # and have to be deleted
206 pipeline.set_state(Gst.State.NULL)
207
208 return 0
209
210
211if __name__ == "__main__":
212 sys.exit(main())
02 - set-properties¶
Shows how to set a specific property.
Show sample code
1
2/* This example will show you how to set properties for a certain camera */
3
4#include "tcam-property-1.0.h" /* gobject introspection interface */
5
6#include <gst/gst.h>
7#include <stdio.h> /* printf and putchar */
8
9
10void print_enum_property(GstElement* source, const char* name)
11{
12 /* this is only a sample not all properties will be set here */
13
14 GError* err = NULL;
15 TcamPropertyBase* property_base = tcam_property_provider_get_tcam_property(TCAM_PROPERTY_PROVIDER(source),
16 name,
17 &err);
18
19 if (err)
20 {
21 printf("Error while retrieving property: %s\n", err->message);
22 g_error_free(err);
23 err = NULL;
24 }
25
26 if (tcam_property_base_get_property_type(property_base) != TCAM_PROPERTY_TYPE_ENUMERATION)
27 {
28 printf("%s has wrong type. This should not happen.\n", name);
29 }
30 else
31 {
32 TcamPropertyEnumeration* property_enum = TCAM_PROPERTY_ENUMERATION(property_base);
33 const char* value = tcam_property_enumeration_get_value(property_enum, &err);
34
35 if (err)
36 {
37 printf("Error while retrieving property: %s\n", err->message);
38 g_error_free(err);
39 err = NULL;
40 }
41 else
42 {
43 printf("%s: %s\n", name, value);
44 }
45 }
46 g_object_unref(property_base);
47}
48
49
50void set_enum_property(GstElement* source, const char* name, const char* value)
51{
52 GError* err = NULL;
53 TcamPropertyBase* property_base = tcam_property_provider_get_tcam_property(TCAM_PROPERTY_PROVIDER(source),
54 name,
55 &err);
56
57 if (err)
58 {
59 printf("Error while retrieving property: %s\n", err->message);
60 g_error_free(err);
61 err = NULL;
62 }
63
64 if (tcam_property_base_get_property_type(property_base) != TCAM_PROPERTY_TYPE_ENUMERATION)
65 {
66 printf("ExposureAuto has wrong type. This should not happen.\n");
67 }
68 else
69 {
70 TcamPropertyEnumeration* enum_property = TCAM_PROPERTY_ENUMERATION(property_base);
71
72 tcam_property_enumeration_set_value(enum_property, value, &err);
73
74 if (err)
75 {
76 printf("Error while setting property: %s\n", err->message);
77 g_error_free(err);
78 err = NULL;
79 }
80 else
81 {
82 printf("Set %s to %s\n", name, value);
83 }
84 }
85 g_object_unref(property_base);
86}
87
88
89
90int main(int argc, char* argv[])
91{
92 /* this line sets the gstreamer default logging level
93 it can be removed in normal applications
94 gstreamer logging can contain verry useful information
95 when debugging your application
96 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
97 for further details
98 */
99 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
100
101 gst_init(&argc, &argv); // init gstreamer
102
103 GError* err = NULL;
104
105 // this is a placeholder definition
106 // normally your pipeline would be defined here
107 GstElement* pipeline = gst_parse_launch("tcambin name=source ! fakesink", &err);
108
109 if (pipeline == NULL)
110 {
111 printf("Unable to create pipeline: %s\n", err->message);
112 g_free(err);
113 err = NULL;
114 return 1;
115 }
116
117 /* create a tcambin to retrieve device information */
118 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
119
120 const char* serial = NULL;
121
122 if (serial != NULL)
123 {
124 GValue val = {};
125 g_value_init(&val, G_TYPE_STRING);
126 g_value_set_static_string(&val, serial);
127
128 g_object_set_property(G_OBJECT(source), "serial", &val);
129 }
130
131 gst_element_set_state(pipeline, GST_STATE_READY);
132
133 /* Device is now in a state for interactions */
134
135 /*
136 We print the properties for a before/after comparison,
137 */
138 printf("Values before we change them:\n\n");
139
140 print_enum_property(source, "ExposureAuto");
141 print_enum_property(source, "GainAuto");
142
143 /*
144 We set the properties to other values
145 */
146 printf("\nChanging:\n\n");
147
148 set_enum_property(source, "ExposureAuto", "Off");
149 set_enum_property(source, "GainAuto", "Off");
150
151 /* alternatively you can get/set directly on the TCAM_PROPERTY_PROVIDER */
152 /* for this you need to know the type of the property you want to get/set */
153
154 /* tcam_property_provider_set_tcam_enumeration(TCAM_PROPERTY_PROVIDER(source), "ExposureAuto", "Off"); */
155 /* tcam_property_provider_set_tcam_integer(TCAM_PROPERTY_PROVIDER(source), "Brightness", 200); */
156 /* tcam_property_provider_set_tcam_float(TCAM_PROPERTY_PROVIDER(source), "ExposureTime", 30000.0); */
157
158 printf("\nValues after we changed them:\n\n");
159
160 /*
161 second print for the before/after comparison
162 */
163 print_enum_property(source, "ExposureAuto");
164 print_enum_property(source, "GainAuto");
165
166 /* cleanup, reset state */
167 gst_element_set_state(source, GST_STATE_NULL);
168
169 gst_object_unref(source);
170
171 return 0;
172}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to set properties
5#
6
7import sys
8import gi
9
10gi.require_version("Tcam", "1.0")
11gi.require_version("Gst", "1.0")
12gi.require_version("GLib", "2.0")
13
14from gi.repository import Tcam, Gst, GLib
15
16
17def print_properties(camera):
18 """
19 Print selected properties
20 """
21 try:
22
23 property_exposure_auto = camera.get_tcam_property("ExposureAuto")
24
25 print(property_exposure_auto.get_value())
26
27 value = camera.get_tcam_enumeration("ExposureAuto")
28
29 print(f"Exposure Auto has value: {value}")
30
31 value = camera.get_tcam_enumeration("GainAuto")
32
33 print("Gain Auto has value: {}".format(value))
34
35 value = camera.get_tcam_float("ExposureTime")
36
37 print("ExposureTimer has value: {}".format(value))
38
39 except GLib.Error as err:
40
41 print(f"{err.message}")
42
43
44def block_until_playing(pipeline):
45
46 while True:
47 # wait 0.1 seconds for something to happen
48 change_return, state, pending = pipeline.get_state(100000000)
49 if change_return == Gst.StateChangeReturn.SUCCESS:
50 return True
51 elif change_return == Gst.StateChangeReturn.FAILURE:
52 print("Failed to change state {} {} {}".format(change_return,
53 state,
54 pending))
55 return False
56
57
58def main():
59
60 Gst.init(sys.argv)
61
62 # this line sets the gstreamer default logging level
63 # it can be removed in normal applications
64 # gstreamer logging can contain verry useful information
65 # when debugging your application
66 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
67 # for further details
68 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
69
70 # Set this to a serial string for a specific camera
71 serial = None
72
73 camera = Gst.ElementFactory.make("tcambin")
74
75 if serial:
76 # This is gstreamer set_property
77 camera.set_property("serial", serial)
78
79 # in the READY state the camera will always be initialized
80 camera.set_state(Gst.State.READY)
81
82 # Print properties for a before/after comparison
83 print_properties(camera)
84
85 # Set properties
86
87 camera.set_tcam_enumeration("ExposureAuto", "Off")
88 camera.set_tcam_enumeration("GainAuto", "Off")
89
90 camera.set_tcam_float("ExposureTime", 2000)
91
92 print_properties(camera)
93
94 # cleanup, reset state
95 camera.set_state(Gst.State.NULL)
96
97
98if __name__ == "__main__":
99 sys.exit(main())
03 - live-stream¶
Delivers live-image stream from the camera.
Show sample code
1
2/* This example will show you how to start a live stream from your camera */
3
4#include <gst/gst.h>
5#include <stdio.h> /* printf and putchar */
6
7
8int main(int argc, char* argv[])
9{
10 /* this line sets the gstreamer default logging level
11 it can be removed in normal applications
12 gstreamer logging can contain verry useful information
13 when debugging your application
14 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
15 for further details
16 */
17 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
18
19 gst_init(&argc, &argv); // init gstreamer
20
21 const char* serial = NULL; // set this if you do not want the first found device
22
23 GError* err = NULL;
24
25 GstElement* pipeline =
26 gst_parse_launch("tcambin name=source ! videoconvert ! ximagesink sync=false", &err);
27
28 if (err)
29 {
30 printf("%s\n", err->message);
31 g_error_free(err);
32 err = NULL;
33 }
34
35 /* test for error */
36 if (pipeline == NULL)
37 {
38 printf("Could not create pipeline. Cause: %s\n", err->message);
39 return 1;
40 }
41
42 if (serial != NULL)
43 {
44 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
45 GValue val = {};
46 g_value_init(&val, G_TYPE_STRING);
47 g_value_set_static_string(&val, serial);
48
49 g_object_set_property(G_OBJECT(source), "serial", &val);
50
51 gst_object_unref(source);
52 }
53
54 gst_element_set_state(pipeline, GST_STATE_PLAYING);
55
56 printf("Press enter to stop the stream.\n");
57 getchar();
58
59 gst_element_set_state(pipeline, GST_STATE_NULL);
60
61 gst_object_unref(pipeline);
62
63 return 0;
64}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to start a simply live stream
5#
6
7import time
8import sys
9import gi
10
11gi.require_version("Gst", "1.0")
12
13from gi.repository import Gst
14
15
16def main():
17
18 Gst.init(sys.argv) # init gstreamer
19
20 # this line sets the gstreamer default logging level
21 # it can be removed in normal applications
22 # gstreamer logging can contain verry useful information
23 # when debugging your application
24 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
25 # for further details
26 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
27
28 serial = None
29
30 pipeline = Gst.parse_launch("tcambin name=bin "
31 " ! videoconvert"
32 " ! ximagesink sync=false")
33
34 # retrieve the bin element from the pipeline
35 camera = pipeline.get_by_name("bin")
36
37 # serial is defined, thus make the source open that device
38 if serial is not None:
39 camera.set_property("serial", serial)
40
41 pipeline.set_state(Gst.State.PLAYING)
42
43 print("Press Ctrl-C to stop.")
44
45 # We wait with this thread until a
46 # KeyboardInterrupt in the form of a Ctrl-C
47 # arrives. This will cause the pipline
48 # to be set to state NULL
49 try:
50 while True:
51 time.sleep(1)
52 except KeyboardInterrupt:
53 pass
54 finally:
55 pipeline.set_state(Gst.State.NULL)
56
57
58if __name__ == "__main__":
59 main()
04 - list-format¶
Lists what formats the camera offers.
Show sample code
1
2/* This example will show you how to list the formats your device offers */
3
4#include "tcam-property-1.0.h" /* gobject introspection interface */
5
6#include <gst/gst.h>
7#include <stdio.h> /* printf and putchar */
8
9
10int main(int argc, char* argv[])
11{
12 /* this line sets the gstreamer default logging level
13 it can be removed in normal applications
14 gstreamer logging can contain verry useful information
15 when debugging your application
16 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
17 for further details
18 */
19 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
20
21 gst_init(&argc, &argv); // init gstreamer
22
23 // set this if you do not want the first found device
24 char* serial = NULL;
25
26 /* create a tcambin to retrieve device information */
27 GstElement* source = gst_element_factory_make("tcambin", "source");
28
29 if (serial != NULL)
30 {
31 GValue val = {};
32 g_value_init(&val, G_TYPE_STRING);
33 g_value_set_static_string(&val, serial);
34
35 g_object_set_property(G_OBJECT(source), "serial", &val);
36 }
37
38 /* Setting the state to ready ensures that all resources
39 are initialized and that we really get all format capabilities */
40 gst_element_set_state(source, GST_STATE_READY);
41
42 GstPad* pad = gst_element_get_static_pad(source, "src");
43
44 GstCaps* caps = gst_pad_query_caps(pad, NULL);
45
46 printf("================ %s\n", gst_caps_to_string(caps));
47
48 for (unsigned int i = 0; i < gst_caps_get_size(caps); ++i)
49 {
50 GstStructure* structure = gst_caps_get_structure(caps, i);
51
52 /*
53 for a simple display the following line can be used
54 printf("%s\n", gst_structure_to_string(structure));
55 */
56
57 const char* name = gst_structure_get_name(structure);
58
59 // this is only required when dealing
60 // with FPD/MiPi cameras on tegra systems
61 // must not be freed
62 GstCapsFeatures* features = gst_caps_get_features(caps, i);
63
64 if (features)
65 {
66 if (gst_caps_features_contains(features, "memory:NVMM"))
67 {
68 // do something with this information
69 printf("NVMM ");
70 }
71 }
72
73 if (gst_structure_get_field_type(structure, "format") == G_TYPE_STRING)
74 {
75 const char* format = gst_structure_get_string(structure, "format");
76
77 printf("%s %s - ", name, format);
78 }
79 else if (gst_structure_get_field_type(structure, "format") == GST_TYPE_LIST)
80 {
81 printf("%s { ", name);
82
83 const GValue* val = gst_structure_get_value(structure, "format");
84
85 for (unsigned int x = 0; x < gst_value_list_get_size(val); ++x)
86 {
87 const GValue* format = gst_value_list_get_value(val, x);
88
89 printf("%s ", g_value_get_string(format));
90 }
91
92
93 printf("} - ");
94 }
95 else
96 {
97 printf("format handling not implemented for unexpected type: %s\n",
98 G_VALUE_TYPE_NAME(gst_structure_get_field_type(structure, "format")));
99 continue;
100 }
101
102 GType width_type = gst_structure_get_field_type(structure, "width");
103
104 if (width_type == GST_TYPE_INT_RANGE)
105 {
106 int width_min =
107 gst_value_get_int_range_min(gst_structure_get_value(structure, "width"));
108 int width_max =
109 gst_value_get_int_range_max(gst_structure_get_value(structure, "width"));
110
111
112 printf("width: [%d-%d]", width_min, width_max);
113 }
114 else
115 {
116 int width;
117 gboolean ret = gst_structure_get_int(structure, "width", &width);
118
119 if (!ret)
120 {
121 printf("Unable to query width\n");
122 continue;
123 }
124
125 printf("%d", width);
126 }
127
128 printf(" X ");
129
130 GType height_type = gst_structure_get_field_type(structure, "height");
131
132 if (height_type == GST_TYPE_INT_RANGE)
133 {
134 int height_min =
135 gst_value_get_int_range_min(gst_structure_get_value(structure, "height"));
136 int height_max =
137 gst_value_get_int_range_max(gst_structure_get_value(structure, "height"));
138
139
140 printf("height: [%d-%d]", height_min, height_max);
141 }
142 else
143 {
144 int height;
145 gboolean ret = gst_structure_get_int(structure, "height", &height);
146
147 if (!ret)
148 {
149 printf("Unable to query height\n");
150 continue;
151 }
152
153 printf("%d", height);
154 }
155
156 printf(" - ");
157
158 const GValue* framerate = gst_structure_get_value(structure, "framerate");
159
160 if (G_VALUE_TYPE(framerate) == GST_TYPE_LIST)
161 {
162 for (unsigned int x = 0; x < gst_value_list_get_size(framerate); ++x)
163 {
164 const GValue* val = gst_value_list_get_value(framerate, x);
165
166 if (G_VALUE_TYPE(val) == GST_TYPE_FRACTION)
167 {
168 int num = gst_value_get_fraction_numerator(val);
169 int den = gst_value_get_fraction_denominator(val);
170
171 printf("%d/%d ", num, den);
172 }
173 else
174 {
175 printf(
176 "Handling of framerate handling not implemented for non fraction types.\n");
177 break;
178 }
179 }
180 }
181 else if (G_VALUE_TYPE(framerate) == GST_TYPE_FRACTION_RANGE)
182 {
183 const GValue* framerate_min = gst_value_get_fraction_range_min(framerate);
184 const GValue* framerate_max = gst_value_get_fraction_range_max(framerate);
185
186 printf("%d/%d - %d/%d",
187 gst_value_get_fraction_numerator(framerate_min),
188 gst_value_get_fraction_denominator(framerate_min),
189 gst_value_get_fraction_numerator(framerate_max),
190 gst_value_get_fraction_denominator(framerate_max));
191 }
192 else
193 {
194 printf("Unable to interpret framerate type\n");
195 continue;
196 }
197
198 // we printed all information for a format decription
199 // print a new line to keep everything user readable
200 printf("\n");
201 }
202
203 gst_caps_unref(caps);
204 gst_object_unref(pad);
205
206 gst_element_set_state(source, GST_STATE_NULL);
207
208 gst_object_unref(source);
209
210 return 0;
211}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to retrieve the available gstreamer
5# caps from tcamsrc and how to display print them to stdout.
6#
7
8import sys
9import gi
10import re
11
12gi.require_version("Gst", "1.0")
13
14from gi.repository import Gst
15
16
17def print_formats(source):
18
19 caps = source.get_static_pad("src").query_caps()
20
21 for x in range(caps.get_size()):
22
23 structure = caps.get_structure(x)
24
25 # video/x-raw, video/x-bayer, etc.
26 name = structure.get_name()
27
28 # this is only required when dealing
29 # with FPD/MiPi cameras on tegra systems
30 features = caps.get_features(x)
31 if features:
32 if features.contains("memory:NVMM"):
33 print("NVMM ")
34
35 try:
36 fmt = structure.get_value("format")
37
38 if isinstance(fmt, str):
39 print(f"{name} {fmt}", end="")
40 elif isinstance(fmt, Gst.ValueList):
41
42 print(f"{name} {{ ", end="")
43
44 for y in range(Gst.ValueList.get_size(fmt)):
45
46 val = Gst.ValueList.get_value(fmt, y)
47
48 print(f"{val} ", end="")
49 print("}", end="")
50 else:
51 print("==")
52 except TypeError: # Gst.ValueList
53
54 # this means we have multiple formats that all
55 # have the same width/height/framerate settings
56
57 begin = structure.to_string().find("format=(string){")
58 print(begin)
59 substr = structure.to_string()[begin:]
60 values = substr[substr.find("{")+1:substr.find("}")]
61
62 print(f"{name} {{ ", end="")
63
64 for fmt in values.split(","):
65
66 print(f"{fmt} ", end="")
67
68 print("}", end="")
69
70 # the python gobject introspection wrapper
71 # can pose problems in older version
72 # the type Gst.IntRange
73 # may not be available and thus cause a TypeError
74 # in such a case we query the string description
75 # of the Gst.Structure and extract the width/height
76 try:
77 if (structure.to_string().find("width=[") != -1
78 or structure.to_string().find("height=[") != -1):
79 raise TypeError
80
81 width = structure.get_value("width")
82 height = structure.get_value("height")
83
84 print(f" - {width}x{height} - ", end="")
85
86 except TypeError:
87
88 # width handling
89
90 begin = structure.to_string().find("width=(int)[")
91 substr = structure.to_string()[begin:]
92 values = substr[substr.find("[")+1:substr.find("]")]
93 v = re.findall(r'\d+', values)
94
95 # assume first entry is smaller
96 width_min = v[0]
97 width_max = v[1]
98
99 # height handling
100
101 begin = structure.to_string().find("height=(int)[")
102 substr = structure.to_string()[begin:]
103 values = substr[substr.find("[")+1:substr.find("]")]
104 v = re.findall(r'\d+', values)
105
106 height_min = v[0]
107 height_max = v[1]
108
109 print(f" - {width_min}x{height_min} <=> {width_max}x{height_max} - ", end="")
110
111 # the python gobject introspection wrapper
112 # can pose problems in older version
113 # the types Gst.Fraction and Gst.FractionRange
114 # may not be available and thus cause a TypeError
115 # in such a case we query the string description
116 # of the Gst.Structure and extract the framerates
117 try:
118 framerates = structure.get_value("framerate")
119 except TypeError:
120
121 substr = structure.to_string()[structure.to_string().find("framerate="):]
122
123 try:
124 # try for frame rate lists
125 field, values, remain = re.split("{|}", substr, maxsplit=3)
126 rates = [x.strip() for x in values.split(",")]
127 for r in rates:
128 print(f"{r} ", end="")
129 except ValueError: # we have a GstFractionRange
130
131 values = substr[substr.find("[")+1:substr.find("]")]
132 v = re.findall(r'\d+', values)
133 fps_min_num = v[0]
134 fps_min_den = v[1]
135 fps_max_num = v[2]
136 fps_max_den = v[3]
137 # framerates are fractions thus one framerate euqals two values
138 print(f"{fps_min_num}/ {fps_min_den} <=> {fps_max_num}/{fps_max_den}", end="")
139
140 # printf line break
141 print("")
142 # we are done here
143 continue
144
145 if isinstance(framerates, Gst.ValueList):
146
147 # Gst.ValueList.get_size may cause a warning:
148 # DeprecationWarning: an integer is required (got type float).
149 # Implicit conversion to integers using __int__ is deprecated,
150 # and may be removed in a future version of Python.
151 #
152 # this is part of the GStreamer python wrapper
153 # and not tiscamera
154 size = Gst.ValueList.get_size(framerates)
155
156 for y in range(size):
157
158 val = Gst.ValueList.get_value(framerates, y)
159
160 print("{} ".format(val), end="")
161
162 elif isinstance(framerates, Gst.FractionRange):
163
164 min_val = Gst.value_get_fraction_range_min(framerates)
165 max_val = Gst.value_get_fraction_range_max(framerates)
166 print(f"{min_val} <-> {max_val}")
167
168 else:
169 print(f"framerates not supported {isinstance(framerates)}")
170 # we are finished
171 print("")
172
173
174def main():
175 """
176 main function
177 initializes GstElement and starts GstCaps query
178 """
179 Gst.init(sys.argv) # init gstreamer
180
181 # this line sets the gstreamer default logging level
182 # it can be removed in normal applications
183 # gstreamer logging can contain verry useful information
184 # when debugging your application
185 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
186 # for further details
187 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
188
189 source = Gst.ElementFactory.make("tcambin")
190
191 # The tcambin wraps the tcamsrc and offers additional
192 # formats by implicitly converting
193 # source = Gst.ElementFactory.make("tcambin")
194
195 serial = None
196
197 if serial:
198 source.set_property("serial", serial)
199
200 source.set_state(Gst.State.READY)
201
202 print_formats(source)
203
204 source.set_state(Gst.State.NULL)
205
206
207if __name__ == "__main__":
208 main()
05 - set format¶
Sets the camera to a specific format.
Show sample code
1
2/*
3 This example will show you how to start a live stream from your camera
4 with a specific format
5 */
6
7#include "tcam-property-1.0.h" /* gobject introspection interface */
8
9#include <gst/gst.h>
10#include <stdio.h> /* printf and putchar */
11
12
13int main(int argc, char* argv[])
14{
15 /* this line sets the gstreamer default logging level
16 it can be removed in normal applications
17 gstreamer logging can contain verry useful information
18 when debugging your application
19 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
20 for further details
21 */
22 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
23
24 gst_init(&argc, &argv); // init gstreamer
25
26 const char* serial = NULL; // set this if you do not want the first found device
27
28 GError* err = NULL;
29 const char* pipeline_desc =
30 "tcambin name=source ! capsfilter name=filter ! videoconvert ! ximagesink";
31
32 GstElement* pipeline = gst_parse_launch(pipeline_desc, &err);
33
34 /* test for error */
35 if (pipeline == NULL)
36 {
37 printf("Could not create pipeline. Cause: %s\n", err->message);
38 return 1;
39 }
40
41 if (serial != NULL)
42 {
43 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
44 GValue val = {};
45 g_value_init(&val, G_TYPE_STRING);
46 g_value_set_static_string(&val, serial);
47
48 g_object_set_property(G_OBJECT(source), "serial", &val);
49
50 gst_object_unref(source);
51 }
52
53
54 GstCaps* caps = gst_caps_new_empty();
55
56 GstStructure* structure = gst_structure_from_string("video/x-raw", NULL);
57 gst_structure_set(structure,
58 "format",
59 G_TYPE_STRING,
60 "BGRx",
61 "width",
62 G_TYPE_INT,
63 640,
64 "height",
65 G_TYPE_INT,
66 480,
67 "framerate",
68 GST_TYPE_FRACTION,
69 15,
70 1,
71 NULL);
72
73 gst_caps_append_structure(caps, structure);
74
75 GstElement* capsfilter = gst_bin_get_by_name(GST_BIN(pipeline), "filter");
76
77 if (capsfilter == NULL)
78 {
79 printf("Could not retrieve capsfilter from pipeline.");
80 return 1;
81 }
82
83 g_object_set(G_OBJECT(capsfilter), "caps", caps, NULL);
84 gst_object_unref(capsfilter);
85 gst_caps_unref(caps);
86
87 /*
88 to statically create caps you can reduce the whole procedure to
89 GstCaps* caps = gst_caps_from_string("video/x-raw,format=BGRx,width=640,height=480,framerate=30/1");
90
91 gst_parse_lauch allows you to use strings for caps descriptions.
92 That means everything until now can be done with:
93
94 GstElement* pipeline = gst_parse_launch("tcambin name=source ! video/x-raw,format=BGRx,width=640,height=480,framerate=30/1 ! videoconvert ! ximagesink", &err);
95
96 */
97
98
99 gst_element_set_state(pipeline, GST_STATE_PLAYING);
100
101 printf("Press enter to stop the stream.\n");
102 getchar();
103
104 gst_element_set_state(pipeline, GST_STATE_NULL);
105
106 gst_object_unref(pipeline);
107
108 return 0;
109}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to start a simply live stream
5#
6
7import time
8import sys
9import gi
10
11gi.require_version("Gst", "1.0")
12
13from gi.repository import Gst
14
15
16def main():
17 """
18 """
19 Gst.init(sys.argv) # init gstreamer
20
21 # this line sets the gstreamer default logging level
22 # it can be removed in normal applications
23 # gstreamer logging can contain verry useful information
24 # when debugging your application
25 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
26 # for further details
27 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
28
29 serial = None
30
31 pipeline = Gst.parse_launch("tcambin name=bin"
32 " ! capsfilter name=filter"
33 " ! videoconvert"
34 " ! ximagesink")
35
36 # serial is defined, thus make the source open that device
37 if serial:
38 # retrieve the bin element from the pipeline
39 camera = pipeline.get_by_name("bin")
40 camera.set_property("serial", serial)
41
42 caps = Gst.Caps.new_empty()
43
44 structure = Gst.Structure.new_from_string("video/x-raw")
45 structure.set_value("width", 640)
46 structure.set_value("height", 480)
47
48 try:
49 fraction = Gst.Fraction(30, 1)
50 structure.set_value("framerate", fraction)
51 except TypeError:
52 struc_string = structure.to_string()
53
54 struc_string += ",framerate={}/{}".format(30, 1)
55 structure.free()
56 structure, end = structure.from_string(struc_string)
57
58 caps.append_structure(structure)
59
60 structure.free()
61 # structure is not useable from here on
62
63 capsfilter = pipeline.get_by_name("filter")
64
65 if not capsfilter:
66 print("Could not retrieve capsfilter from pipeline.")
67 return 1
68
69 capsfilter.set_property("caps", caps)
70
71 # to statically create caps you can reduce the whole procedure to
72 # caps = Gst.Caps.from_string("video/x-raw,format=BGRx,width=640,height=480,framerate=30/1");
73 #
74 # Gst.parse_lauch allows you to use strings for caps descriptions.
75 # That means everything until now can be done with:
76 #
77 # pipeline = Gst.parse_launch("tcambin name=source"
78 # " ! video/x-raw,format=BGRx,width=640,height=480,framerate=30/1"
79 # " ! videoconvert ! ximagesink");
80
81 pipeline.set_state(Gst.State.PLAYING)
82
83 print("Press Ctrl-C to stop.")
84
85 # We wait with this thread until a
86 # KeyboardInterrupt in the form of a Ctrl-C
87 # arrives. This will cause the pipline
88 # to be set to state NULL
89 try:
90 while True:
91 time.sleep(1)
92 except KeyboardInterrupt:
93 pass
94 finally:
95 pipeline.set_state(Gst.State.NULL)
96
97 return 0
98
99
100if __name__ == "__main__":
101 sys.exit(main())
06 - softwaretrigger¶
Triggers single images - instead of a continuous image stream.
Show sample code
1
2/* This example will show you how to trigger images */
3
4#include <gst/gst.h>
5#include <stdio.h> /* printf */
6#include <tcam-property-1.0.h>
7#include <unistd.h> /* sleep */
8
9
10int main(int argc, char* argv[])
11{
12 /* this line sets the gstreamer default logging level
13 it can be removed in normal applications
14 gstreamer logging can contain verry useful information
15 when debugging your application
16 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
17 for further details
18 */
19 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
20
21 gst_init(&argc, &argv); // init gstreamer
22
23 const char* serial = NULL; // the serial number of the camera we want to use
24
25 GError* err = NULL;
26
27 GstElement* pipeline =
28 gst_parse_launch("tcambin name=source ! video/x-raw,format=BGRx ! videoconvert ! ximagesink ", &err);
29
30 /* test for error */
31 if (pipeline == NULL)
32 {
33 printf("Could not create pipeline. Cause: %s\n", err->message);
34 return 1;
35 }
36
37 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
38
39 if (serial != NULL)
40 {
41 GValue val = {};
42 g_value_init(&val, G_TYPE_STRING);
43 g_value_set_static_string(&val, serial);
44
45 g_object_set_property(G_OBJECT(source), "serial", &val);
46
47 g_value_unset(&val);
48 }
49
50 gst_element_set_state(pipeline, GST_STATE_PLAYING);
51
52 /*
53 This sleep exists only to ensure
54 that a live image exists before trigger mode is activated.
55 for all other purposes this can be removed.
56 */
57 sleep(2);
58
59 tcam_property_provider_set_tcam_enumeration(TCAM_PROPERTY_PROVIDER(source), "TriggerMode", "On", &err);
60
61 if (err)
62 {
63 printf("Error while setting trigger mode: %s\n", err->message);
64 g_error_free(err);
65 err = NULL;
66 }
67
68 while (0 == 0)
69 {
70 printf("Press 'q' then 'enter' to stop the stream.\n");
71 printf("Press 'Enter' to trigger a new image.\n");
72
73 char c = getchar();
74
75 if (c == 'q')
76 {
77 break;
78 }
79
80 tcam_property_provider_set_tcam_command(TCAM_PROPERTY_PROVIDER(source), "TriggerSoftware", &err);
81 if (err)
82 {
83 printf("!!! Could not trigger. !!!\n");
84 printf("Error while setting trigger: %s\n", err->message);
85 g_error_free(err);
86 err = NULL;
87 }
88 else
89 {
90 printf("=== Triggered image. ===\n");
91 }
92 }
93
94 /* deactivate trigger mode */
95 /* this is simply to prevent confusion when the camera ist started without wanting to trigger */
96 tcam_property_provider_set_tcam_enumeration(TCAM_PROPERTY_PROVIDER(source), "TriggerMode", "Off", &err);
97
98 // this stops the pipeline and frees all resources
99 gst_element_set_state(pipeline, GST_STATE_NULL);
100
101 gst_object_unref(source);
102 /* the pipeline automatically handles all elements that have been added to it.
103 thus they do not have to be cleaned up manually */
104 gst_object_unref(pipeline);
105
106 return 0;
107}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to enable trigger-mode
5# and how to trigger images with via software trigger.
6#
7
8import sys
9import gi
10import time
11
12gi.require_version("Tcam", "1.0")
13gi.require_version("Gst", "1.0")
14gi.require_version("GLib", "2.0")
15
16from gi.repository import Tcam, Gst, GLib
17
18
19def main():
20
21 Gst.init(sys.argv) # init gstreamer
22
23 # this line sets the gstreamer default logging level
24 # it can be removed in normal applications
25 # gstreamer logging can contain verry useful information
26 # when debugging your application
27 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
28 # for further details
29 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
30
31 serial = None
32
33 pipeline = Gst.parse_launch("tcambin name=source ! videoconvert ! ximagesink")
34
35 source = pipeline.get_by_name("source")
36
37 # serial is defined, thus make the source open that device
38 if serial is not None:
39 source.set_property("serial", serial)
40
41 pipeline.set_state(Gst.State.PLAYING)
42
43 # stream for 2 seconds before switching to trigger mode
44 # this is simply to show that the device is running
45 time.sleep(2)
46
47 try:
48 source.set_tcam_enumeration("TriggerMode", "On")
49
50 wait = True
51 while wait:
52 input_text = input("Press 'Enter' to trigger an image.\n q + enter to stop the stream.")
53 if input_text == "q":
54 break
55 else:
56 ret = source.set_tcam_command("TriggerSoftware")
57
58 if ret:
59 print("=== Triggered image. ===\n")
60 else:
61 print("!!! Could not trigger. !!!\n")
62
63 # deactivate trigger mode
64 # this is simply to prevent confusion when the camera ist started without wanting to trigger
65 source.set_tcam_enumeration("TriggerMode", "Off")
66
67 except GLib.Error as e:
68
69 print(e.message)
70
71 # this stops the pipeline and frees all resources
72 pipeline.set_state(Gst.State.NULL)
73
74
75if __name__ == "__main__":
76 main()
07 - appsink¶
Receives images in an application instead of just showing them.
Show sample code
1
2/*
3 This example will show you how to receive data
4 from gstreamer in your application
5 and how to get the actual image data
6*/
7
8#include <gst/gst.h>
9#include <gst/video/video.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
14
15
16/*
17 This function will be called in a separate thread when our appsink
18 says there is data for us. user_data has to be defined
19 when calling g_signal_connect. It can be used to pass objects etc.
20 from your other function to the callback.
21
22 user_data can point to additional data for your usage
23 marked as unused to prevent compiler warnings
24*/
25static GstFlowReturn callback(GstElement* sink, void* user_data __attribute__((unused)))
26{
27 GstSample* sample = NULL;
28 /* Retrieve the buffer */
29 g_signal_emit_by_name(sink, "pull-sample", &sample, NULL);
30
31 if (sample)
32 {
33 // we have a valid sample
34 // do things with the image here
35 static guint framecount = 0;
36 int pixel_data = -1;
37
38 GstBuffer* buffer = gst_sample_get_buffer(sample);
39 GstMapInfo info; // contains the actual image
40 if (gst_buffer_map(buffer, &info, GST_MAP_READ))
41 {
42 GstVideoInfo* video_info = gst_video_info_new();
43 if (!gst_video_info_from_caps(video_info, gst_sample_get_caps(sample)))
44 {
45 // Could not parse video info (should not happen)
46 g_warning("Failed to parse video info");
47 return GST_FLOW_ERROR;
48 }
49
50 // pointer to the image data
51
52 // unsigned char* data = info.data;
53
54 // Get the pixel value of the center pixel
55
56 // int stride = video_info->finfo->bits / 8;
57 // unsigned int pixel_offset = video_info->width / 2 * stride
58 // + video_info->width * video_info->height / 2 * stride;
59
60 // this is only one pixel
61 // when dealing with formats like BGRx
62 // pixel_data will consist out of
63 // pixel_offset => B
64 // pixel_offset+1 => G
65 // pixel_offset+2 => R
66 // pixel_offset+3 => x
67
68 // pixel_data = info.data[pixel_offset];
69
70 gst_buffer_unmap(buffer, &info);
71 gst_video_info_free(video_info);
72 }
73
74 GstClockTime timestamp = GST_BUFFER_PTS(buffer);
75 g_print("Captured frame %d, Pixel Value=%03d Timestamp=%" GST_TIME_FORMAT " \r",
76 framecount,
77 pixel_data,
78 GST_TIME_ARGS(timestamp));
79 framecount++;
80
81
82 // delete our reference so that gstreamer can handle the sample
83 gst_sample_unref(sample);
84 }
85 return GST_FLOW_OK;
86}
87
88
89int main(int argc, char* argv[])
90{
91 /* this line sets the gstreamer default logging level
92 it can be removed in normal applications
93 gstreamer logging can contain verry useful information
94 when debugging your application
95 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
96 for further details
97 */
98 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
99
100 gst_init(&argc, &argv);
101
102 const char* serial = NULL; // the serial number of the camera we want to use
103
104 const char* pipeline_str = "tcambin name=source ! videoconvert ! appsink name=sink";
105
106 GError* err = NULL;
107 GstElement* pipeline = gst_parse_launch(pipeline_str, &err);
108
109 /* test for error */
110 if (pipeline == NULL)
111 {
112 printf("Could not create pipeline. Cause: %s\n", err->message);
113 return 1;
114 }
115
116 if (serial != NULL)
117 {
118 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
119
120 GValue val = {};
121 g_value_init(&val, G_TYPE_STRING);
122 g_value_set_static_string(&val, serial);
123
124 g_object_set_property(G_OBJECT(source), "serial", &val);
125 gst_object_unref(source);
126 }
127
128 /* retrieve the appsink from the pipeline */
129 GstElement* sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");
130
131 // tell appsink to notify us when it receives an image
132 g_object_set(G_OBJECT(sink), "emit-signals", TRUE, NULL);
133
134 // tell appsink what function to call when it notifies us
135 g_signal_connect(sink, "new-sample", G_CALLBACK(callback), NULL);
136
137 gst_object_unref(sink);
138
139 gst_element_set_state(pipeline, GST_STATE_PLAYING);
140
141 g_print("Press 'enter' to stop the stream.\n");
142 /* wait for user input to end the program */
143 getchar();
144
145 // this stops the pipeline and frees all resources
146 gst_element_set_state(pipeline, GST_STATE_NULL);
147
148 /*
149 the pipeline automatically handles
150 all elements that have been added to it.
151 thus they do not have to be cleaned up manually
152 */
153 gst_object_unref(pipeline);
154
155 return 0;
156}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to enable trigger-mode
5# and how to trigger images with via software trigger.
6#
7
8
9import sys
10import gi
11import time
12
13gi.require_version("Gst", "1.0")
14gi.require_version("GstVideo", "1.0")
15
16from gi.repository import Gst, GstVideo
17
18framecount = 0
19
20
21def callback(appsink, user_data):
22 """
23 This function will be called in a separate thread when our appsink
24 says there is data for us. user_data has to be defined
25 when calling g_signal_connect. It can be used to pass objects etc.
26 from your other function to the callback.
27 """
28 sample = appsink.emit("pull-sample")
29
30 if sample:
31
32 caps = sample.get_caps()
33
34 gst_buffer = sample.get_buffer()
35
36 try:
37 (ret, buffer_map) = gst_buffer.map(Gst.MapFlags.READ)
38
39 video_info = GstVideo.VideoInfo()
40 video_info.from_caps(caps)
41
42 stride = video_info.finfo.bits / 8
43
44 pixel_offset = int(video_info.width / 2 * stride +
45 video_info.width * video_info.height / 2 * stride)
46
47 # this is only one pixel
48 # when dealing with formats like BGRx
49 # pixel_data will have to consist out of
50 # pixel_offset => B
51 # pixel_offset+1 => G
52 # pixel_offset+2 => R
53 # pixel_offset+3 => x
54 pixel_data = buffer_map.data[pixel_offset]
55 timestamp = gst_buffer.pts
56
57 global framecount
58
59 output_str = "Captured frame {}, Pixel Value={} Timestamp={}".format(framecount,
60 pixel_data,
61 timestamp)
62
63 print(output_str, end="\r") # print with \r to rewrite line
64
65 framecount += 1
66
67 finally:
68 gst_buffer.unmap(buffer_map)
69
70 return Gst.FlowReturn.OK
71
72
73def main():
74
75 Gst.init(sys.argv) # init gstreamer
76
77 # this line sets the gstreamer default logging level
78 # it can be removed in normal applications
79 # gstreamer logging can contain verry useful information
80 # when debugging your application
81 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
82 # for further details
83 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
84
85 serial = None
86
87 pipeline = Gst.parse_launch("tcambin name=source"
88 " ! videoconvert"
89 " ! appsink name=sink")
90
91 # test for error
92 if not pipeline:
93 print("Could not create pipeline.")
94 sys.exit(1)
95
96 # The user has not given a serial, so we prompt for one
97 if serial is not None:
98 source = pipeline.get_by_name("source")
99 source.set_property("serial", serial)
100
101 sink = pipeline.get_by_name("sink")
102
103 # tell appsink to notify us when it receives an image
104 sink.set_property("emit-signals", True)
105
106 user_data = "This is our user data"
107
108 # tell appsink what function to call when it notifies us
109 sink.connect("new-sample", callback, user_data)
110
111 pipeline.set_state(Gst.State.PLAYING)
112
113 print("Press Ctrl-C to stop.")
114
115 # We wait with this thread until a
116 # KeyboardInterrupt in the form of a Ctrl-C
117 # arrives. This will cause the pipline
118 # to be set to state NULL
119 try:
120 while True:
121 time.sleep(1)
122 except KeyboardInterrupt:
123 pass
124 finally:
125 pipeline.set_state(Gst.State.NULL)
126
127
128if __name__ == "__main__":
129 main()
08 - save-stream¶
Stores a stream in a file.
Show sample code
1
2/* This example will show you how to save a videostream into a file */
3
4#include <gst/gst.h>
5#include <stdio.h>
6#include <string.h>
7
8int main(int argc, char* argv[])
9{
10 /* this line sets the gstreamer default logging level
11 it can be removed in normal applications
12 gstreamer logging can contain verry useful information
13 when debugging your application
14 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
15 for further details
16 */
17 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
18
19 gst_init(&argc, &argv); // init gstreamer
20
21 const char* serial = NULL; // the serial number of the camera we want to use
22
23 GError* err = NULL;
24
25
26 GstElement* pipeline =
27 gst_parse_launch("tcambin name=bin"
28 " ! video/x-raw,format=BGRx,width=640,height=480,framerate=30/1"
29 " ! tee name=t"
30 " ! queue"
31 " ! videoconvert"
32 " ! ximagesink"
33 " t."
34 " ! queue"
35 " ! videoconvert"
36 " ! avimux"
37 " ! filesink name=fsink",
38 &err);
39 /*
40 to save a video without live view reduce the pipeline to the following:
41
42 GstElement* pipeline = Gst.parse_launch("tcambin name=bin"
43 " ! video/x-raw,format=BGRx,width=640,height=480,framerate=30/1"
44 " ! videoconvert"
45 " ! avimux"
46 " ! filesink name=fsink", &err);
47
48 */
49
50 if (serial != NULL)
51 {
52 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "bin");
53 GValue val = {};
54 g_value_init(&val, G_TYPE_STRING);
55 g_value_set_static_string(&val, serial);
56
57 g_object_set_property(G_OBJECT(source), "serial", &val);
58 gst_object_unref(source);
59 }
60
61 const char* file_location = "/tmp/tiscamera-save-stream.avi";
62
63 GstElement* fsink = gst_bin_get_by_name(GST_BIN(pipeline), "fsink");
64
65 g_object_set(G_OBJECT(fsink), "location", file_location, NULL);
66
67 gst_element_set_state(pipeline, GST_STATE_PLAYING);
68
69 printf("Press Enter to stop the recording\n");
70 getchar();
71
72 // this stops the pipeline and frees all resources
73 gst_element_set_state(pipeline, GST_STATE_NULL);
74
75 gst_object_unref(fsink);
76
77 /* the pipeline automatically handles all elements that have been added to it.
78 thus they do not have to be cleaned up manually */
79 gst_object_unref(pipeline);
80
81 printf("Stream saved to: %s\n", file_location);
82
83 return 0;
84}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to save a video stream to a file
5#
6
7import time
8import sys
9import gi
10
11gi.require_version("Gst", "1.0")
12
13from gi.repository import Gst
14
15
16def main():
17
18 Gst.init(sys.argv) # init gstreamer
19
20 # this line sets the gstreamer default logging level
21 # it can be removed in normal applications
22 # gstreamer logging can contain verry useful information
23 # when debugging your application
24 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
25 # for further details
26 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
27
28 serial = None
29
30 pipeline = Gst.parse_launch("tcambin name=bin"
31 " ! video/x-raw,format=BGRx,width=640,height=480,framerate=30/1"
32 " ! tee name=t"
33 " ! queue"
34 " ! videoconvert"
35 " ! ximagesink"
36 " t."
37 " ! queue"
38 " ! videoconvert"
39 " ! avimux"
40 " ! filesink name=fsink")
41
42 # to save a video without live view reduce the pipeline to the following:
43
44 # pipeline = Gst.parse_launch("tcambin name=bin"
45 # " ! video/x-raw,format=BGRx,width=640,height=480,framerate=30/1"
46 # " ! videoconvert"
47 # " ! avimux"
48 # " ! filesink name=fsink")
49
50 # serial is defined, thus make the source open that device
51 if serial is not None:
52 camera = pipeline.get_by_name("bin")
53 camera.set_property("serial", serial)
54
55 file_location = "/tmp/tiscamera-save-stream.avi"
56
57 fsink = pipeline.get_by_name("fsink")
58 fsink.set_property("location", file_location)
59
60 pipeline.set_state(Gst.State.PLAYING)
61
62 print("Press Ctrl-C to stop.")
63
64 try:
65 while True:
66 time.sleep(1)
67 except KeyboardInterrupt:
68 pass
69 finally:
70 pipeline.set_state(Gst.State.NULL)
71
72
73if __name__ == "__main__":
74 main()
09 - device-lost¶
Receives device-lost and other messages and react to them.
Show sample code
1
2/* This example will show you how to start a live stream from your camera */
3
4#include <gst/gst.h>
5#include <stdio.h> /* printf and putchar */
6#include <unistd.h> /* usleep */
7
8
9static GMainLoop* loop;
10
11
12static gboolean starts_with(const char* a, const char* b)
13{
14 if (strncmp(a, b, strlen(b)) == 0)
15 {
16 return 1;
17 }
18 return 0;
19}
20
21
22static gboolean bus_callback(GstBus* bus __attribute__((unused)), GstMessage* message, gpointer data __attribute__((unused)))
23{
24 g_print("Got %s message\n", GST_MESSAGE_TYPE_NAME(message));
25
26 switch (GST_MESSAGE_TYPE(message))
27 {
28 case GST_MESSAGE_ERROR:
29 {
30 GError* err;
31 gchar* debug;
32
33 gst_message_parse_error(message, &err, &debug);
34 g_print("Error: %s \n", err->message);
35
36 if (starts_with(err->message, "Device lost ("))
37 {
38 char* s_str = strstr(err->message, "(");
39 const char* serial = strtok(s_str, "()");
40 printf("Device lost came from device with serial = %s\n", serial);
41
42 // device lost handling should be initiated here
43 // this example simply stops playback
44 g_main_loop_quit(loop);
45 }
46
47 g_error_free(err);
48 g_free(debug);
49
50 break;
51 }
52 case GST_MESSAGE_INFO:
53 {
54 break;
55 }
56 case GST_MESSAGE_EOS:
57 {
58 /* end-of-stream */
59 g_main_loop_quit(loop);
60 break;
61 }
62 default:
63 {
64 /* unhandled message */
65 break;
66 }
67 }
68 return TRUE;
69}
70
71
72int main(int argc, char* argv[])
73{
74 /* this line sets the gstreamer default logging level
75 it can be removed in normal applications
76 gstreamer logging can contain verry useful information
77 when debugging your application
78 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
79 for further details
80 */
81 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
82
83 gst_init(&argc, &argv); // init gstreamer
84
85 const char* serial = NULL; // set this if you do not want the first found device
86
87 GError* err = NULL;
88
89 GstElement* pipeline =
90 gst_parse_launch("tcambin name=source ! videoconvert ! ximagesink", &err);
91
92 /* test for error */
93 if (pipeline == NULL)
94 {
95 printf("Could not create pipeline. Cause: %s\n", err->message);
96 return 1;
97 }
98
99 if (serial != NULL)
100 {
101 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
102 GValue val = {};
103 g_value_init(&val, G_TYPE_STRING);
104 g_value_set_static_string(&val, serial);
105
106 g_object_set_property(G_OBJECT(source), "serial", &val);
107 gst_object_unref(source);
108 }
109
110 GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
111
112 gst_bus_add_watch(bus, bus_callback, NULL);
113
114 gst_object_unref(bus);
115
116
117 gst_element_set_state(pipeline, GST_STATE_PLAYING);
118
119 printf("Disconnect your camera to trigger a device lost or press enter to stop the stream.\n");
120
121 // we work with a event loop to be automatically
122 // notified when a new messages occur.
123 loop = g_main_loop_new(NULL, FALSE);
124 g_main_loop_run(loop);
125
126 g_main_loop_unref(loop);
127 gst_element_set_state(pipeline, GST_STATE_NULL);
128
129 gst_object_unref(pipeline);
130
131 return 0;
132}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to react to messages on the gstreamer bus.
5#
6
7import sys
8import re
9import gi
10
11gi.require_version("Gst", "1.0")
12
13from gi.repository import Gst, GLib
14
15
16loop = GLib.MainLoop()
17
18
19def bus_callback(bus, message, user_data):
20 """
21 Gstreamer Message Types and how to parse
22 https://lazka.github.io/pgi-docs/Gst-1.0/flags.html#Gst.MessageType
23 """
24 mtype = message.type
25
26 if mtype == Gst.MessageType.EOS:
27 # end-of-stream
28 loop.quit()
29 elif mtype == Gst.MessageType.ERROR:
30 # Handle Errors
31 err, debug = message.parse_error()
32 print(err, debug)
33
34 if err.message.startswith("Device lost ("):
35
36 m = re.search('Device lost \((.*)\)', err.message)
37 print("Device lost came from device with serial = {}".format(m.group(1)))
38
39 # device lost handling should be initiated here
40 # this example simply stops playback
41 loop.quit()
42
43 elif mtype == Gst.MessageType.WARNING:
44 # Handle warnings
45 err, debug = message.parse_warning()
46 print(err, debug)
47
48 return True
49
50
51def main():
52
53 Gst.init(sys.argv)
54
55 # this line sets the gstreamer default logging level
56 # it can be removed in normal applications
57 # gstreamer logging can contain verry useful information
58 # when debugging your application
59 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
60 # for further details
61 #Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
62
63 serial = None
64
65 pipeline = Gst.parse_launch("tcambin name=source ! videoconvert ! ximagesink sync=false")
66
67 if not pipeline:
68 print("Could not create pipeline")
69 sys.exit(1)
70
71 if serial:
72 src = pipeline.get_by_name("source")
73 src.set_property("serial", serial)
74 src = None
75
76 bus = pipeline.get_bus()
77 bus.add_signal_watch()
78 # bus.enable_sync_message_emission()
79 bus.connect('message', bus_callback, None)
80
81 # bus.add_watch(bus_callback, None)
82
83 pipeline.set_state(Gst.State.PLAYING)
84
85 print("Disconnect your camera to trigger a device lost or press enter to stop the stream.")
86
87 # we work with a event loop to be automatically
88 # be notified when new messages occur.
89 loop.run()
90
91 pipeline.set_state(Gst.State.NULL)
92
93
94if __name__ == "__main__":
95 main()
10 - metadata¶
Read meta information like is-damaged, camera capture time, etc.
Show sample code
1
2/* This example will show you how to receive data from gstreamer in your application
3 and how to get the actual iamge data */
4
5#include "gstmetatcamstatistics.h"
6#include "tcam-property-1.0.h" /* gobject introspection interface */
7
8#include <gst/gst.h>
9#include <gst/video/video.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
14
15
16static gboolean meta_struc_print(GQuark field_id, const GValue* value, gpointer user_data __attribute__((unused)))
17{
18 // GQuark is a gobject internal ID for strings
19 // we call the function g_quark_to_string to get the name of the field
20 // value is a simple, generic value
21 // user_data can contain things you need for further processing
22
23 printf("%s: ", g_quark_to_string(field_id));
24
25 if (G_VALUE_TYPE(value) == G_TYPE_BOOLEAN)
26 {
27 gboolean val = g_value_get_boolean(value);
28 if (val)
29 {
30 printf(" true\n");
31 }
32 else
33 {
34 printf(" false\n");
35 }
36 }
37 else if (G_VALUE_TYPE(value) == G_TYPE_DOUBLE)
38 {
39 double val = g_value_get_double(value);
40 printf("%f\n", val);
41 }
42 else if (G_VALUE_TYPE(value) == G_TYPE_UINT64)
43 {
44 guint64 val = g_value_get_uint64(value);
45 printf("%lu\n", val);
46 }
47 else
48 {
49 printf("value type not implemented\n");
50 }
51
52 return TRUE;
53}
54
55/*
56 This function will be called in a separate thread when our appsink
57 says there is data for us. user_data has to be defined when calling g_signal_connect.
58 */
59static GstFlowReturn callback(GstElement* sink, void* user_data __attribute__((unused)))
60{
61 printf("new sample\n");
62
63 GstSample* sample = NULL;
64 /* Retrieve the buffer */
65 g_signal_emit_by_name(sink, "pull-sample", &sample, NULL);
66
67 if (sample)
68 {
69 static guint framecount = 0;
70
71 framecount++;
72
73 GstBuffer* buffer = gst_sample_get_buffer(sample);
74
75 // if you need the associated caps
76 // GstCaps* c = gst_sample_get_caps(sample);
77
78 GstMeta* meta = gst_buffer_get_meta(buffer, g_type_from_name("TcamStatisticsMetaApi"));
79
80 if (meta)
81 {
82 printf("We have meta\n");
83 }
84 else
85 {
86 g_warning("No meta data available\n");
87 }
88
89 GstStructure* struc = ((TcamStatisticsMeta*)meta)->structure;
90
91 // this prints all contained fields
92 gst_structure_foreach(struc, meta_struc_print, NULL);
93
94 // to only print selective fields
95 // read the documentation
96 // https://www.theimagingsource.com/documentation/tiscamera/tcam-gstreamer.html#metadata
97 // concerning available fields and call them manually by name
98
99 /*
100 guint64 frame_count = 0;
101 gst_structure_get_uint64(struc, "frame_count", &frame_count);
102 printf("frame_count: %ul\n", frame_count);
103 */
104
105 // delete our reference so that gstreamer can handle the sample
106 gst_sample_unref(sample);
107 }
108 return GST_FLOW_OK;
109}
110
111
112int main(int argc, char* argv[])
113{
114 /* this line sets the gstreamer default logging level
115 it can be removed in normal applications
116 gstreamer logging can contain verry useful information
117 when debugging your application
118 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
119 for further details
120 */
121 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
122
123 gst_init(&argc, &argv);
124
125 const char* serial = NULL; // set this if you do not want the first found device
126
127 GError* err = NULL;
128
129 // some conversion elements will drop the metadata
130 // for the sake of this example we will retrieve buffers
131 // directly from the src
132 const char* pipeline_str = "tcamsrc name=source ! appsink name=sink";
133
134 GstElement* pipeline = gst_parse_launch(pipeline_str, &err);
135
136 /* test for error */
137 if (pipeline == NULL)
138 {
139 printf("Could not create pipeline. Cause: %s\n", err->message);
140 return 1;
141 }
142
143 if (serial != NULL)
144 {
145 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
146 GValue val = {};
147 g_value_init(&val, G_TYPE_STRING);
148 g_value_set_static_string(&val, serial);
149
150 g_object_set_property(G_OBJECT(source), "serial", &val);
151 gst_object_unref(source);
152 }
153
154 /* retrieve the appsink from the pipeline */
155 GstElement* sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");
156
157 // tell appsink to notify us when it receives an image
158 g_object_set(G_OBJECT(sink), "emit-signals", TRUE, NULL);
159
160 // tell appsink what function to call when it notifies us
161 g_signal_connect(sink, "new-sample", G_CALLBACK(callback), NULL);
162
163 gst_object_unref(sink);
164
165 gst_element_set_state(pipeline, GST_STATE_PLAYING);
166
167 g_print("Press 'enter' to stop the stream.\n");
168 /* wait for user input to end the program */
169 getchar();
170
171 // this stops the pipeline and frees all resources
172 gst_element_set_state(pipeline, GST_STATE_NULL);
173
174 /*
175 the pipeline automatically handles
176 all elements that have been added to it.
177 thus they do not have to be cleaned up manually
178 */
179 gst_object_unref(pipeline);
180
181 return 0;
182}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to enable trigger-mode
5# and how to trigger images with via software trigger.
6#
7
8import sys
9import gi
10import time
11import ctypes
12
13gi.require_version("Gst", "1.0")
14gi.require_version("GstVideo", "1.0")
15gi.require_version("GObject", "2.0")
16gi.require_version("GLib", "2.0")
17
18from gi.repository import Gst, GstVideo, GObject, GLib
19
20# workaround for missing GstMeta apis
21
22# load tiscamera GstMeta library
23clib = ctypes.CDLL("../../build/lib/libgsttcamstatistics.so")
24
25# declare input/output type for our helper function
26clib.tcam_statistics_get_structure.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_size_t]
27clib.tcam_statistics_get_structure.restype = ctypes.c_bool
28
29# allocate a c-string with length 320 bytes
30# this _should_ be long enough to hold any
31# GstStructure string that will be retrieved
32# if not change this to a higher number
33meta_out_buffer_size = 320
34meta_out_buffer = ctypes.create_string_buffer(meta_out_buffer_size)
35
36
37def get_meta(gst_buffer):
38 """
39 Check Gst.Buffer for a valid Gst.Meta object
40 and return the contained Gst.Structure
41
42 Parameters:
43 Gst.Buffer
44
45 Returns:
46 Gst.Structure or None in case of error
47 """
48 meta = gst_buffer.get_meta("TcamStatisticsMetaApi")
49
50 if not meta:
51 return None
52
53 # fill meta_out_buffer with the result of gst_structure_get_string(meta->structure)
54 ret = clib.tcam_statistics_get_structure(hash(meta), meta_out_buffer, meta_out_buffer_size)
55
56 # ret is a bool indicating successfull string copy
57 if ret:
58 # ret is bytecode
59 # decode it to get a valide str object
60 # ret.decode("utf-8")
61 structure_string = ctypes.string_at(meta_out_buffer).decode("utf-8")
62 struc = Gst.Structure.from_string(structure_string)
63 # Gst.Structure.from_string returns a tuple
64 # we only want the actual Gst.Structure
65 return struc[0]
66 return None
67
68
69def callback(appsink, user_data):
70 """
71 This function will be called in a separate thread when our appsink
72 says there is data for us. user_data has to be defined
73 when calling g_signal_connect. It can be used to pass objects etc.
74 from your other function to the callback.
75 """
76 sample = appsink.emit("pull-sample")
77
78 if sample:
79 print("new sample")
80 # caps = sample.get_caps()
81
82 gst_buffer = sample.get_buffer()
83
84 tcam_meta = get_meta(gst_buffer)
85 if tcam_meta:
86
87 def print_structure(field_id, value, user_data):
88 """
89 """
90
91 name = GLib.quark_to_string(field_id)
92
93 print(f"{name} => {value}")
94
95 # return true as we want to continue iterating
96 return True
97
98 # call print structure for all members of the Gst.Structure
99 tcam_meta.foreach(print_structure, None)
100
101 else:
102 print("No meta")
103
104 # empty line for more readability
105 print("")
106
107 return Gst.FlowReturn.OK
108
109
110def main():
111
112 Gst.init(sys.argv)
113 serial = None
114
115 pipeline = Gst.parse_launch("tcambin name=source"
116 " ! appsink name=sink")
117
118 # test for error
119 if not pipeline:
120 print("Could not create pipeline.")
121 sys.exit(1)
122
123 # The user has not given a serial, so we prompt for one
124 if serial is not None:
125 source = pipeline.get_by_name("source")
126 source.set_property("serial", serial)
127
128 sink = pipeline.get_by_name("sink")
129
130 # tell appsink to notify us when it receives an image
131 sink.set_property("emit-signals", True)
132
133 user_data = "This is our user data"
134
135 # tell appsink what function to call when it notifies us
136 sink.connect("new-sample", callback, user_data)
137
138 pipeline.set_state(Gst.State.PLAYING)
139
140 print("Press Ctrl-C to stop.")
141
142 # We wait with this thread until a
143 # KeyboardInterrupt in the form of a Ctrl-C
144 # arrives. This will cause the pipline
145 # to be set to state NULL
146 try:
147 while True:
148 time.sleep(1)
149 except KeyboardInterrupt:
150 pass
151 finally:
152 pipeline.set_state(Gst.State.NULL)
153
154
155if __name__ == "__main__":
156 main()
11 - json-state¶
Save and load JSON device state.
Show sample code
1
2/* This example will show you how to get/set the JSON property description for a certain camera */
3
4#include "tcam-property-1.0.h" /* gobject introspection interface */
5
6#include <gst/gst.h>
7#include <stdio.h> /* printf and putchar */
8
9
10gboolean block_until_playing(GstElement* pipeline)
11{
12 while (TRUE)
13 {
14 GstState state;
15 GstState pending;
16
17 // wait 0.1 seconds for something to happen
18 GstStateChangeReturn ret = gst_element_get_state(pipeline, &state, &pending, 100000000);
19
20 if (ret == GST_STATE_CHANGE_SUCCESS)
21 {
22 return TRUE;
23 }
24 else if (ret == GST_STATE_CHANGE_FAILURE)
25 {
26 printf("Failed to change state %s %s %s\n",
27 gst_element_state_change_return_get_name(ret),
28 gst_element_state_get_name(state),
29 gst_element_state_get_name(pending));
30
31 return FALSE;
32 }
33 }
34}
35
36
37int main(int argc, char* argv[])
38{
39 /* this line sets the gstreamer default logging level
40 it can be removed in normal applications
41 gstreamer logging can contain verry useful information
42 when debugging your application
43 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
44 for further details
45 */
46 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
47
48 gst_init(&argc, &argv); // init gstreamer
49
50 GError* err = NULL;
51
52 // this is a placeholder definition
53 // normally your pipeline would be defined here
54 GstElement* pipeline = gst_parse_launch("tcambin name=source ! fakesink", &err);
55
56 if (pipeline == NULL)
57 {
58 printf("Unable to create pipeline: %s\n", err->message);
59 g_free(err);
60 return 1;
61 }
62
63 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
64
65 const char* serial = NULL;
66
67 if (serial != NULL)
68 {
69 GValue val = {};
70 g_value_init(&val, G_TYPE_STRING);
71 g_value_set_static_string(&val, serial);
72
73 g_object_set_property(G_OBJECT(source), "serial", &val);
74 }
75
76 // in the READY state the camera will always be initialized
77 // in the PLAYING state additional properties may appear from gstreamer elements
78 gst_element_set_state(source, GST_STATE_PLAYING);
79
80 // helper function to ensure we have the right state
81 // alternatively wait for the first image
82 if (!block_until_playing(pipeline))
83 {
84 printf("Unable to start pipeline. \n");
85 }
86
87 // Device is now in a state for interactions
88 GValue state = G_VALUE_INIT;
89 g_value_init(&state, G_TYPE_STRING);
90
91 //We print the properties for a before/after comparison,
92 g_object_get_property(G_OBJECT(source), "tcam-properties-json", &state);
93
94 printf("State of device is:\n%s", g_value_get_string(&state));
95
96 // Change JSON description here
97 // not part of this example
98
99 // second print for the before/after comparison
100 g_object_set_property(G_OBJECT(source), "tcam-properties-json", &state);
101
102 //reread state to see if anything changed
103 g_object_get_property(G_OBJECT(source), "tcam-properties-json", &state);
104
105 printf("State of device is:\n%s", g_value_get_string(&state));
106
107 // cleanup, reset state
108 gst_element_set_state(source, GST_STATE_NULL);
109
110 gst_object_unref(source);
111 gst_object_unref(pipeline);
112 g_value_unset(&state);
113
114 return 0;
115}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to set properties
5#
6
7import sys
8import gi
9
10gi.require_version("Gst", "1.0")
11
12from gi.repository import Gst
13
14
15def block_until_playing(pipeline):
16
17 while True:
18 # wait 0.1 seconds for something to happen
19 change_return, state, pending = pipeline.get_state(100000000)
20 if change_return == Gst.StateChangeReturn.SUCCESS:
21 return True
22 elif change_return == Gst.StateChangeReturn.FAILURE:
23 print("Failed to change state {} {} {}".format(change_return,
24 state,
25 pending))
26 return False
27
28
29def main():
30
31 Gst.init(sys.argv)
32
33 # this line sets the gstreamer default logging level
34 # it can be removed in normal applications
35 # gstreamer logging can contain verry useful information
36 # when debugging your application
37 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
38 # for further details
39 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
40
41 pipeline = Gst.parse_launch("tcambin name=source ! fakesink")
42
43 if not pipeline:
44 print("Unable to create pipeline")
45 return 1
46
47 # Set this to a serial string for a specific camera
48 serial = None
49
50 camera = pipeline.get_by_name("source")
51
52 if serial:
53 # This is gstreamer set_property
54 camera.set_property("serial", serial)
55
56 # in the READY state the camera will always be initialized
57 # in the PLAYING state additional properties may appear from gstreamer elements
58 pipeline.set_state(Gst.State.PLAYING)
59
60 if not block_until_playing(pipeline):
61 print("Unable to start pipeline")
62
63 # Print properties for a before/after comparison
64 state = camera.get_property("tcam-properties-json")
65
66 print(f"State of device is:\n{state}")
67
68 # Change JSON description here
69 # not part of this example
70
71 camera.set_property("tcam-properties-json", state)
72
73 # Print properties for a before/after comparison
74 state = camera.get_property("tcam-properties-json")
75 print(f"State of device is:\n{state}")
76
77 # cleanup, reset state
78 pipeline.set_state(Gst.State.NULL)
79
80
81if __name__ == "__main__":
82 sys.exit(main())
12 - tcam-properties¶
Save and load properties via GstStructure.
Show sample code
1
2/* This example will show you how to get/set the properties through a description string */
3
4#include <gst/gst.h>
5#include <stdio.h> /* printf and putchar */
6
7
8gboolean block_until_state_change_done (GstElement* pipeline)
9{
10 while (TRUE)
11 {
12 GstState state;
13 GstState pending;
14
15 // wait 0.1 seconds for something to happen
16 GstStateChangeReturn ret = gst_element_get_state(pipeline, &state, &pending, 100000000);
17
18 if (ret == GST_STATE_CHANGE_SUCCESS || ret == GST_STATE_CHANGE_NO_PREROLL)
19 {
20 return TRUE;
21 }
22 else if (ret == GST_STATE_CHANGE_FAILURE)
23 {
24 printf("Failed to change state %s %s %s\n",
25 gst_element_state_change_return_get_name(ret),
26 gst_element_state_get_name(state),
27 gst_element_state_get_name(pending));
28
29 return FALSE;
30 }
31 }
32}
33
34
35static void print_current_properties (GstElement* source)
36{
37 // Initialize the GValue
38 GValue current_properties = G_VALUE_INIT;
39 g_value_init(¤t_properties, GST_TYPE_STRUCTURE);
40
41 // Get the GObject property
42 g_object_get_property(G_OBJECT(source), "tcam-properties", ¤t_properties);
43
44 // get a string to print the current property state
45 char* string = gst_structure_to_string(gst_value_get_structure(¤t_properties));
46 printf("Current properties:\n%s\n", string );
47 g_free(string); // free the string
48
49 g_value_unset( ¤t_properties ); // free the GstStructure in the GValue
50}
51
52
53int main (int argc, char* argv[])
54{
55 /* this line sets the gstreamer default logging level
56 it can be removed in normal applications
57 gstreamer logging can contain very useful information
58 when debugging your application
59 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
60 for further details
61 */
62 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
63
64 gst_init(&argc, &argv); // init gstreamer
65
66 GError* err = NULL;
67
68 // this is a placeholder definition
69 // normally your pipeline would be defined here
70 GstElement* pipeline = gst_parse_launch("tcambin name=source ! fakesink", &err);
71
72 if (pipeline == NULL)
73 {
74 printf("Unable to create pipeline: %s\n", err->message);
75 g_free(err);
76 return 1;
77 }
78
79 GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline), "source");
80
81 const char* serial = NULL;
82
83 if (serial != NULL)
84 {
85 GValue val = G_VALUE_INIT;
86 g_value_init(&val, G_TYPE_STRING);
87 g_value_set_static_string(&val, serial);
88
89 g_object_set_property(G_OBJECT(source), "serial", &val);
90 }
91
92 // in the READY state the camera will always be initialized
93 gst_element_set_state(source, GST_STATE_READY);
94
95 // helper function to wait for async state change to be done
96 if (!block_until_state_change_done(pipeline))
97 {
98 printf("Unable to start pipeline. \n");
99 return 2;
100 }
101
102 print_current_properties( source );
103
104 // Create a new structure
105 GstStructure* new_property_struct = gst_structure_new_empty("tcam");
106
107 // Change 2 properties so that we can see a 'difference'
108 gst_structure_set(new_property_struct,
109 "ExposureAuto", G_TYPE_STRING, "Off",
110 "ExposureTime", G_TYPE_DOUBLE, 35000.0,
111 NULL );
112
113 GValue new_state = G_VALUE_INIT;
114 g_value_init(&new_state, GST_TYPE_STRUCTURE);
115 gst_value_set_structure( &new_state, new_property_struct);
116
117 // Set the new property settings
118 g_object_set_property(G_OBJECT(source), "tcam-properties", &new_state);
119
120 g_value_unset(&new_state);
121 gst_structure_free(new_property_struct);
122
123 // Print the property settings after the change above
124 print_current_properties(source);
125
126 // cleanup, reset state
127 gst_element_set_state(source, GST_STATE_NULL);
128
129 gst_object_unref(source);
130 gst_object_unref(pipeline);
131
132 return 0;
133}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to get/set the properties through a description string
5#
6
7import sys
8import gi
9
10gi.require_version("Gst", "1.0")
11
12from gi.repository import Gst
13
14
15def block_until_playing(pipeline):
16
17 while True:
18 # wait 0.1 seconds for something to happen
19 change_return, state, pending = pipeline.get_state(100000000)
20 if change_return == Gst.StateChangeReturn.SUCCESS:
21 return True
22 elif change_return == Gst.StateChangeReturn.FAILURE:
23 print("Failed to change state {} {} {}".format(change_return,
24 state,
25 pending))
26 return False
27
28
29def main():
30
31 Gst.init(sys.argv)
32
33 # this line sets the gstreamer default logging level
34 # it can be removed in normal applications
35 # gstreamer logging can contain very useful information
36 # when debugging your application
37 # see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
38 # for further details
39 Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
40
41 pipeline = Gst.parse_launch("tcambin name=source ! fakesink")
42
43 if not pipeline:
44 print("Unable to create pipeline")
45 return 1
46
47 serial = None
48
49 source = pipeline.get_by_name("source")
50
51 # The user has not given a serial, so we prompt for one
52 if serial is not None:
53 source.set_property("serial", serial)
54
55 # in the READY state the camera will always be initialized
56 # in the PLAYING state additional properties may appear from gstreamer elements
57 pipeline.set_state(Gst.State.PLAYING)
58
59 if not block_until_playing(pipeline):
60 print("Unable to start pipeline")
61
62 # Print properties for a before/after comparison
63 state = source.get_property("tcam-properties")
64
65 print(f"State of device is:\n{state.to_string()}")
66
67 # Create new structure
68 # containing changes we want to apply
69
70 new_state = Gst.Structure.new_empty("tcam")
71
72 new_state.set_value("ExposureAuto", "Off")
73 new_state.set_value("ExposureTime", 35000.0)
74
75 # this can also be done by calling Gst.Structure.from_string()
76
77 source.set_property("tcam-properties", new_state)
78
79 # Print properties for a before/after comparison
80 state = source.get_property("tcam-properties")
81 print(f"New state of device is:\n{state.to_string()}")
82
83 # cleanup, reset state
84 pipeline.set_state(Gst.State.NULL)
85
86
87if __name__ == "__main__":
88 sys.exit(main())
13 - GstQuery¶
Shows how to use GstQuery for GstCaps verification.
Show sample code
1
2/*
3 This example will show you how to query the tcamsrc
4 - to verify potential framerates
5 - to verify potential caps
6 */
7
8#include <gst/gst.h>
9#include <stdio.h> /* printf and putchar */
10
11
12int main(int argc, char* argv[])
13{
14 /* this line sets the gstreamer default logging level
15 it can be removed in normal applications
16 gstreamer logging can contain verry useful information
17 when debugging your application
18 see https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html
19 for further details
20 */
21 gst_debug_set_default_threshold(GST_LEVEL_WARNING);
22
23 gst_init(&argc, &argv); // init gstreamer
24
25 GError* err = NULL;
26 const char* pipeline_desc = "tcambin name=bin ! videoconvert ! ximagesink";
27
28 GstElement* pipeline = gst_parse_launch(pipeline_desc, &err);
29
30 /* test for error */
31 if (pipeline == NULL)
32 {
33 printf("Could not create pipeline. Cause: %s\n", err->message);
34 return 1;
35 }
36 GstElement* tcambin = gst_bin_get_by_name(GST_BIN(pipeline), "bin");
37
38 gst_element_set_state(pipeline, GST_STATE_READY);
39
40
41 /* retrieve the source
42 these queries have to be performed on the source
43 as the tcambin might alter the query
44 which we do not want
45 */
46 GstElement* source = gst_bin_get_by_name(GST_BIN(tcambin), "tcambin-source");
47
48 GstCaps* framerate_query_caps =
49 gst_caps_from_string("video/x-bayer,format=rggb,width=640,height=480");
50
51 // if you have a mono camera try these instead
52 // GstCaps* framerate_query_caps =
53 // gst_caps_from_string("video/x-raw,format=GRAY8,width=640,height=480");
54
55 GstQuery* framerate_query = gst_query_new_caps(framerate_query_caps);
56
57 gst_caps_unref(framerate_query_caps);
58
59 if (gst_element_query(source, framerate_query))
60 {
61 // no transfer, nothing has to be freed
62 GstCaps* query_result_caps = NULL;
63 gst_query_parse_caps_result(framerate_query, &query_result_caps);
64
65 char* result_caps_string = gst_caps_to_string(query_result_caps);
66 printf("Camera supports these framerates: %s\n", result_caps_string);
67 g_free(result_caps_string);
68 }
69
70 gst_query_unref(framerate_query);
71
72 /*
73 verify specific caps
74 for this all needed fields have to be set(format, width, height and framerate)
75 */
76
77 GstCaps* accept_query_caps =
78 gst_caps_from_string("video/x-bayer,format=rggb,width=640,height=480,framerate=30/1");
79
80 GstQuery* accept_query = gst_query_new_accept_caps(accept_query_caps);
81
82 gst_caps_unref(accept_query_caps);
83
84 if (gst_element_query(source, accept_query))
85 {
86 gboolean accepts_caps;
87 gst_query_parse_accept_caps_result(accept_query, &accepts_caps);
88
89 if (accepts_caps)
90 {
91 printf("Caps are accepted\n");
92 }
93 else
94 {
95 printf("Caps are not accepted\n");
96 }
97 }
98
99 gst_query_unref(accept_query);
100
101 gst_object_unref(source);
102 gst_object_unref(tcambin);
103
104 gst_element_set_state(pipeline, GST_STATE_NULL);
105
106 gst_object_unref(pipeline);
107
108 return 0;
109}
1#!/usr/bin/env python3
2
3#
4# This example will show you how to query the tcamsrc
5# - to verify potential framerates
6# - to verify potential caps
7#
8
9import sys
10import gi
11import time
12
13gi.require_version("Gst", "1.0")
14
15from gi.repository import Gst
16
17def main():
18
19 Gst.init(sys.argv)
20
21 pipeline = Gst.parse_launch("tcambin name=bin ! videoconvert ! ximagesink ")
22
23 pipeline.set_state(Gst.State.READY)
24
25 tcambin = pipeline.get_by_name("bin")
26
27 # retrieve the source
28 # these queries have to be performed on the source
29 # as the tcambin might alter the query
30 # which we do not want
31 source = tcambin.get_by_name("tcambin-source")
32
33 framerate_query_caps = Gst.Caps.from_string("video/x-bayer,format=rggb,width=640,height=480")
34 # if you have a mono camera try these instead
35 # framerate_query_caps = Gst.Caps.from_string("video/x-raw,format=GRAY8.width=640,height=480")
36
37 framerate_query = Gst.Query.new_caps(framerate_query_caps)
38
39 if source.query(framerate_query):
40
41 # the result caps will contain our framerate_query_caps + all potential framerates
42 supported_framerate_caps = framerate_query.parse_caps_result()
43 print("Camera supports these framerates: {}".format(supported_framerate_caps.to_string()))
44
45 #
46 # verify specific caps
47 # for this all needed fields have to be set (format, width, height and framerate)
48 #
49
50 accept_query_caps = Gst.Caps.from_string("video/x-bayer,format=rggb,width=640,height=480,framerate=30/1")
51
52 accept_query = Gst.Query.new_accept_caps(accept_query_caps)
53
54 if source.query(accept_query):
55
56 if accept_query.parse_accept_caps_result():
57 print("Caps are supported")
58 else:
59 print("Caps are not supported")
60
61 pipeline.set_state(Gst.State.NULL)
62 return 0
63
64
65if __name__ == "__main__":
66 sys.exit(main())
Further Examples¶
For extended examples, look through the examples repository.
https://github.com/TheImagingSource/Linux-tiscamera-Programming-Samples
It contains examples on how to interact with OpenCV, ROS, GUI toolkits and much more.