1 /* GStreamer
2 * Copyright (C) <2006> Eric Jonas <jonas@mit.edu>
3 * Copyright (C) <2006> Antoine Tremblay <hexa00@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 /**
22 * SECTION:element-dc1394src
23 * @title: dc1394src
24 *
25 * Source for IIDC (Instrumentation & Industrial Digital Camera) firewire
26 * cameras. If several cameras are connected to the system, the desired one
27 * can be selected by its GUID and an optional unit number (most cameras are
28 * single unit and do not require it). The frame size, rate and format are set
29 * from capabilities. Although the IIDC specification includes a raw video
30 * mode, many cameras use mono video modes to capture in Bayer format.
31 * Thus, for each mono video mode supported by a camera, both gray raw and Bayer
32 * corresponding video formats are exposed in the capabilities.
33 * The Bayer pattern is left unspecified.
34 *
35 * ## Example launch lines
36 * |[
37 * gst-launch-1.0 -v dc1394src ! videoconvert ! autovideosink
38 * ]| Capture and display frames from the first camera available in the system.
39 * |[
40 * gst-launch-1.0 dc1394src guid=00074813004DF937 \
41 * ! "video/x-bayer,format=gbrg,width=1280,height=960,framerate=15/2" \
42 * ! bayer2rgb ! videoconvert ! autovideosink
43 * ]| Capture and display frames from a specific camera in the desired format.
44 *
45 */
46
47 #ifdef HAVE_CONFIG_H
48 #include "config.h"
49 #endif
50 #include "gstdc1394src.h"
51 #include <gst/video/video.h>
52
53 GST_DEBUG_CATEGORY_STATIC (dc1394_debug);
54 #define GST_CAT_DEFAULT dc1394_debug
55
56
57 enum
58 {
59 PROP_0,
60 PROP_CAMERA_GUID,
61 PROP_CAMERA_UNIT,
62 PROP_ISO_SPEED,
63 PROP_DMA_BUFFER_SIZE
64 };
65
66
67 #define GST_TYPE_DC1394_ISO_SPEED (gst_dc1394_iso_speed_get_type ())
68 static GType
gst_dc1394_iso_speed_get_type(void)69 gst_dc1394_iso_speed_get_type (void)
70 {
71 static const GEnumValue iso_speeds[] = {
72 {100, "DC1394 ISO speed 100", "100"},
73 {200, "DC1394 ISO speed 200", "200"},
74 {400, "DC1394 ISO speed 400", "400"},
75 {800, "DC1394 ISO speed 800", "800"},
76 {1600, "DC1394 ISO speed 1600", "1600"},
77 {3200, "DC1394 ISO speed 3200", "3200"},
78 {0, NULL, NULL}
79 };
80 static GType type = 0;
81
82 if (!type) {
83 type = g_enum_register_static ("GstDC1394ISOSpeed", iso_speeds);
84 }
85 return type;
86 }
87
88
89 #define gst_dc1394_src_parent_class parent_class
90 G_DEFINE_TYPE_WITH_CODE (GstDC1394Src, gst_dc1394_src, GST_TYPE_PUSH_SRC,
91 GST_DEBUG_CATEGORY_INIT (dc1394_debug, "dc1394", 0, "DC1394 interface");
92 );
93 GST_ELEMENT_REGISTER_DEFINE (dc1394src, "dc1394src", GST_RANK_NONE,
94 GST_TYPE_DC1394_SRC);
95
96 static void gst_dc1394_src_set_property (GObject * object, guint prop_id,
97 const GValue * value, GParamSpec * pspec);
98 static void gst_dc1394_src_get_property (GObject * object, guint prop_id,
99 GValue * value, GParamSpec * pspec);
100 static gboolean gst_dc1394_src_start (GstBaseSrc * bsrc);
101 static gboolean gst_dc1394_src_stop (GstBaseSrc * bsrc);
102 static gboolean gst_dc1394_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps);
103 static GstCaps *gst_dc1394_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter);
104 static GstFlowReturn gst_dc1394_src_create (GstPushSrc * psrc,
105 GstBuffer ** buffer);
106
107 static void gst_dc1394_src_set_prop_camera_guid (GstDC1394Src * src,
108 const gchar * guid);
109 static gchar *gst_dc1394_src_get_prop_camera_guid (GstDC1394Src * src);
110 static void gst_dc1394_src_set_prop_camera_unit (GstDC1394Src * src, gint unit);
111 static gint gst_dc1394_src_get_prop_camera_unit (GstDC1394Src * src);
112 static void gst_dc1394_src_set_prop_iso_speed (GstDC1394Src * src, guint speed);
113 static guint gst_dc1394_src_get_prop_iso_speed (GstDC1394Src * src);
114 static void gst_dc1394_src_set_prop_dma_buffer_size (GstDC1394Src * src,
115 guint size);
116 static guint gst_dc1394_src_get_prop_dma_buffer_size (GstDC1394Src * src);
117 static gboolean gst_dc1394_src_open_cam (GstDC1394Src * src);
118 static void gst_dc1394_src_close_cam (GstDC1394Src * src);
119 static gboolean gst_dc1394_src_start_cam (GstDC1394Src * src);
120 static gboolean gst_dc1394_src_stop_cam (GstDC1394Src * src);
121 static gboolean gst_dc1394_src_set_cam_caps (GstDC1394Src * src,
122 GstCaps * caps);
123 static GstCaps *gst_dc1394_src_get_cam_caps (GstDC1394Src * src);
124 static GstCaps *gst_dc1394_src_get_all_caps (void);
125
126 static GstCaps *gst_dc1394_src_build_caps (const dc1394color_codings_t *
127 supported_codings, const dc1394framerates_t * supported_rates,
128 guint width_min, guint width_max, guint width_step, guint height_min,
129 guint height_max, guint height_step);
130 static gboolean gst_dc1394_src_parse_caps (const GstCaps * caps,
131 dc1394color_codings_t * color_codings, dc1394framerate_t * rate,
132 gdouble * rate_decimal, guint * width, guint * height);
133
134 static void
gst_dc1394_src_class_init(GstDC1394SrcClass * klass)135 gst_dc1394_src_class_init (GstDC1394SrcClass * klass)
136 {
137 GObjectClass *gobject_class;
138 GstElementClass *element_class;
139 GstBaseSrcClass *basesrc_class;
140 GstPushSrcClass *pushsrc_class;
141
142 gobject_class = G_OBJECT_CLASS (klass);
143 element_class = GST_ELEMENT_CLASS (klass);
144 basesrc_class = GST_BASE_SRC_CLASS (klass);
145 pushsrc_class = GST_PUSH_SRC_CLASS (klass);
146
147 gobject_class->set_property = gst_dc1394_src_set_property;
148 gobject_class->get_property = gst_dc1394_src_get_property;
149 g_object_class_install_property (gobject_class, PROP_CAMERA_GUID,
150 g_param_spec_string ("guid", "Camera GUID",
151 "The hexadecimal representation of the GUID of the camera"
152 " (use first camera available if null)",
153 NULL,
154 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE |
155 GST_PARAM_MUTABLE_READY));
156 g_object_class_install_property (gobject_class, PROP_CAMERA_UNIT,
157 g_param_spec_int ("unit", "Camera unit",
158 "The unit number of the camera (-1 if no unit number is used)",
159 -1, G_MAXINT, -1,
160 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE |
161 GST_PARAM_MUTABLE_READY));
162 g_object_class_install_property (gobject_class, PROP_ISO_SPEED,
163 g_param_spec_enum ("iso", "ISO bandwidth",
164 "The ISO bandwidth in Mbps",
165 GST_TYPE_DC1394_ISO_SPEED, 400,
166 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE |
167 GST_PARAM_MUTABLE_READY));
168 g_object_class_install_property (gobject_class, PROP_DMA_BUFFER_SIZE,
169 g_param_spec_uint ("dma", "DMA ring buffer size",
170 "The number of frames in the Direct Memory Access ring buffer",
171 1, G_MAXUINT, 10,
172 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE |
173 GST_PARAM_MUTABLE_READY));
174
175 gst_element_class_set_static_metadata (element_class,
176 "1394 IIDC Video Source", "Source/Video",
177 "libdc1394 based source for IIDC cameras",
178 "Antoine Tremblay <hexa00@gmail.com>");
179 gst_element_class_add_pad_template (element_class,
180 gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
181 gst_dc1394_src_get_all_caps ()));
182
183 basesrc_class->start = GST_DEBUG_FUNCPTR (gst_dc1394_src_start);
184 basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dc1394_src_stop);
185 basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_dc1394_src_set_caps);
186 basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_dc1394_src_get_caps);
187
188 pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_dc1394_src_create);
189
190 gst_type_mark_as_plugin_api (GST_TYPE_DC1394_ISO_SPEED, 0);
191 }
192
193
194 static void
gst_dc1394_src_init(GstDC1394Src * src)195 gst_dc1394_src_init (GstDC1394Src * src)
196 {
197 src->guid = -1;
198 src->unit = -1;
199 src->iso_speed = DC1394_ISO_SPEED_400;
200 src->dma_buffer_size = 10;
201 src->dc1394 = NULL;
202 src->camera = NULL;
203 src->caps = NULL;
204
205 gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
206 gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
207 gst_base_src_set_do_timestamp (GST_BASE_SRC (src), TRUE);
208 }
209
210
211 static void
gst_dc1394_src_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)212 gst_dc1394_src_get_property (GObject * object, guint prop_id, GValue * value,
213 GParamSpec * pspec)
214 {
215 GstDC1394Src *src;
216
217 src = GST_DC1394_SRC (object);
218 switch (prop_id) {
219 case PROP_CAMERA_GUID:
220 g_value_take_string (value, gst_dc1394_src_get_prop_camera_guid (src));
221 break;
222 case PROP_CAMERA_UNIT:
223 g_value_set_int (value, gst_dc1394_src_get_prop_camera_unit (src));
224 break;
225 case PROP_ISO_SPEED:
226 g_value_set_enum (value, gst_dc1394_src_get_prop_iso_speed (src));
227 break;
228 case PROP_DMA_BUFFER_SIZE:
229 g_value_set_uint (value, gst_dc1394_src_get_prop_dma_buffer_size (src));
230 break;
231 default:
232 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
233 break;
234 }
235 }
236
237
238 static void
gst_dc1394_src_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)239 gst_dc1394_src_set_property (GObject * object,
240 guint prop_id, const GValue * value, GParamSpec * pspec)
241 {
242 GstDC1394Src *src;
243
244 src = GST_DC1394_SRC (object);
245 switch (prop_id) {
246 case PROP_CAMERA_GUID:
247 gst_dc1394_src_set_prop_camera_guid (src, g_value_get_string (value));
248 break;
249 case PROP_CAMERA_UNIT:
250 gst_dc1394_src_set_prop_camera_unit (src, g_value_get_int (value));
251 break;
252 case PROP_ISO_SPEED:
253 gst_dc1394_src_set_prop_iso_speed (src, g_value_get_enum (value));
254 break;
255 case PROP_DMA_BUFFER_SIZE:
256 gst_dc1394_src_set_prop_dma_buffer_size (src, g_value_get_uint (value));
257 break;
258 default:
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
260 break;
261 }
262 }
263
264
265 static gboolean
gst_dc1394_src_start(GstBaseSrc * bsrc)266 gst_dc1394_src_start (GstBaseSrc * bsrc)
267 {
268 GstDC1394Src *src;
269
270 src = GST_DC1394_SRC (bsrc);
271 return gst_dc1394_src_open_cam (src);
272 }
273
274
275 static gboolean
gst_dc1394_src_stop(GstBaseSrc * bsrc)276 gst_dc1394_src_stop (GstBaseSrc * bsrc)
277 {
278 GstDC1394Src *src;
279
280 src = GST_DC1394_SRC (bsrc);
281 if (!gst_dc1394_src_stop_cam (src))
282 return FALSE;
283 gst_dc1394_src_close_cam (src);
284 return TRUE;
285 }
286
287
288 static GstCaps *
gst_dc1394_src_get_caps(GstBaseSrc * bsrc,GstCaps * filter)289 gst_dc1394_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
290 {
291 GstDC1394Src *src;
292 GstCaps *caps, *ret;
293
294 src = GST_DC1394_SRC (bsrc);
295 if (src->camera) {
296 caps = gst_dc1394_src_get_cam_caps (src);
297 } else {
298 caps = gst_dc1394_src_get_all_caps ();
299 }
300 if (caps && filter) {
301 ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
302 gst_caps_unref (caps);
303 } else {
304 ret = caps;
305 }
306 return ret;
307 }
308
309
310 static gboolean
gst_dc1394_src_set_caps(GstBaseSrc * bsrc,GstCaps * caps)311 gst_dc1394_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
312 {
313 GstDC1394Src *src;
314
315 src = GST_DC1394_SRC (bsrc);
316 return gst_dc1394_src_stop_cam (src)
317 && gst_dc1394_src_set_cam_caps (src, caps)
318 && gst_dc1394_src_start_cam (src);
319 }
320
321
322 static GstFlowReturn
gst_dc1394_src_create(GstPushSrc * psrc,GstBuffer ** obuf)323 gst_dc1394_src_create (GstPushSrc * psrc, GstBuffer ** obuf)
324 {
325 GstDC1394Src *src;
326 GstBuffer *buffer = NULL;
327 dc1394video_frame_t *frame;
328 dc1394error_t ret;
329
330 src = GST_DC1394_SRC (psrc);
331 ret = dc1394_capture_dequeue (src->camera, DC1394_CAPTURE_POLICY_WAIT,
332 &frame);
333 if (ret != DC1394_SUCCESS) {
334 GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
335 ("Could not dequeue frame: %s.", dc1394_error_get_string (ret)));
336 return GST_FLOW_ERROR;
337 }
338 /*
339 * TODO: We could create the buffer by wrapping the image bytes in the frame
340 * (enqueing the frame in the notify function) to save the copy operation.
341 * It will only work if all the buffers are disposed before closing the camera
342 * when state changes from PAUSED to READY.
343 */
344 buffer = gst_buffer_new_allocate (NULL, frame->image_bytes, NULL);
345 gst_buffer_fill (buffer, 0, frame->image, frame->image_bytes);
346 /*
347 * TODO: There is a field timestamp in the frame structure,
348 * It is not sure if it could be used as PTS or DTS:
349 * we are not sure if it comes from a monotonic clock,
350 * and it seems to be left undefined under MS Windows.
351 */
352 ret = dc1394_capture_enqueue (src->camera, frame);
353 if (ret != DC1394_SUCCESS) {
354 GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
355 ("Could not enqueue frame: %s.", dc1394_error_get_string (ret)));
356 }
357 *obuf = buffer;
358 return GST_FLOW_OK;
359 }
360
361
362 static void
gst_dc1394_src_set_prop_camera_guid(GstDC1394Src * src,const gchar * guid)363 gst_dc1394_src_set_prop_camera_guid (GstDC1394Src * src, const gchar * guid)
364 {
365 gchar *end;
366
367 if (!guid) {
368 GST_DEBUG_OBJECT (src, "Null camera GUID value: %s.",
369 "first camera available will be used");
370 src->guid = -1;
371 return;
372 }
373 errno = 0;
374 src->guid = g_ascii_strtoull (guid, &end, 16);
375 if (errno == ERANGE || end == guid || *end != '\0') {
376 GST_ERROR_OBJECT (src, "Invalid camera GUID value: %s.", guid);
377 return;
378 }
379 }
380
381
382 static gchar *
gst_dc1394_src_get_prop_camera_guid(GstDC1394Src * src)383 gst_dc1394_src_get_prop_camera_guid (GstDC1394Src * src)
384 {
385 if (src->guid == -1) {
386 return NULL;
387 }
388 return g_strdup_printf ("%016" G_GINT64_MODIFIER "X", src->guid);
389 }
390
391
392 static void
gst_dc1394_src_set_prop_camera_unit(GstDC1394Src * src,gint unit)393 gst_dc1394_src_set_prop_camera_unit (GstDC1394Src * src, gint unit)
394 {
395 src->unit = unit;
396 }
397
398
399 static gint
gst_dc1394_src_get_prop_camera_unit(GstDC1394Src * src)400 gst_dc1394_src_get_prop_camera_unit (GstDC1394Src * src)
401 {
402 return src->unit;
403 }
404
405
406 static void
gst_dc1394_src_set_prop_iso_speed(GstDC1394Src * src,guint speed)407 gst_dc1394_src_set_prop_iso_speed (GstDC1394Src * src, guint speed)
408 {
409 switch (speed) {
410 case 100:
411 src->iso_speed = DC1394_ISO_SPEED_100;
412 break;
413 case 200:
414 src->iso_speed = DC1394_ISO_SPEED_200;
415 break;
416 case 400:
417 src->iso_speed = DC1394_ISO_SPEED_400;
418 break;
419 case 800:
420 src->iso_speed = DC1394_ISO_SPEED_800;
421 break;
422 case 1600:
423 src->iso_speed = DC1394_ISO_SPEED_1600;
424 break;
425 case 3200:
426 src->iso_speed = DC1394_ISO_SPEED_3200;
427 break;
428 default:
429 GST_ERROR_OBJECT (src, "Invalid ISO speed value: %d.", speed);
430 }
431 }
432
433
434 static guint
gst_dc1394_src_get_prop_iso_speed(GstDC1394Src * src)435 gst_dc1394_src_get_prop_iso_speed (GstDC1394Src * src)
436 {
437 switch (src->iso_speed) {
438 case DC1394_ISO_SPEED_100:
439 return 100;
440 case DC1394_ISO_SPEED_200:
441 return 200;
442 case DC1394_ISO_SPEED_400:
443 return 400;
444 case DC1394_ISO_SPEED_800:
445 return 800;
446 case DC1394_ISO_SPEED_1600:
447 return 1600;
448 case DC1394_ISO_SPEED_3200:
449 return 3200;
450 default: /* never reached */
451 return DC1394_ISO_SPEED_MIN - 1;
452 }
453 }
454
455
456 static void
gst_dc1394_src_set_prop_dma_buffer_size(GstDC1394Src * src,guint size)457 gst_dc1394_src_set_prop_dma_buffer_size (GstDC1394Src * src, guint size)
458 {
459 src->dma_buffer_size = size;
460 }
461
462
463 static guint
gst_dc1394_src_get_prop_dma_buffer_size(GstDC1394Src * src)464 gst_dc1394_src_get_prop_dma_buffer_size (GstDC1394Src * src)
465 {
466 return src->dma_buffer_size;
467 }
468
469
470 static gboolean
gst_dc1394_src_open_cam(GstDC1394Src * src)471 gst_dc1394_src_open_cam (GstDC1394Src * src)
472 {
473 dc1394camera_list_t *cameras;
474 dc1394error_t ret;
475 int number;
476 uint64_t guid;
477 int unit, i;
478
479 src->dc1394 = dc1394_new ();
480 if (!src->dc1394) {
481 GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
482 ("Could not initialize dc1394 library."));
483 goto error;
484 }
485
486 number = -1;
487 guid = -1;
488 unit = -1;
489 ret = dc1394_camera_enumerate (src->dc1394, &cameras);
490 if (ret != DC1394_SUCCESS) {
491 GST_ELEMENT_ERROR (src, LIBRARY, FAILED, (NULL),
492 ("Could not enumerate cameras: %s.", dc1394_error_get_string (ret)));
493 goto error;
494 }
495 for (i = 0; i < cameras->num; i++) {
496 GST_DEBUG_OBJECT (src, "Camera %2d is %016" G_GINT64_MODIFIER "X %d.",
497 i, cameras->ids[i].guid, cameras->ids[i].unit);
498 if ((src->guid == -1 || src->guid == cameras->ids[i].guid) &&
499 (src->unit == -1 || src->unit == cameras->ids[i].unit)) {
500 number = i;
501 guid = cameras->ids[i].guid;
502 unit = cameras->ids[i].unit;
503 }
504 }
505 dc1394_camera_free_list (cameras);
506 if (number < 0) {
507 if (src->guid == -1) {
508 GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
509 ("No cameras found."));
510 } else {
511 GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
512 ("Camera %016" G_GINT64_MODIFIER "X %d not found.",
513 src->guid, src->unit));
514 }
515 goto error;
516 }
517
518 GST_DEBUG_OBJECT (src, "Open camera %016" G_GINT64_MODIFIER "X %d.",
519 guid, unit);
520 src->camera = dc1394_camera_new_unit (src->dc1394, guid, unit);
521 if (!src->camera) {
522 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
523 ("Could not open camera %016" G_GINT64_MODIFIER "X %d.", guid, unit));
524 goto error;
525 }
526 GST_DEBUG_OBJECT (src,
527 "Camera %016" G_GINT64_MODIFIER "X %d opened: \"%s %s\".",
528 src->camera->guid, src->camera->unit,
529 src->camera->vendor, src->camera->model);
530
531 if (src->iso_speed > DC1394_ISO_SPEED_400) {
532 ret = dc1394_video_set_operation_mode (src->camera,
533 DC1394_OPERATION_MODE_1394B);
534 if (ret != DC1394_SUCCESS) {
535 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
536 ("Could not set 1394B operation mode: %s.",
537 dc1394_error_get_string (ret)));
538 goto error;
539 }
540 }
541 ret = dc1394_video_set_iso_speed (src->camera, src->iso_speed);
542 if (ret != DC1394_SUCCESS) {
543 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
544 ("Could not set ISO speed %d: %s.", src->iso_speed,
545 dc1394_error_get_string (ret)));
546 goto error;
547 }
548
549 return TRUE;
550
551 error:
552 if (src->camera) {
553 dc1394_camera_free (src->camera);
554 src->camera = NULL;
555 }
556 if (src->dc1394) {
557 dc1394_free (src->dc1394);
558 src->dc1394 = NULL;
559 }
560 return FALSE;
561 }
562
563
564 static void
gst_dc1394_src_close_cam(GstDC1394Src * src)565 gst_dc1394_src_close_cam (GstDC1394Src * src)
566 {
567 GST_DEBUG_OBJECT (src,
568 "Close camera %016" G_GINT64_MODIFIER "X %d: \"%s %s\".",
569 src->camera->guid, src->camera->unit,
570 src->camera->vendor, src->camera->model);
571 if (src->caps) {
572 gst_caps_unref (src->caps);
573 src->caps = NULL;
574 }
575 dc1394_camera_free (src->camera);
576 src->camera = NULL;
577 dc1394_free (src->dc1394);
578 src->dc1394 = NULL;
579 GST_DEBUG_OBJECT (src, "Camera closed.");
580 }
581
582
583 static gboolean
gst_dc1394_src_start_cam(GstDC1394Src * src)584 gst_dc1394_src_start_cam (GstDC1394Src * src)
585 {
586 dc1394error_t ret;
587 dc1394switch_t status;
588 guint trials;
589
590 GST_DEBUG_OBJECT (src, "Setup capture with a DMA buffer of %d frames",
591 src->dma_buffer_size);
592 ret = dc1394_capture_setup (src->camera, src->dma_buffer_size,
593 DC1394_CAPTURE_FLAGS_DEFAULT);
594 if (ret == DC1394_NO_BANDWIDTH) {
595 GST_DEBUG_OBJECT (src,
596 "Could not setup capture with available ISO bandwidth,"
597 "releasing channels and bandwidth and retrying...");
598 ret = dc1394_iso_release_all (src->camera);
599 if (ret != DC1394_SUCCESS) {
600 GST_ELEMENT_WARNING (src, RESOURCE, FAILED, (NULL),
601 ("Could not release ISO channels and bandwidth: %s",
602 dc1394_error_get_string (ret)));
603 }
604 ret = dc1394_capture_setup (src->camera, src->dma_buffer_size,
605 DC1394_CAPTURE_FLAGS_DEFAULT);
606 }
607 if (ret != DC1394_SUCCESS) {
608 GST_ELEMENT_ERROR (src, RESOURCE, FAILED, (NULL),
609 ("Could not setup capture: %s", dc1394_error_get_string (ret)));
610 goto error_capture;
611 }
612
613 /*
614 * TODO: dc1394_capture_setup/stop can start/stop the transmission
615 * when called with DC1394_CAPTURE_FLAGS_AUTO_ISO in the flags.
616 * The repeated trials check is a leftover of the original code,
617 * and might not be needed.
618 */
619 GST_DEBUG_OBJECT (src, "Enable camera transmission.");
620 ret = dc1394_video_set_transmission (src->camera, DC1394_ON);
621 if (ret != DC1394_SUCCESS) {
622 GST_ELEMENT_ERROR (src, RESOURCE, FAILED, (NULL),
623 ("Could not set transmission status: %s.",
624 dc1394_error_get_string (ret)));
625 goto error_transmission;
626 }
627 ret = dc1394_video_get_transmission (src->camera, &status);
628 for (trials = 10;
629 (trials > 0) && !(ret == DC1394_SUCCESS && status == DC1394_ON);
630 trials--) {
631 GST_DEBUG_OBJECT (src,
632 "Wait for camera to start transmission (%d trials left).", trials);
633 g_usleep (50000);
634 ret = dc1394_video_get_transmission (src->camera, &status);
635 }
636 if (!(ret == DC1394_SUCCESS && status == DC1394_ON)) {
637 GST_ELEMENT_ERROR (src, RESOURCE, FAILED, (NULL),
638 ("Could not get positive transmission status: %s.",
639 dc1394_error_get_string (ret)));
640 goto error_transmission;
641 }
642
643 GST_DEBUG_OBJECT (src, "Capture successfully started.");
644 return TRUE;
645
646 error_transmission:
647 ret = dc1394_capture_stop (src->camera);
648 if (ret != DC1394_SUCCESS) {
649 GST_ELEMENT_WARNING (src, RESOURCE, FAILED, (NULL),
650 ("Could not stop capture: %s.", dc1394_error_get_string (ret)));
651 }
652 error_capture:
653 return FALSE;
654 }
655
656
657 static gboolean
gst_dc1394_src_stop_cam(GstDC1394Src * src)658 gst_dc1394_src_stop_cam (GstDC1394Src * src)
659 {
660 dc1394error_t ret;
661 dc1394switch_t status;
662 guint trials;
663
664 /*
665 * TODO: dc1394_capture_setup/stop can start/stop the transmission
666 * when called with DC1394_CAPTURE_FLAGS_AUTO_ISO in the flags.
667 * The repeated trials check is a leftover of the original code,
668 * and might not be needed.
669 */
670 GST_DEBUG_OBJECT (src, "Disable camera transmission.");
671 ret = dc1394_video_set_transmission (src->camera, DC1394_OFF);
672 if (ret != DC1394_SUCCESS) {
673 GST_ELEMENT_ERROR (src, RESOURCE, FAILED, (NULL),
674 ("Could not set transmission status: %s.",
675 dc1394_error_get_string (ret)));
676 return FALSE;
677 }
678 ret = dc1394_video_get_transmission (src->camera, &status);
679 for (trials = 10;
680 (trials > 0) && !(ret == DC1394_SUCCESS && status == DC1394_OFF);
681 trials--) {
682 GST_DEBUG_OBJECT (src,
683 "Wait for camera to stop transmission (%d trials left).", trials);
684 g_usleep (50000);
685 ret = dc1394_video_get_transmission (src->camera, &status);
686 }
687 if (!(ret == DC1394_SUCCESS && status == DC1394_OFF)) {
688 GST_WARNING_OBJECT (src,
689 "Could not get negative transmission status: %s.",
690 dc1394_error_get_string (ret));
691 }
692
693 GST_DEBUG_OBJECT (src, "Clear capture resources.");
694 ret = dc1394_capture_stop (src->camera);
695 if (ret != DC1394_SUCCESS && ret != DC1394_CAPTURE_IS_NOT_SET) {
696 GST_ELEMENT_ERROR (src, RESOURCE, FAILED, (NULL),
697 ("Could not clear capture: %s.", dc1394_error_get_string (ret)));
698 return FALSE;
699 }
700
701 switch (ret) {
702 case DC1394_CAPTURE_IS_NOT_SET:
703 GST_DEBUG_OBJECT (src, "Capture was not set up.");
704 break;
705 case DC1394_SUCCESS:
706 GST_DEBUG_OBJECT (src, "Capture successfully stopped.");
707 break;
708 default:
709 break;
710 }
711
712 return TRUE;
713 }
714
715
716 static gboolean
gst_dc1394_src_set_cam_caps(GstDC1394Src * src,GstCaps * caps)717 gst_dc1394_src_set_cam_caps (GstDC1394Src * src, GstCaps * caps)
718 {
719 GstCaps *mode_caps;
720 gboolean ok, supported;
721 dc1394video_modes_t supported_modes;
722 dc1394video_mode_t mode;
723 dc1394color_codings_t supported_codings;
724 dc1394color_coding_t coding;
725 dc1394framerates_t supported_rates;
726 dc1394framerate_t rate;
727 double rate_decimal;
728 uint64_t total_bytes;
729 uint32_t width, width_step, height, height_step;
730 guint m, c;
731
732 ok = dc1394_video_get_supported_modes (src->camera,
733 &supported_modes) == DC1394_SUCCESS;
734 if (!ok) {
735 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
736 ("Could not get supported modes."));
737 goto error;
738 }
739 supported = FALSE;
740 for (m = 0; m < supported_modes.num && !supported; m++) {
741 mode = supported_modes.modes[m];
742 mode_caps = gst_caps_new_empty ();
743 if (dc1394_is_video_mode_scalable (mode)) {
744 ok &= dc1394_format7_get_color_codings (src->camera, mode,
745 &supported_codings) == DC1394_SUCCESS;
746 ok &= dc1394_format7_get_max_image_size (src->camera, mode,
747 &width, &height) == DC1394_SUCCESS;
748 ok &= dc1394_format7_get_unit_size (src->camera, mode,
749 &width_step, &height_step) == DC1394_SUCCESS;
750 } else {
751 ok &= dc1394_get_color_coding_from_video_mode (src->camera, mode,
752 &coding) == DC1394_SUCCESS;
753 ok &= dc1394_get_image_size_from_video_mode (src->camera, mode,
754 &width, &height) == DC1394_SUCCESS;
755 ok &= dc1394_video_get_supported_framerates (src->camera, mode,
756 &supported_rates) == DC1394_SUCCESS;
757 }
758 if (!ok) {
759 GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
760 ("Could not get video mode %d parameters.", mode));
761 } else if (dc1394_is_video_mode_scalable (mode)) {
762 gst_caps_append (mode_caps,
763 gst_dc1394_src_build_caps (&supported_codings, NULL,
764 width_step, width, width_step, height_step, height, height_step));
765 } else {
766 supported_codings.num = 1;
767 supported_codings.codings[0] = coding;
768 gst_caps_append (mode_caps,
769 gst_dc1394_src_build_caps (&supported_codings, &supported_rates,
770 width, width, 1, height, height, 1));
771 }
772 supported = gst_caps_can_intersect (caps, mode_caps);
773 gst_caps_unref (mode_caps);
774 }
775 ok = supported && gst_dc1394_src_parse_caps (caps, &supported_codings, &rate,
776 &rate_decimal, &width, &height);
777 if (!ok) {
778 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
779 ("Unsupported caps %" GST_PTR_FORMAT, caps));
780 goto error;
781 }
782 GST_DEBUG_OBJECT (src, "Set video mode %d.", mode);
783 ok = dc1394_video_set_mode (src->camera, mode) == DC1394_SUCCESS;
784 if (!ok) {
785 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
786 ("Could not set video mode %d.", mode));
787 goto error;
788 }
789 if (dc1394_is_video_mode_scalable (mode)) {
790 ok = FALSE;
791 for (c = 0; c < supported_codings.num && !ok; c++) {
792 coding = supported_codings.codings[c];
793 GST_DEBUG_OBJECT (src,
794 "Try format7 video mode %d with coding %d, size %d %d, and rate %.4f Hz.",
795 mode, coding, width, height, rate_decimal);
796 ok = (dc1394_format7_set_color_coding (src->camera, mode,
797 coding) == DC1394_SUCCESS)
798 && (dc1394_format7_set_image_size (src->camera, mode,
799 width, height) == DC1394_SUCCESS)
800 && (dc1394_format7_get_total_bytes (src->camera, mode,
801 &total_bytes) == DC1394_SUCCESS)
802 && (dc1394_format7_set_packet_size (src->camera, mode,
803 total_bytes * rate_decimal * 0.000125) == DC1394_SUCCESS);
804 }
805 } else {
806 GST_DEBUG_OBJECT (src, "Set fixed video mode %d rate %.4f Hz (%d).",
807 mode, rate_decimal, rate);
808 ok = dc1394_video_set_framerate (src->camera, rate) == DC1394_SUCCESS;
809 }
810 /* TODO: check feature framerate */
811 if (!ok) {
812 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
813 ("Could not set video mode %d parameters.", mode));
814 goto error;
815 }
816 return TRUE;
817
818 error:
819 return FALSE;
820 }
821
822
823 GstCaps *
gst_dc1394_src_get_cam_caps(GstDC1394Src * src)824 gst_dc1394_src_get_cam_caps (GstDC1394Src * src)
825 {
826 gboolean ok;
827 dc1394video_modes_t supported_modes;
828 dc1394video_mode_t mode;
829 dc1394color_codings_t supported_codings;
830 dc1394color_coding_t coding;
831 dc1394framerates_t supported_rates;
832 uint32_t width, width_step, height, height_step;
833 guint m;
834
835 if (src->caps)
836 return gst_caps_ref (src->caps);
837
838 ok = dc1394_video_get_supported_modes (src->camera,
839 &supported_modes) == DC1394_SUCCESS;
840 if (!ok) {
841 GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
842 ("Could not get supported modes."));
843 return NULL;
844 }
845
846 src->caps = gst_caps_new_empty ();
847 for (m = 0; m < supported_modes.num; m++) {
848 mode = supported_modes.modes[m];
849 if (dc1394_is_video_mode_scalable (mode)) {
850 ok &= dc1394_format7_get_color_codings (src->camera, mode,
851 &supported_codings) == DC1394_SUCCESS;
852 ok &= dc1394_format7_get_max_image_size (src->camera, mode,
853 &width, &height) == DC1394_SUCCESS;
854 ok &= dc1394_format7_get_unit_size (src->camera, mode,
855 &width_step, &height_step) == DC1394_SUCCESS;
856 if (!ok) {
857 GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
858 ("Could not get format7 video mode %d parameters.", mode));
859 } else {
860 gst_caps_append (src->caps,
861 gst_dc1394_src_build_caps (&supported_codings, NULL,
862 width_step, width, width_step, height_step, height,
863 height_step));
864 }
865 } else {
866 ok &= dc1394_get_image_size_from_video_mode (src->camera, mode,
867 &width, &height) == DC1394_SUCCESS;
868 ok &= dc1394_video_get_supported_framerates (src->camera, mode,
869 &supported_rates) == DC1394_SUCCESS;
870 ok &= dc1394_get_color_coding_from_video_mode (src->camera, mode,
871 &coding) == DC1394_SUCCESS;
872 if (!ok) {
873 GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
874 ("Could not get fixed video mode %d parameters.", mode));
875 } else {
876 supported_codings.num = 1;
877 supported_codings.codings[0] = coding;
878 gst_caps_append (src->caps,
879 gst_dc1394_src_build_caps (&supported_codings, &supported_rates,
880 width, width, 1, height, height, 1));
881 }
882 }
883 }
884 GST_DEBUG_OBJECT (src, "Camera capabilities: \"%" GST_PTR_FORMAT "\".",
885 src->caps);
886 return gst_caps_ref (src->caps);
887 }
888
889
890 static GstCaps *
gst_dc1394_src_get_all_caps(void)891 gst_dc1394_src_get_all_caps (void)
892 {
893 GstCaps *caps;
894 dc1394color_coding_t coding;
895 dc1394color_codings_t video_codings;
896 uint32_t width, height;
897
898 const dc1394color_codings_t supported_codings = { 7, {
899 /* DC1394_COLOR_CODING_RGB16S, DC1394_COLOR_CODING_RGB16, */
900 DC1394_COLOR_CODING_RGB8, DC1394_COLOR_CODING_YUV444,
901 DC1394_COLOR_CODING_YUV422, DC1394_COLOR_CODING_YUV411,
902 /* DC1394_COLOR_CODING_RAW16, DC1394_COLOR_CODING_MONO16S */
903 DC1394_COLOR_CODING_MONO16, DC1394_COLOR_CODING_RAW8,
904 DC1394_COLOR_CODING_MONO8}
905 };
906 const dc1394framerates_t all_rates = { 8, {
907 DC1394_FRAMERATE_1_875, DC1394_FRAMERATE_3_75, DC1394_FRAMERATE_7_5,
908 DC1394_FRAMERATE_15, DC1394_FRAMERATE_30, DC1394_FRAMERATE_60,
909 DC1394_FRAMERATE_120, DC1394_FRAMERATE_240}
910 };
911 dc1394video_mode_t mode;
912
913 caps = gst_caps_new_empty ();
914 /* First caps for fixed video modes */
915 for (mode = DC1394_VIDEO_MODE_MIN; mode < DC1394_VIDEO_MODE_EXIF; mode++) {
916 dc1394_get_image_size_from_video_mode (NULL, mode, &width, &height);
917 dc1394_get_color_coding_from_video_mode (NULL, mode, &coding);
918 video_codings.codings[0] = coding;
919 video_codings.num = 1;
920 gst_caps_append (caps,
921 gst_dc1394_src_build_caps (&video_codings, &all_rates,
922 width, width, 1, height, height, 1));
923 }
924 /* Then caps for Format 7 modes */
925 gst_caps_append (caps,
926 gst_dc1394_src_build_caps (&supported_codings, NULL,
927 1, G_MAXINT, 1, 1, G_MAXINT, 1));
928 return caps;
929 }
930
931
932 static GstCaps *
gst_dc1394_src_build_caps(const dc1394color_codings_t * supported_codings,const dc1394framerates_t * supported_rates,uint32_t width_min,uint32_t width_max,uint32_t width_step,uint32_t height_min,uint32_t height_max,uint32_t height_step)933 gst_dc1394_src_build_caps (const dc1394color_codings_t * supported_codings,
934 const dc1394framerates_t * supported_rates,
935 uint32_t width_min, uint32_t width_max, uint32_t width_step,
936 uint32_t height_min, uint32_t height_max, uint32_t height_step)
937 {
938 GstCaps *caps;
939 GstStructure *structure;
940 GstVideoFormat video_format;
941 dc1394color_coding_t coding;
942 dc1394framerate_t rate;
943 GValue format = { 0 };
944 GValue formats = { 0 };
945 GValue width = { 0 };
946 GValue widths = { 0 };
947 GValue height = { 0 };
948 GValue heights = { 0 };
949 GValue framerate = { 0 };
950 GValue framerates = { 0 };
951 guint c, w, h, r;
952
953 caps = gst_caps_new_empty ();
954 for (c = 0; c < supported_codings->num; c++) {
955 coding = supported_codings->codings[c];
956 switch (coding) {
957 case DC1394_COLOR_CODING_MONO8:
958 video_format = GST_VIDEO_FORMAT_GRAY8;
959 break;
960 case DC1394_COLOR_CODING_YUV411:
961 video_format = GST_VIDEO_FORMAT_IYU1;
962 break;
963 case DC1394_COLOR_CODING_YUV422:
964 video_format = GST_VIDEO_FORMAT_UYVY;
965 break;
966 case DC1394_COLOR_CODING_YUV444:
967 video_format = GST_VIDEO_FORMAT_IYU2;
968 break;
969 case DC1394_COLOR_CODING_RGB8:
970 video_format = GST_VIDEO_FORMAT_RGB;
971 break;
972 case DC1394_COLOR_CODING_RAW8:
973 video_format = GST_VIDEO_FORMAT_UNKNOWN; /* GST_BAYER_FORMAT_XXXX8 */
974 break;
975 case DC1394_COLOR_CODING_MONO16:
976 video_format = GST_VIDEO_FORMAT_GRAY16_BE;
977 break;
978 /*
979 * The following formats do not exist in Gstreamer:
980 *case DC1394_COLOR_CODING_RGB16: // Unsigned RGB 16 bits per channel
981 * video_format = GST_VIDEO_FORMAT_RGB48;
982 * break;
983 *case DC1394_COLOR_CODING_MONO16S: // Signed grayscale 16 bits
984 * video_format = GST_VIDEO_FORMAT_GRAY16_BE_SIGNED;
985 * break;
986 *case DC1394_COLOR_CODING_RGB16S: // Signed RGB 16 bits per channel
987 * video_format = GST_VIDEO_FORMAT_RGB48_SIGNED;
988 * break;
989 *case DC1394_COLOR_CODING_RAW16: // Raw sensor output (bayer) 16 bits
990 * video_format = GST_VIDEO_FORMAT_UNKNOWN; // GST_BAYER_FORMAT_XXXX16_BE
991 * break;
992 */
993 default:
994 video_format = GST_VIDEO_FORMAT_UNKNOWN;
995 GST_DEBUG ("unsupported dc1394 video coding %d", coding);
996 }
997 if (video_format != GST_VIDEO_FORMAT_UNKNOWN) {
998 g_value_init (&formats, G_TYPE_STRING);
999 g_value_set_string (&formats, gst_video_format_to_string (video_format));
1000 structure = gst_structure_new_empty ("video/x-raw");
1001 gst_structure_set_value (structure, "format", &formats);
1002 gst_caps_append_structure (caps, structure);
1003 g_value_unset (&formats);
1004 }
1005 if (coding == DC1394_COLOR_CODING_MONO8 ||
1006 coding == DC1394_COLOR_CODING_RAW8) {
1007 g_value_init (&formats, GST_TYPE_LIST);
1008 g_value_init (&format, G_TYPE_STRING);
1009 g_value_set_static_string (&format, "bggr");
1010 gst_value_list_append_value (&formats, &format);
1011 g_value_set_static_string (&format, "rggb");
1012 gst_value_list_append_value (&formats, &format);
1013 g_value_set_static_string (&format, "grbg");
1014 gst_value_list_append_value (&formats, &format);
1015 g_value_set_static_string (&format, "gbrg");
1016 gst_value_list_append_value (&formats, &format);
1017 structure = gst_structure_new_empty ("video/x-bayer");
1018 gst_structure_set_value (structure, "format", &formats);
1019 gst_caps_append_structure (caps, structure);
1020 g_value_unset (&format);
1021 g_value_unset (&formats);
1022 }
1023 }
1024
1025 if (width_min == width_max) {
1026 g_value_init (&widths, G_TYPE_INT);
1027 g_value_set_int (&widths, width_min);
1028 } else if (width_step == 1) {
1029 g_value_init (&widths, GST_TYPE_INT_RANGE);
1030 gst_value_set_int_range (&widths, width_min, width_max);
1031 } else {
1032 g_value_init (&widths, GST_TYPE_LIST);
1033 g_value_init (&width, G_TYPE_INT);
1034 for (w = width_min; w <= width_max; w += width_step) {
1035 g_value_set_int (&width, w);
1036 gst_value_list_append_value (&widths, &width);
1037 }
1038 g_value_unset (&width);
1039 }
1040 if (height_min == height_max) {
1041 g_value_init (&heights, G_TYPE_INT);
1042 g_value_set_int (&heights, height_min);
1043 } else if (height_step == 1) {
1044 g_value_init (&heights, GST_TYPE_INT_RANGE);
1045 gst_value_set_int_range (&heights, height_min, height_max);
1046 } else {
1047 g_value_init (&heights, GST_TYPE_LIST);
1048 g_value_init (&height, G_TYPE_INT);
1049 for (h = height_min; h <= height_max; h += height_step) {
1050 g_value_set_int (&height, h);
1051 gst_value_list_append_value (&heights, &height);
1052 }
1053 g_value_unset (&height);
1054 }
1055 gst_caps_set_value (caps, "width", &widths);
1056 gst_caps_set_value (caps, "height", &heights);
1057 g_value_unset (&widths);
1058 g_value_unset (&heights);
1059
1060 if (supported_rates) {
1061 g_value_init (&framerates, GST_TYPE_LIST);
1062 g_value_init (&framerate, GST_TYPE_FRACTION);
1063 for (r = 0; r < supported_rates->num; r++) {
1064 rate = supported_rates->framerates[r];
1065 switch (rate) {
1066 case DC1394_FRAMERATE_1_875:
1067 gst_value_set_fraction (&framerate, 240, 128);
1068 break;
1069 case DC1394_FRAMERATE_3_75:
1070 gst_value_set_fraction (&framerate, 240, 64);
1071 break;
1072 case DC1394_FRAMERATE_7_5:
1073 gst_value_set_fraction (&framerate, 240, 32);
1074 break;
1075 case DC1394_FRAMERATE_15:
1076 gst_value_set_fraction (&framerate, 240, 16);
1077 break;
1078 case DC1394_FRAMERATE_30:
1079 gst_value_set_fraction (&framerate, 240, 8);
1080 break;
1081 case DC1394_FRAMERATE_60:
1082 gst_value_set_fraction (&framerate, 240, 4);
1083 break;
1084 case DC1394_FRAMERATE_120:
1085 gst_value_set_fraction (&framerate, 240, 2);
1086 break;
1087 case DC1394_FRAMERATE_240:
1088 gst_value_set_fraction (&framerate, 240, 1);
1089 break;
1090 }
1091 gst_value_list_append_value (&framerates, &framerate);
1092 }
1093 g_value_unset (&framerate);
1094 } else {
1095 g_value_init (&framerates, GST_TYPE_FRACTION_RANGE);
1096 gst_value_set_fraction_range_full (&framerates, 1, G_MAXINT, G_MAXINT, 1);
1097 }
1098 gst_caps_set_value (caps, "framerate", &framerates);
1099 g_value_unset (&framerates);
1100 return caps;
1101 }
1102
1103
1104 static gboolean
gst_dc1394_src_parse_caps(const GstCaps * caps,dc1394color_codings_t * color_codings,dc1394framerate_t * rate,double * rate_decimal,uint32_t * width,uint32_t * height)1105 gst_dc1394_src_parse_caps (const GstCaps * caps,
1106 dc1394color_codings_t * color_codings,
1107 dc1394framerate_t * rate, double *rate_decimal,
1108 uint32_t * width, uint32_t * height)
1109 {
1110 const GstStructure *structure;
1111 const gchar *format;
1112 gint w, h, num, den;
1113 gdouble dec;
1114
1115 structure = gst_caps_get_structure (caps, 0);
1116 if (!structure)
1117 goto error;
1118
1119 if (!gst_structure_get_int (structure, "width", &w)
1120 || !gst_structure_get_int (structure, "height", &h))
1121 goto error;
1122
1123 *width = w;
1124 *height = h;
1125
1126 if (!gst_structure_get_fraction (structure, "framerate", &num, &den))
1127 goto error;
1128
1129 if (gst_util_fraction_compare (num, den, 240, 128) <= 0) {
1130 *rate = DC1394_FRAMERATE_1_875;
1131 } else if (gst_util_fraction_compare (num, den, 240, 64) <= 0) {
1132 *rate = DC1394_FRAMERATE_3_75;
1133 } else if (gst_util_fraction_compare (num, den, 240, 32) <= 0) {
1134 *rate = DC1394_FRAMERATE_7_5;
1135 } else if (gst_util_fraction_compare (num, den, 240, 16) <= 0) {
1136 *rate = DC1394_FRAMERATE_15;
1137 } else if (gst_util_fraction_compare (num, den, 240, 8) <= 0) {
1138 *rate = DC1394_FRAMERATE_30;
1139 } else if (gst_util_fraction_compare (num, den, 240, 4) <= 0) {
1140 *rate = DC1394_FRAMERATE_60;
1141 } else if (gst_util_fraction_compare (num, den, 240, 2) <= 0) {
1142 *rate = DC1394_FRAMERATE_120;
1143 } else if (gst_util_fraction_compare (num, den, 240, 1) <= 0) {
1144 *rate = DC1394_FRAMERATE_240;
1145 } else {
1146 *rate = DC1394_FRAMERATE_240;
1147 }
1148
1149 gst_util_fraction_to_double (num, den, &dec);
1150 *rate_decimal = dec;
1151
1152 if (gst_structure_has_name (structure, "video/x-raw")) {
1153 format = gst_structure_get_string (structure, "format");
1154 switch (gst_video_format_from_string (format)) {
1155 case GST_VIDEO_FORMAT_GRAY8:
1156 color_codings->num = 1;
1157 color_codings->codings[0] = DC1394_COLOR_CODING_MONO8;
1158 break;
1159 case GST_VIDEO_FORMAT_IYU1:
1160 color_codings->num = 1;
1161 color_codings->codings[0] = DC1394_COLOR_CODING_YUV411;
1162 break;
1163 case GST_VIDEO_FORMAT_UYVY:
1164 color_codings->num = 1;
1165 color_codings->codings[0] = DC1394_COLOR_CODING_YUV422;
1166 break;
1167 case GST_VIDEO_FORMAT_IYU2:
1168 color_codings->num = 1;
1169 color_codings->codings[0] = DC1394_COLOR_CODING_YUV444;
1170 break;
1171 case GST_VIDEO_FORMAT_RGB:
1172 color_codings->num = 1;
1173 color_codings->codings[0] = DC1394_COLOR_CODING_RGB8;
1174 break;
1175 case GST_VIDEO_FORMAT_GRAY16_BE:
1176 color_codings->num = 1;
1177 color_codings->codings[0] = DC1394_COLOR_CODING_MONO16;
1178 break;
1179 /*
1180 * The following formats do not exist in Gstreamer:
1181 *case GST_VIDEO_FORMAT_RGB48: // Unsigned RGB format 16 bits per channel
1182 * color_codings->num = 1
1183 * color_codings->codings[0] = DC1394_COLOR_CODING_RGB16;
1184 * break;
1185 *case GST_VIDEO_FORMAT_GRAY16_BE_SIGNED: // Signed grayscale format 16 bits
1186 * color_codings->num = 1
1187 * color_codings->codings[0] = DC1394_COLOR_CODING_MONO16S;
1188 * break;
1189 *case GST_VIDEO_FORMAT_RGB48_SIGNED: // Signed RGB format 16 bits per channel
1190 * color_codings->num = 1
1191 * color_codings->codings[0] = DC1394_COLOR_CODING_RGB16S;
1192 * break;
1193 */
1194 default:
1195 GST_ERROR ("unsupported raw video format %s", format);
1196 goto error;
1197 }
1198 } else if (gst_structure_has_name (structure, "video/x-bayer")) {
1199 /*
1200 * The following formats do not exist in Gstreamer:
1201 *switch (gst_bayer_format_from_string(format)) {
1202 * case GST_BAYER_FORMAT_BGGR8:
1203 * case GST_BAYER_FORMAT_GBRG8:
1204 * case GST_BAYER_FORMAT_GRBG8:
1205 * case GST_BAYER_FORMAT_BGGR8:
1206 * *coding = DC1394_COLOR_CODING_RAW8;
1207 * break;
1208 * case GST_BAYER_FORMAT_BGGR16_BE:
1209 * case GST_BAYER_FORMAT_GBRG16_BE:
1210 * case GST_BAYER_FORMAT_GRBG16_BE:
1211 * case GST_BAYER_FORMAT_BGGR16_BE:
1212 * *coding = DC1394_COLOR_CODING_RAW16;
1213 * break;
1214 * default:
1215 * GST_ERROR("unsupported raw video format %s", format);
1216 * goto error;
1217 *}
1218 */
1219 color_codings->num = 2;
1220 color_codings->codings[0] = DC1394_COLOR_CODING_RAW8;
1221 color_codings->codings[1] = DC1394_COLOR_CODING_MONO8;
1222 } else {
1223 goto error;
1224 }
1225
1226 return TRUE;
1227
1228 error:
1229 return FALSE;
1230 }
1231
1232
1233 static gboolean
plugin_init(GstPlugin * plugin)1234 plugin_init (GstPlugin * plugin)
1235 {
1236 return GST_ELEMENT_REGISTER (dc1394src, plugin);
1237 }
1238
1239 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1240 GST_VERSION_MINOR,
1241 dc1394,
1242 "1394 IIDC video source",
1243 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
1244