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