upload tizen1.0 source
[framework/multimedia/gst-plugins-good0.10.git] / ext / raw1394 / gsthdv1394src.c
1 /* GStreamer
2  * Copyright (C) <2008> Edward Hervey <bilboed@bilboed.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 /**
20  * SECTION:element-hdv1394src
21  *
22  * Read MPEG-TS data from firewire port.
23  *
24  * <refsect2>
25  * <title>Example launch line</title>
26  * |[
27  * gst-launch hdv1394src ! queue ! decodebin name=d ! queue ! xvimagesink d. ! queue ! alsasink
28  * ]| captures from the firewire port and plays the streams.
29  * |[
30  * gst-launch hdv1394src ! queue ! filesink location=mydump.ts
31  * ]| capture to a disk file
32  * </refsect2>
33  */
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 #include <unistd.h>
39 #include <sys/poll.h>
40 #include <sys/socket.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <string.h>
44 #include <stdlib.h>
45
46 #include <libavc1394/avc1394.h>
47 #include <libavc1394/avc1394_vcr.h>
48 #include <libavc1394/rom1394.h>
49 #include <libraw1394/raw1394.h>
50 #include <libiec61883/iec61883.h>
51
52 #include <gst/gst.h>
53
54 #include "gsthdv1394src.h"
55 #include "gst1394probe.h"
56
57
58 #define CONTROL_STOP            'S'     /* stop the select call */
59 #define CONTROL_SOCKETS(src)   src->control_sock
60 #define WRITE_SOCKET(src)      src->control_sock[1]
61 #define READ_SOCKET(src)       src->control_sock[0]
62
63 #define SEND_COMMAND(src, command)          \
64 G_STMT_START {                              \
65   int G_GNUC_UNUSED _res; unsigned char c; c = command;   \
66   _res = write (WRITE_SOCKET(src), &c, 1);  \
67 } G_STMT_END
68
69 #define READ_COMMAND(src, command, res)        \
70 G_STMT_START {                                 \
71   res = read(READ_SOCKET(src), &command, 1);   \
72 } G_STMT_END
73
74
75 GST_DEBUG_CATEGORY_STATIC (hdv1394src_debug);
76 #define GST_CAT_DEFAULT (hdv1394src_debug)
77
78 #define DEFAULT_PORT    -1
79 #define DEFAULT_CHANNEL   63
80 #define DEFAULT_USE_AVC   TRUE
81 #define DEFAULT_GUID    0
82
83 enum
84 {
85   PROP_0,
86   PROP_PORT,
87   PROP_CHANNEL,
88   PROP_USE_AVC,
89   PROP_GUID,
90   PROP_DEVICE_NAME
91 };
92
93 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
94     GST_PAD_SRC,
95     GST_PAD_ALWAYS,
96     GST_STATIC_CAPS
97     ("video/mpegts,systemstream=(boolean)true,packetsize=(int)188")
98     );
99
100 static void gst_hdv1394src_uri_handler_init (gpointer g_iface,
101     gpointer iface_data);
102
103 static void gst_hdv1394src_set_property (GObject * object, guint prop_id,
104     const GValue * value, GParamSpec * pspec);
105 static void gst_hdv1394src_get_property (GObject * object, guint prop_id,
106     GValue * value, GParamSpec * pspec);
107 static void gst_hdv1394src_dispose (GObject * object);
108
109 static gboolean gst_hdv1394src_start (GstBaseSrc * bsrc);
110 static gboolean gst_hdv1394src_stop (GstBaseSrc * bsrc);
111 static gboolean gst_hdv1394src_unlock (GstBaseSrc * bsrc);
112
113 static GstFlowReturn gst_hdv1394src_create (GstPushSrc * psrc,
114     GstBuffer ** buf);
115
116 static void gst_hdv1394src_update_device_name (GstHDV1394Src * src);
117
118 static void
119 _do_init (GType type)
120 {
121   static const GInterfaceInfo urihandler_info = {
122     gst_hdv1394src_uri_handler_init,
123     NULL,
124     NULL,
125   };
126   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
127
128   gst_1394_type_add_property_probe_interface (type);
129
130   GST_DEBUG_CATEGORY_INIT (hdv1394src_debug, "hdv1394src", 0,
131       "MPEG-TS firewire source");
132 }
133
134 GST_BOILERPLATE_FULL (GstHDV1394Src, gst_hdv1394src, GstPushSrc,
135     GST_TYPE_PUSH_SRC, _do_init);
136
137
138 static void
139 gst_hdv1394src_base_init (gpointer g_class)
140 {
141   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
142
143   gst_element_class_add_pad_template (element_class,
144       gst_static_pad_template_get (&src_factory));
145
146   gst_element_class_set_details_simple (element_class,
147       "Firewire (1394) HDV video source", "Source/Video",
148       "Source for MPEG-TS video data from firewire port",
149       "Edward Hervey <bilboed@bilboed.com>");
150 }
151
152 static void
153 gst_hdv1394src_class_init (GstHDV1394SrcClass * klass)
154 {
155   GObjectClass *gobject_class;
156   GstBaseSrcClass *gstbasesrc_class;
157   GstPushSrcClass *gstpushsrc_class;
158
159   gobject_class = (GObjectClass *) klass;
160   gstbasesrc_class = (GstBaseSrcClass *) klass;
161   gstpushsrc_class = (GstPushSrcClass *) klass;
162
163   gobject_class->set_property = gst_hdv1394src_set_property;
164   gobject_class->get_property = gst_hdv1394src_get_property;
165   gobject_class->dispose = gst_hdv1394src_dispose;
166
167   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PORT,
168       g_param_spec_int ("port", "Port", "Port number (-1 automatic)",
169           -1, 16, DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
170   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CHANNEL,
171       g_param_spec_int ("channel", "Channel", "Channel number for listening",
172           0, 64, DEFAULT_CHANNEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
173   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_USE_AVC,
174       g_param_spec_boolean ("use-avc", "Use AV/C", "Use AV/C VTR control",
175           DEFAULT_USE_AVC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
176   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_GUID,
177       g_param_spec_uint64 ("guid", "GUID",
178           "select one of multiple DV devices by its GUID. use a hexadecimal "
179           "like 0xhhhhhhhhhhhhhhhh. (0 = no guid)", 0, G_MAXUINT64,
180           DEFAULT_GUID, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
181   /**
182    * GstHDV1394Src:device-name
183    *
184    * Descriptive name of the currently opened device
185    *
186    * Since: 0.10.7
187    **/
188   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE_NAME,
189       g_param_spec_string ("device-name", "device name",
190           "user-friendly name of the device", "Default",
191           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
192
193   gstbasesrc_class->negotiate = NULL;
194   gstbasesrc_class->start = gst_hdv1394src_start;
195   gstbasesrc_class->stop = gst_hdv1394src_stop;
196   gstbasesrc_class->unlock = gst_hdv1394src_unlock;
197
198   gstpushsrc_class->create = gst_hdv1394src_create;
199 }
200
201 static void
202 gst_hdv1394src_init (GstHDV1394Src * dv1394src, GstHDV1394SrcClass * klass)
203 {
204   GstPad *srcpad = GST_BASE_SRC_PAD (dv1394src);
205
206   gst_base_src_set_live (GST_BASE_SRC (dv1394src), TRUE);
207   gst_pad_use_fixed_caps (srcpad);
208
209   dv1394src->port = DEFAULT_PORT;
210   dv1394src->channel = DEFAULT_CHANNEL;
211
212   dv1394src->use_avc = DEFAULT_USE_AVC;
213   dv1394src->guid = DEFAULT_GUID;
214   dv1394src->uri = g_strdup_printf ("hdv://%d", dv1394src->port);
215   dv1394src->device_name = g_strdup_printf ("Default");
216
217   READ_SOCKET (dv1394src) = -1;
218   WRITE_SOCKET (dv1394src) = -1;
219
220   dv1394src->frame_sequence = 0;
221 }
222
223 static void
224 gst_hdv1394src_dispose (GObject * object)
225 {
226   GstHDV1394Src *src = GST_HDV1394SRC (object);
227
228   g_free (src->uri);
229   src->uri = NULL;
230
231   g_free (src->device_name);
232   src->device_name = NULL;
233
234   G_OBJECT_CLASS (parent_class)->dispose (object);
235 }
236
237 static void
238 gst_hdv1394src_set_property (GObject * object, guint prop_id,
239     const GValue * value, GParamSpec * pspec)
240 {
241   GstHDV1394Src *filter = GST_HDV1394SRC (object);
242
243   switch (prop_id) {
244     case PROP_PORT:
245       filter->port = g_value_get_int (value);
246       g_free (filter->uri);
247       filter->uri = g_strdup_printf ("hdv://%d", filter->port);
248       break;
249     case PROP_CHANNEL:
250       filter->channel = g_value_get_int (value);
251       break;
252     case PROP_USE_AVC:
253       filter->use_avc = g_value_get_boolean (value);
254       break;
255     case PROP_GUID:
256       filter->guid = g_value_get_uint64 (value);
257       gst_hdv1394src_update_device_name (filter);
258       break;
259     default:
260       break;
261   }
262 }
263
264 static void
265 gst_hdv1394src_get_property (GObject * object, guint prop_id, GValue * value,
266     GParamSpec * pspec)
267 {
268   GstHDV1394Src *filter = GST_HDV1394SRC (object);
269
270   switch (prop_id) {
271     case PROP_PORT:
272       g_value_set_int (value, filter->port);
273       break;
274     case PROP_CHANNEL:
275       g_value_set_int (value, filter->channel);
276       break;
277     case PROP_USE_AVC:
278       g_value_set_boolean (value, filter->use_avc);
279       break;
280     case PROP_GUID:
281       g_value_set_uint64 (value, filter->guid);
282       break;
283     case PROP_DEVICE_NAME:
284       g_value_set_string (value, filter->device_name);
285       break;
286     default:
287       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
288       break;
289   }
290 }
291
292 static GstHDV1394Src *
293 gst_hdv1394src_from_raw1394handle (raw1394handle_t handle)
294 {
295   iec61883_mpeg2_t mpeg2 = (iec61883_mpeg2_t) raw1394_get_userdata (handle);
296   return GST_HDV1394SRC (iec61883_mpeg2_get_callback_data (mpeg2));
297 }
298
299 /* Within one loop iteration (which may call _receive() many times), it seems
300  * as though '*data' will always be different.
301  *
302  * We can therefore assume that any '*data' given to us will stay allocated until
303  * the next loop iteration.
304  */
305
306 static int
307 gst_hdv1394src_iec61883_receive (unsigned char *data, int len,
308     unsigned int dropped, void *cbdata)
309 {
310   GstHDV1394Src *dv1394src = GST_HDV1394SRC (cbdata);
311
312   GST_LOG ("data:%p, len:%d, dropped:%d", data, len, dropped);
313
314   /* error out if we don't have enough room ! */
315   if (G_UNLIKELY (dv1394src->outoffset > (2048 * 188 - len)))
316     return -1;
317
318   if (G_LIKELY (len == IEC61883_MPEG2_TSP_SIZE)) {
319     memcpy ((guint8 *) dv1394src->outdata + dv1394src->outoffset, data, len);
320     dv1394src->outoffset += len;
321   }
322   dv1394src->frame_sequence++;
323   return 0;
324 }
325
326 /*
327  * When an ieee1394 bus reset happens, usually a device has been removed
328  * or added.  We send a message on the message bus with the node count 
329  * and whether the capture device used in this element connected, disconnected 
330  * or was unchanged
331  * Message structure:
332  * nodecount - integer with number of nodes on bus
333  * current-device-change - integer (1 if device connected, 0 if no change to
334  *                         current device status, -1 if device disconnected)
335  */
336 static int
337 gst_hdv1394src_bus_reset (raw1394handle_t handle, unsigned int generation)
338 {
339   GstHDV1394Src *src;
340   gint nodecount;
341   GstMessage *message;
342   GstStructure *structure;
343   gint current_device_change;
344   gint i;
345
346   src = gst_hdv1394src_from_raw1394handle (handle);
347
348   GST_INFO_OBJECT (src, "have bus reset");
349
350   /* update generation - told to do so by docs */
351   raw1394_update_generation (handle, generation);
352   nodecount = raw1394_get_nodecount (handle);
353   /* allocate memory for portinfo */
354
355   /* current_device_change is -1 if camera disconnected, 0 if other device
356    * connected or 1 if camera has now connected */
357   current_device_change = -1;
358   for (i = 0; i < nodecount; i++) {
359     if (src->guid == rom1394_get_guid (handle, i)) {
360       /* Camera is with us */
361       GST_DEBUG ("Camera is with us");
362       if (!src->connected) {
363         current_device_change = 1;
364         src->connected = TRUE;
365       } else
366         current_device_change = 0;
367     }
368   }
369   if (src->connected && current_device_change == -1) {
370     GST_DEBUG ("Camera has disconnected");
371     src->connected = FALSE;
372   } else if (!src->connected && current_device_change == -1) {
373     GST_DEBUG ("Camera is still not with us");
374     current_device_change = 0;
375   }
376
377   structure = gst_structure_new ("ieee1394-bus-reset", "nodecount", G_TYPE_INT,
378       nodecount, "current-device-change", G_TYPE_INT, current_device_change,
379       NULL);
380   message = gst_message_new_element (GST_OBJECT (src), structure);
381   gst_element_post_message (GST_ELEMENT (src), message);
382
383   return 0;
384 }
385
386 static GstFlowReturn
387 gst_hdv1394src_create (GstPushSrc * psrc, GstBuffer ** buf)
388 {
389   GstHDV1394Src *dv1394src = GST_HDV1394SRC (psrc);
390   GstCaps *caps;
391   struct pollfd pollfds[2];
392
393   pollfds[0].fd = raw1394_get_fd (dv1394src->handle);
394   pollfds[0].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
395   pollfds[1].fd = READ_SOCKET (dv1394src);
396   pollfds[1].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
397
398   /* allocate a 2048 samples buffer */
399   dv1394src->outdata = g_malloc (2048 * 188);
400   dv1394src->outoffset = 0;
401
402   GST_DEBUG ("Create...");
403
404   while (TRUE) {
405     int res = poll (pollfds, 2, -1);
406
407     GST_LOG ("res:%d", res);
408
409     if (G_UNLIKELY (res < 0)) {
410       if (errno == EAGAIN || errno == EINTR)
411         continue;
412       else
413         goto error_while_polling;
414     }
415
416     if (G_UNLIKELY (pollfds[1].revents)) {
417       char command;
418
419       if (pollfds[1].revents & POLLIN)
420         READ_COMMAND (dv1394src, command, res);
421
422       goto told_to_stop;
423     } else if (G_LIKELY (pollfds[0].revents & POLLIN)) {
424       int pt;
425
426       pt = dv1394src->frame_sequence;
427       /* shouldn't block in theory */
428       GST_LOG ("Iterating ! (%d)", dv1394src->frame_sequence);
429       raw1394_loop_iterate (dv1394src->handle);
430       GST_LOG ("After iteration : %d (diff:%d)",
431           dv1394src->frame_sequence, dv1394src->frame_sequence - pt);
432       if (dv1394src->outoffset)
433         break;
434     }
435   }
436
437   g_assert (dv1394src->outoffset);
438
439   GST_LOG ("We have some frames (%u bytes)", (guint) dv1394src->outoffset);
440
441   /* Create the buffer */
442   *buf = gst_buffer_new ();
443   GST_BUFFER_DATA (*buf) = dv1394src->outdata;
444   GST_BUFFER_MALLOCDATA (*buf) = dv1394src->outdata;
445   GST_BUFFER_SIZE (*buf) = dv1394src->outoffset;
446   dv1394src->outdata = NULL;
447   dv1394src->outoffset = 0;
448
449   caps = gst_pad_get_caps (GST_BASE_SRC_PAD (psrc));
450   gst_buffer_set_caps (*buf, caps);
451   gst_caps_unref (caps);
452
453   return GST_FLOW_OK;
454
455 error_while_polling:
456   {
457     GST_ELEMENT_ERROR (dv1394src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
458     return GST_FLOW_UNEXPECTED;
459   }
460 told_to_stop:
461   {
462     GST_DEBUG_OBJECT (dv1394src, "told to stop, shutting down");
463     return GST_FLOW_WRONG_STATE;
464   }
465 }
466
467 static int
468 gst_hdv1394src_discover_avc_node (GstHDV1394Src * src)
469 {
470   int node = -1;
471   int i, j = 0;
472   int m = src->num_ports;
473
474   if (src->port >= 0) {
475     /* search on explicit port */
476     j = src->port;
477     m = j + 1;
478   }
479
480   /* loop over all our ports */
481   for (; j < m && node == -1; j++) {
482     raw1394handle_t handle;
483     struct raw1394_portinfo pinf[16];
484
485     /* open the port */
486     handle = raw1394_new_handle ();
487     if (!handle) {
488       GST_WARNING ("raw1394 - failed to get handle: %s.\n", strerror (errno));
489       continue;
490     }
491     if (raw1394_get_port_info (handle, pinf, 16) < 0) {
492       GST_WARNING ("raw1394 - failed to get port info: %s.\n",
493           strerror (errno));
494       goto next;
495     }
496
497     /* tell raw1394 which host adapter to use */
498     if (raw1394_set_port (handle, j) < 0) {
499       GST_WARNING ("raw1394 - failed to set set port: %s.\n", strerror (errno));
500       goto next;
501     }
502
503     /* now loop over all the nodes */
504     for (i = 0; i < raw1394_get_nodecount (handle); i++) {
505       /* are we looking for an explicit GUID ? */
506       if (src->guid != 0) {
507         if (src->guid == rom1394_get_guid (handle, i)) {
508           node = i;
509           src->port = j;
510           g_free (src->uri);
511           src->uri = g_strdup_printf ("dv://%d", src->port);
512           break;
513         }
514       } else {
515         rom1394_directory rom_dir;
516
517         /* select first AV/C Tape Recorder Player node */
518         if (rom1394_get_directory (handle, i, &rom_dir) < 0) {
519           GST_WARNING ("error reading config rom directory for node %d\n", i);
520           continue;
521         }
522         if ((rom1394_get_node_type (&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
523             avc1394_check_subunit_type (handle, i, AVC1394_SUBUNIT_TYPE_VCR)) {
524           node = i;
525           src->port = j;
526           src->guid = rom1394_get_guid (handle, i);
527           g_free (src->uri);
528           src->uri = g_strdup_printf ("dv://%d", src->port);
529           g_free (src->device_name);
530           src->device_name = g_strdup (rom_dir.label);
531           break;
532         }
533         rom1394_free_directory (&rom_dir);
534       }
535     }
536   next:
537     raw1394_destroy_handle (handle);
538   }
539   return node;
540 }
541
542 static gboolean
543 gst_hdv1394src_start (GstBaseSrc * bsrc)
544 {
545   GstHDV1394Src *src = GST_HDV1394SRC (bsrc);
546   int control_sock[2];
547
548   src->connected = FALSE;
549
550   if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
551     goto socket_pair;
552
553   READ_SOCKET (src) = control_sock[0];
554   WRITE_SOCKET (src) = control_sock[1];
555
556   fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK);
557   fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK);
558
559   src->handle = raw1394_new_handle ();
560
561   if (!src->handle) {
562     if (errno == EACCES)
563       goto permission_denied;
564     else if (errno == ENOENT)
565       goto not_found;
566     else
567       goto no_handle;
568   }
569
570   src->num_ports = raw1394_get_port_info (src->handle, src->pinfo, 16);
571
572   if (src->num_ports == 0)
573     goto no_ports;
574
575   if (src->use_avc || src->port == -1)
576     src->avc_node = gst_hdv1394src_discover_avc_node (src);
577
578   /* lets destroy handle and create one on port
579      this is more reliable than setting port on
580      the existing handle */
581   raw1394_destroy_handle (src->handle);
582   src->handle = raw1394_new_handle_on_port (src->port);
583   if (!src->handle)
584     goto cannot_set_port;
585
586   raw1394_set_userdata (src->handle, src);
587   raw1394_set_bus_reset_handler (src->handle, gst_hdv1394src_bus_reset);
588
589   if ((src->iec61883mpeg2 =
590           iec61883_mpeg2_recv_init (src->handle,
591               gst_hdv1394src_iec61883_receive, src)) == NULL)
592     goto cannot_initialise_dv;
593
594 #if 0
595   raw1394_set_iso_handler (src->handle, src->channel,
596       gst_hdv1394src_iso_receive);
597 #endif
598
599   GST_DEBUG_OBJECT (src, "successfully opened up 1394 connection");
600   src->connected = TRUE;
601
602   if (iec61883_mpeg2_recv_start (src->iec61883mpeg2, src->channel) != 0)
603     goto cannot_start;
604 #if 0
605   if (raw1394_start_iso_rcv (src->handle, src->channel) < 0)
606     goto cannot_start;
607 #endif
608
609   if (src->use_avc) {
610     raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);
611
612     GST_LOG ("We have an avc_handle");
613
614     /* start the VCR */
615     if (avc_handle) {
616       if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
617           && avc1394_vcr_is_playing (avc_handle, src->avc_node)
618           != AVC1394_VCR_OPERAND_PLAY_FORWARD) {
619         GST_LOG ("Calling avc1394_vcr_play()");
620         avc1394_vcr_play (avc_handle, src->avc_node);
621       }
622       raw1394_destroy_handle (avc_handle);
623     } else {
624       GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
625           g_strerror (errno));
626     }
627   }
628
629   return TRUE;
630
631 socket_pair:
632   {
633     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
634         GST_ERROR_SYSTEM);
635     return FALSE;
636   }
637 permission_denied:
638   {
639     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
640     return FALSE;
641   }
642 not_found:
643   {
644     GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), GST_ERROR_SYSTEM);
645     return FALSE;
646   }
647 no_handle:
648   {
649     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
650         ("can't get raw1394 handle (%s)", g_strerror (errno)));
651     return FALSE;
652   }
653 no_ports:
654   {
655     raw1394_destroy_handle (src->handle);
656     src->handle = NULL;
657     GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
658         ("no ports available for raw1394"));
659     return FALSE;
660   }
661 cannot_set_port:
662   {
663     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
664         ("can't set 1394 port %d", src->port));
665     return FALSE;
666   }
667 cannot_start:
668   {
669     raw1394_destroy_handle (src->handle);
670     src->handle = NULL;
671     iec61883_mpeg2_close (src->iec61883mpeg2);
672     src->iec61883mpeg2 = NULL;
673     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
674         ("can't start 1394 iso receive"));
675     return FALSE;
676   }
677 cannot_initialise_dv:
678   {
679     raw1394_destroy_handle (src->handle);
680     src->handle = NULL;
681     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
682         ("can't initialise iec61883 hdv"));
683     return FALSE;
684   }
685 }
686
687 static gboolean
688 gst_hdv1394src_stop (GstBaseSrc * bsrc)
689 {
690   GstHDV1394Src *src = GST_HDV1394SRC (bsrc);
691
692   close (READ_SOCKET (src));
693   close (WRITE_SOCKET (src));
694   READ_SOCKET (src) = -1;
695   WRITE_SOCKET (src) = -1;
696
697   iec61883_mpeg2_close (src->iec61883mpeg2);
698 #if 0
699   raw1394_stop_iso_rcv (src->handle, src->channel);
700 #endif
701
702   if (src->use_avc) {
703     raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);
704
705     /* pause and stop the VCR */
706     if (avc_handle) {
707       if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
708           && (avc1394_vcr_is_playing (avc_handle, src->avc_node)
709               != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE))
710         avc1394_vcr_pause (avc_handle, src->avc_node);
711       avc1394_vcr_stop (avc_handle, src->avc_node);
712       raw1394_destroy_handle (avc_handle);
713     } else {
714       GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
715           g_strerror (errno));
716     }
717   }
718
719   raw1394_destroy_handle (src->handle);
720
721   return TRUE;
722 }
723
724 static gboolean
725 gst_hdv1394src_unlock (GstBaseSrc * bsrc)
726 {
727   GstHDV1394Src *src = GST_HDV1394SRC (bsrc);
728
729   SEND_COMMAND (src, CONTROL_STOP);
730
731   return TRUE;
732 }
733
734 static void
735 gst_hdv1394src_update_device_name (GstHDV1394Src * src)
736 {
737   raw1394handle_t handle;
738   gint portcount, port, nodecount, node;
739   rom1394_directory directory;
740
741   g_free (src->device_name);
742   src->device_name = NULL;
743
744   GST_LOG_OBJECT (src, "updating device name for current GUID");
745
746   handle = raw1394_new_handle ();
747
748   if (handle == NULL)
749     goto gethandle_failed;
750
751   portcount = raw1394_get_port_info (handle, NULL, 0);
752   for (port = 0; port < portcount; port++) {
753     if (raw1394_set_port (handle, port) >= 0) {
754       nodecount = raw1394_get_nodecount (handle);
755       for (node = 0; node < nodecount; node++) {
756         if (src->guid == rom1394_get_guid (handle, node)) {
757           if (rom1394_get_directory (handle, node, &directory) >= 0) {
758             g_free (src->device_name);
759             src->device_name = g_strdup (directory.label);
760             rom1394_free_directory (&directory);
761             goto done;
762           } else {
763             GST_WARNING ("error reading rom directory for node %d", node);
764           }
765         }
766       }
767     }
768   }
769
770   src->device_name = g_strdup ("Unknown");      /* FIXME: translate? */
771
772 done:
773
774   raw1394_destroy_handle (handle);
775   return;
776
777 /* ERRORS */
778 gethandle_failed:
779   {
780     GST_WARNING ("failed to get raw1394 handle: %s", g_strerror (errno));
781     src->device_name = g_strdup ("Unknown");    /* FIXME: translate? */
782     return;
783   }
784 }
785
786 /*** GSTURIHANDLER INTERFACE *************************************************/
787
788 static guint
789 gst_hdv1394src_uri_get_type (void)
790 {
791   return GST_URI_SRC;
792 }
793
794 static gchar **
795 gst_hdv1394src_uri_get_protocols (void)
796 {
797   static gchar *protocols[] = { (char *) "hdv", NULL };
798
799   return protocols;
800 }
801
802 static const gchar *
803 gst_hdv1394src_uri_get_uri (GstURIHandler * handler)
804 {
805   GstHDV1394Src *gst_hdv1394src = GST_HDV1394SRC (handler);
806
807   return gst_hdv1394src->uri;
808 }
809
810 static gboolean
811 gst_hdv1394src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
812 {
813   gchar *protocol, *location;
814   gboolean ret = TRUE;
815   GstHDV1394Src *gst_hdv1394src = GST_HDV1394SRC (handler);
816
817   protocol = gst_uri_get_protocol (uri);
818   if (strcmp (protocol, "hdv") != 0) {
819     g_free (protocol);
820     return FALSE;
821   }
822   g_free (protocol);
823
824   location = gst_uri_get_location (uri);
825   if (location && *location != '\0')
826     gst_hdv1394src->port = strtol (location, NULL, 10);
827   else
828     gst_hdv1394src->port = DEFAULT_PORT;
829   g_free (location);
830   g_free (gst_hdv1394src->uri);
831   gst_hdv1394src->uri = g_strdup_printf ("hdv://%d", gst_hdv1394src->port);
832
833   return ret;
834 }
835
836 static void
837 gst_hdv1394src_uri_handler_init (gpointer g_iface, gpointer iface_data)
838 {
839   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
840
841   iface->get_type = gst_hdv1394src_uri_get_type;
842   iface->get_protocols = gst_hdv1394src_uri_get_protocols;
843   iface->get_uri = gst_hdv1394src_uri_get_uri;
844   iface->set_uri = gst_hdv1394src_uri_set_uri;
845 }