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