• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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