Tizen 2.0 Release
[framework/multimedia/gst-plugins-good0.10.git] / ext / raw1394 / gstdv1394src.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *               <2000> Daniel Fischer <dan@f3c.com>
4  *               <2004> Wim Taymans <wim@fluendo.com>
5  *               <2006> Zaheer Abbas Merali <zaheerabbas at merali dot org>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 /**
23  * SECTION:element-dv1394src
24  *
25  * Read DV (digital video) data from firewire port.
26  *
27  * <refsect2>
28  * <title>Example launch line</title>
29  * |[
30  * gst-launch dv1394src ! queue ! dvdemux name=d ! queue ! dvdec ! xvimagesink d. ! queue ! alsasink
31  * ]| This pipeline captures from the firewire port and displays it (might need
32  * format converters for audio/video).
33  * </refsect2>
34  */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39 #include <unistd.h>
40 #include <sys/poll.h>
41 #include <sys/socket.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <string.h>
45 #include <stdlib.h>
46
47 #include <libavc1394/avc1394.h>
48 #include <libavc1394/avc1394_vcr.h>
49 #include <libavc1394/rom1394.h>
50 #include <libraw1394/raw1394.h>
51 #ifdef HAVE_LIBIEC61883
52 #include <libiec61883/iec61883.h>
53 #endif
54
55 #include <gst/gst.h>
56
57 #include "gstdv1394src.h"
58 #include "gst1394probe.h"
59 #include "gst1394clock.h"
60
61
62 #define CONTROL_STOP            'S'     /* stop the select call */
63 #define CONTROL_SOCKETS(src)   src->control_sock
64 #define WRITE_SOCKET(src)      src->control_sock[1]
65 #define READ_SOCKET(src)       src->control_sock[0]
66
67 #define SEND_COMMAND(src, command)          \
68 G_STMT_START {                              \
69   int G_GNUC_UNUSED _res; unsigned char c; c = command;   \
70   _res = write (WRITE_SOCKET(src), &c, 1);  \
71 } G_STMT_END
72
73 #define READ_COMMAND(src, command, res)        \
74 G_STMT_START {                                 \
75   res = read(READ_SOCKET(src), &command, 1);   \
76 } G_STMT_END
77
78
79 GST_DEBUG_CATEGORY_STATIC (dv1394src_debug);
80 #define GST_CAT_DEFAULT (dv1394src_debug)
81
82 #define PAL_FRAMESIZE 144000
83 #define PAL_FRAMERATE 25
84
85 #define NTSC_FRAMESIZE 120000
86 #define NTSC_FRAMERATE 30
87
88 enum
89 {
90   SIGNAL_FRAME_DROPPED,
91   /* FILL ME */
92   LAST_SIGNAL
93 };
94
95 #define DEFAULT_PORT    -1
96 #define DEFAULT_CHANNEL   63
97 #define DEFAULT_CONSECUTIVE 1
98 #define DEFAULT_SKIP    0
99 #define DEFAULT_DROP_INCOMPLETE TRUE
100 #define DEFAULT_USE_AVC   TRUE
101 #define DEFAULT_GUID    0
102
103 enum
104 {
105   PROP_0,
106   PROP_PORT,
107   PROP_CHANNEL,
108   PROP_CONSECUTIVE,
109   PROP_SKIP,
110   PROP_DROP_INCOMPLETE,
111   PROP_USE_AVC,
112   PROP_GUID,
113   PROP_DEVICE_NAME
114 };
115
116 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
117     GST_PAD_SRC,
118     GST_PAD_ALWAYS,
119     GST_STATIC_CAPS ("video/x-dv, "
120         "format = (string) { NTSC, PAL }, " "systemstream = (boolean) true")
121     );
122
123 static void gst_dv1394src_uri_handler_init (gpointer g_iface,
124     gpointer iface_data);
125
126 static void gst_dv1394src_set_property (GObject * object, guint prop_id,
127     const GValue * value, GParamSpec * pspec);
128 static void gst_dv1394src_get_property (GObject * object, guint prop_id,
129     GValue * value, GParamSpec * pspec);
130 static void gst_dv1394src_dispose (GObject * object);
131
132 static GstClock *gst_dv1394src_provide_clock (GstElement * element);
133 static GstStateChangeReturn gst_dv1394_src_change_state (GstElement * element,
134     GstStateChange transition);
135
136 static gboolean gst_dv1394src_start (GstBaseSrc * bsrc);
137 static gboolean gst_dv1394src_stop (GstBaseSrc * bsrc);
138 static gboolean gst_dv1394src_unlock (GstBaseSrc * bsrc);
139
140 static GstFlowReturn gst_dv1394src_create (GstPushSrc * psrc, GstBuffer ** buf);
141
142 static gboolean gst_dv1394src_query (GstBaseSrc * src, GstQuery * query);
143 static void gst_dv1394src_update_device_name (GstDV1394Src * src);
144
145 static void
146 _do_init (GType type)
147 {
148   static const GInterfaceInfo urihandler_info = {
149     gst_dv1394src_uri_handler_init,
150     NULL,
151     NULL,
152   };
153   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
154
155   gst_1394_type_add_property_probe_interface (type);
156
157   GST_DEBUG_CATEGORY_INIT (dv1394src_debug, "dv1394src", 0,
158       "DV firewire source");
159 }
160
161 GST_BOILERPLATE_FULL (GstDV1394Src, gst_dv1394src, GstPushSrc,
162     GST_TYPE_PUSH_SRC, _do_init);
163
164
165 static guint gst_dv1394src_signals[LAST_SIGNAL] = { 0 };
166
167
168 static void
169 gst_dv1394src_base_init (gpointer g_class)
170 {
171   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
172
173   gst_element_class_add_static_pad_template (element_class, &src_factory);
174
175   gst_element_class_set_details_simple (element_class,
176       "Firewire (1394) DV video source", "Source/Video",
177       "Source for DV video data from firewire port",
178       "Erik Walthinsen <omega@temple-baptist.com>, "
179       "Daniel Fischer <dan@f3c.com>, " "Wim Taymans <wim@fluendo.com>, "
180       "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
181 }
182
183 static void
184 gst_dv1394src_class_init (GstDV1394SrcClass * klass)
185 {
186   GObjectClass *gobject_class;
187   GstElementClass *gstelement_class;
188   GstBaseSrcClass *gstbasesrc_class;
189   GstPushSrcClass *gstpushsrc_class;
190
191   gobject_class = (GObjectClass *) klass;
192   gstelement_class = (GstElementClass *) klass;
193   gstbasesrc_class = (GstBaseSrcClass *) klass;
194   gstpushsrc_class = (GstPushSrcClass *) klass;
195
196   gobject_class->set_property = gst_dv1394src_set_property;
197   gobject_class->get_property = gst_dv1394src_get_property;
198   gobject_class->dispose = gst_dv1394src_dispose;
199
200   gstelement_class->provide_clock = gst_dv1394src_provide_clock;
201   gstelement_class->change_state = gst_dv1394_src_change_state;
202
203   gst_dv1394src_signals[SIGNAL_FRAME_DROPPED] =
204       g_signal_new ("frame-dropped", G_TYPE_FROM_CLASS (klass),
205       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDV1394SrcClass, frame_dropped),
206       NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
207
208   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PORT,
209       g_param_spec_int ("port", "Port", "Port number (-1 automatic)",
210           -1, 16, DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
211   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CHANNEL,
212       g_param_spec_int ("channel", "Channel", "Channel number for listening",
213           0, 64, DEFAULT_CHANNEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
214   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CONSECUTIVE,
215       g_param_spec_int ("consecutive", "consecutive frames",
216           "send n consecutive frames after skipping", 1, G_MAXINT,
217           DEFAULT_CONSECUTIVE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
218   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SKIP,
219       g_param_spec_int ("skip", "skip frames", "skip n frames",
220           0, G_MAXINT, DEFAULT_SKIP,
221           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
222   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DROP_INCOMPLETE,
223       g_param_spec_boolean ("drop-incomplete", "drop incomplete",
224           "drop incomplete frames", DEFAULT_DROP_INCOMPLETE,
225           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_USE_AVC,
227       g_param_spec_boolean ("use-avc", "Use AV/C", "Use AV/C VTR control",
228           DEFAULT_USE_AVC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
229   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_GUID,
230       g_param_spec_uint64 ("guid", "GUID",
231           "select one of multiple DV devices by its GUID. use a hexadecimal "
232           "like 0xhhhhhhhhhhhhhhhh. (0 = no guid)", 0, G_MAXUINT64,
233           DEFAULT_GUID, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
234   /**
235    * GstDV1394Src:device-name
236    *
237    * Descriptive name of the currently opened device
238    *
239    * Since: 0.10.7
240    **/
241   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE_NAME,
242       g_param_spec_string ("device-name", "device name",
243           "user-friendly name of the device", "Default",
244           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
245
246   gstbasesrc_class->negotiate = NULL;
247   gstbasesrc_class->start = gst_dv1394src_start;
248   gstbasesrc_class->stop = gst_dv1394src_stop;
249   gstbasesrc_class->unlock = gst_dv1394src_unlock;
250   gstbasesrc_class->query = gst_dv1394src_query;
251
252   gstpushsrc_class->create = gst_dv1394src_create;
253 }
254
255 static void
256 gst_dv1394src_init (GstDV1394Src * dv1394src, GstDV1394SrcClass * klass)
257 {
258   GstPad *srcpad = GST_BASE_SRC_PAD (dv1394src);
259
260   gst_base_src_set_live (GST_BASE_SRC (dv1394src), TRUE);
261   gst_base_src_set_format (GST_BASE_SRC (dv1394src), GST_FORMAT_TIME);
262   gst_base_src_set_do_timestamp (GST_BASE_SRC (dv1394src), TRUE);
263   gst_pad_use_fixed_caps (srcpad);
264
265   dv1394src->port = DEFAULT_PORT;
266   dv1394src->channel = DEFAULT_CHANNEL;
267
268   dv1394src->consecutive = DEFAULT_CONSECUTIVE;
269   dv1394src->skip = DEFAULT_SKIP;
270   dv1394src->drop_incomplete = DEFAULT_DROP_INCOMPLETE;
271   dv1394src->use_avc = DEFAULT_USE_AVC;
272   dv1394src->guid = DEFAULT_GUID;
273   dv1394src->uri = g_strdup_printf ("dv://%d", dv1394src->port);
274   dv1394src->device_name = g_strdup_printf ("Default");
275
276   READ_SOCKET (dv1394src) = -1;
277   WRITE_SOCKET (dv1394src) = -1;
278
279   /* initialized when first header received */
280   dv1394src->frame_size = 0;
281
282   dv1394src->buf = NULL;
283   dv1394src->frame = NULL;
284   dv1394src->frame_sequence = 0;
285
286   dv1394src->provided_clock = gst_1394_clock_new ("dv1394clock");
287 }
288
289 static void
290 gst_dv1394src_dispose (GObject * object)
291 {
292   GstDV1394Src *src = GST_DV1394SRC (object);
293
294   if (src->provided_clock) {
295     g_object_unref (src->provided_clock);
296   }
297
298   g_free (src->uri);
299   src->uri = NULL;
300
301   g_free (src->device_name);
302   src->device_name = NULL;
303
304   G_OBJECT_CLASS (parent_class)->dispose (object);
305 }
306
307 static void
308 gst_dv1394src_set_property (GObject * object, guint prop_id,
309     const GValue * value, GParamSpec * pspec)
310 {
311   GstDV1394Src *filter = GST_DV1394SRC (object);
312
313   switch (prop_id) {
314     case PROP_PORT:
315       filter->port = g_value_get_int (value);
316       g_free (filter->uri);
317       filter->uri = g_strdup_printf ("dv://%d", filter->port);
318       break;
319     case PROP_CHANNEL:
320       filter->channel = g_value_get_int (value);
321       break;
322     case PROP_SKIP:
323       filter->skip = g_value_get_int (value);
324       break;
325     case PROP_CONSECUTIVE:
326       filter->consecutive = g_value_get_int (value);
327       break;
328     case PROP_DROP_INCOMPLETE:
329       filter->drop_incomplete = g_value_get_boolean (value);
330       break;
331     case PROP_USE_AVC:
332       filter->use_avc = g_value_get_boolean (value);
333       break;
334     case PROP_GUID:
335       filter->guid = g_value_get_uint64 (value);
336       gst_dv1394src_update_device_name (filter);
337       break;
338     default:
339       break;
340   }
341 }
342
343 static void
344 gst_dv1394src_get_property (GObject * object, guint prop_id, GValue * value,
345     GParamSpec * pspec)
346 {
347   GstDV1394Src *filter = GST_DV1394SRC (object);
348
349   switch (prop_id) {
350     case PROP_PORT:
351       g_value_set_int (value, filter->port);
352       break;
353     case PROP_CHANNEL:
354       g_value_set_int (value, filter->channel);
355       break;
356     case PROP_SKIP:
357       g_value_set_int (value, filter->skip);
358       break;
359     case PROP_CONSECUTIVE:
360       g_value_set_int (value, filter->consecutive);
361       break;
362     case PROP_DROP_INCOMPLETE:
363       g_value_set_boolean (value, filter->drop_incomplete);
364       break;
365     case PROP_USE_AVC:
366       g_value_set_boolean (value, filter->use_avc);
367       break;
368     case PROP_GUID:
369       g_value_set_uint64 (value, filter->guid);
370       break;
371     case PROP_DEVICE_NAME:
372       g_value_set_string (value, filter->device_name);
373       break;
374     default:
375       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
376       break;
377   }
378 }
379
380 static GstClock *
381 gst_dv1394src_provide_clock (GstElement * element)
382 {
383   GstDV1394Src *dv1394src = GST_DV1394SRC (element);
384
385   return GST_CLOCK_CAST (gst_object_ref (dv1394src->provided_clock));
386 }
387
388 static GstStateChangeReturn
389 gst_dv1394_src_change_state (GstElement * element, GstStateChange transition)
390 {
391   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
392   GstDV1394Src *src = GST_DV1394SRC (element);
393
394   switch (transition) {
395     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
396       gst_element_post_message (element,
397           gst_message_new_clock_lost (GST_OBJECT_CAST (element),
398               GST_CLOCK_CAST (src->provided_clock)));
399       break;
400     default:
401       break;
402   }
403
404   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
405   if (ret == GST_STATE_CHANGE_FAILURE)
406     return ret;
407
408   switch (transition) {
409     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
410       gst_element_post_message (element,
411           gst_message_new_clock_provide (GST_OBJECT_CAST (element),
412               GST_CLOCK_CAST (src->provided_clock), TRUE));
413       break;
414     default:
415       break;
416   }
417
418   return ret;
419 }
420
421 #ifdef HAVE_LIBIEC61883
422 static GstDV1394Src *
423 gst_dv1394src_from_raw1394handle (raw1394handle_t handle)
424 {
425   iec61883_dv_t dv = (iec61883_dv_t) raw1394_get_userdata (handle);
426   iec61883_dv_fb_t dv_fb =
427       (iec61883_dv_fb_t) iec61883_dv_get_callback_data (dv);
428   return GST_DV1394SRC (iec61883_dv_fb_get_callback_data (dv_fb));
429 }
430 #else /* HAVE_LIBIEC61883 */
431 static GstDV1394Src *
432 gst_dv1394src_from_raw1394handle (raw1394handle_t handle)
433 {
434   return GST_DV1394SRC (raw1394_get_userdata (handle));
435 }
436 #endif /* HAVE_LIBIEC61883 */
437
438 #ifdef HAVE_LIBIEC61883
439 static int
440 gst_dv1394src_iec61883_receive (unsigned char *data, int len,
441     int complete, void *cbdata)
442 {
443   GstDV1394Src *dv1394src = GST_DV1394SRC (cbdata);
444
445   if (G_UNLIKELY (!GST_PAD_CAPS (GST_BASE_SRC_PAD (dv1394src)))) {
446     GstCaps *caps;
447     unsigned char *p = data;
448
449     // figure format (NTSC/PAL)
450     if (p[3] & 0x80) {
451       // PAL
452       dv1394src->frame_size = PAL_FRAMESIZE;
453       dv1394src->frame_rate = PAL_FRAMERATE;
454       GST_DEBUG ("PAL data");
455       caps = gst_caps_new_simple ("video/x-dv",
456           "format", G_TYPE_STRING, "PAL",
457           "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
458     } else {
459       // NTSC (untested)
460       dv1394src->frame_size = NTSC_FRAMESIZE;
461       dv1394src->frame_rate = NTSC_FRAMERATE;
462       GST_DEBUG
463           ("NTSC data [untested] - please report success/failure to <dan@f3c.com>");
464       caps = gst_caps_new_simple ("video/x-dv",
465           "format", G_TYPE_STRING, "NTSC",
466           "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
467     }
468     gst_pad_set_caps (GST_BASE_SRC_PAD (dv1394src), caps);
469     gst_caps_unref (caps);
470   }
471
472   dv1394src->frame = NULL;
473   if (G_LIKELY ((dv1394src->frame_sequence + 1) % (dv1394src->skip +
474               dv1394src->consecutive) < dv1394src->consecutive)) {
475     if (complete && len == dv1394src->frame_size) {
476       guint8 *bufdata;
477       GstBuffer *buf;
478
479       buf = gst_buffer_new_and_alloc (dv1394src->frame_size);
480
481       GST_BUFFER_OFFSET (buf) = dv1394src->frame_sequence;
482       bufdata = GST_BUFFER_DATA (buf);
483       memcpy (bufdata, data, len);
484       dv1394src->buf = buf;
485     }
486   }
487   dv1394src->frame_sequence++;
488   return 0;
489 }
490
491 #else
492 static int
493 gst_dv1394src_iso_receive (raw1394handle_t handle, int channel, size_t len,
494     quadlet_t * data)
495 {
496   GstDV1394Src *dv1394src = gst_dv1394src_from_raw1394handle (handle);
497
498   if (len > 16) {
499     /*
500        the following code taken from kino-0.51 (Dan Dennedy/Charles Yates)
501        Kindly relicensed under the LGPL. See the commit log for version 1.6 of
502        this file in CVS.
503      */
504     unsigned char *p = (unsigned char *) &data[3];
505
506     int section_type = p[0] >> 5;       /* section type is in bits 5 - 7 */
507     int dif_sequence = p[1] >> 4;       /* dif sequence number is in bits 4 - 7 */
508     int dif_block = p[2];
509
510     /* if we are at the beginning of a frame, 
511        we set buf=frame, and alloc a new buffer for frame
512      */
513     if (section_type == 0 && dif_sequence == 0) {       // dif header
514       if (!GST_PAD_CAPS (GST_BASE_SRC_PAD (dv1394src))) {
515         GstCaps *caps;
516
517         // figure format (NTSC/PAL)
518         if (p[3] & 0x80) {
519           // PAL
520           dv1394src->frame_size = PAL_FRAMESIZE;
521           dv1394src->frame_rate = PAL_FRAMERATE;
522           GST_DEBUG ("PAL data");
523           caps = gst_caps_new_simple ("video/x-dv",
524               "format", G_TYPE_STRING, "PAL",
525               "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
526         } else {
527           // NTSC (untested)
528           dv1394src->frame_size = NTSC_FRAMESIZE;
529           dv1394src->frame_rate = NTSC_FRAMERATE;
530           GST_DEBUG
531               ("NTSC data [untested] - please report success/failure to <dan@f3c.com>");
532           caps = gst_caps_new_simple ("video/x-dv",
533               "format", G_TYPE_STRING, "NTSC",
534               "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
535         }
536         gst_pad_set_caps (GST_BASE_SRC_PAD (dv1394src), caps);
537         gst_caps_unref (caps);
538       }
539       // drop last frame when not complete
540       if (!dv1394src->drop_incomplete
541           || dv1394src->bytes_in_frame == dv1394src->frame_size) {
542         dv1394src->buf = dv1394src->frame;
543       } else {
544         GST_INFO_OBJECT (GST_ELEMENT (dv1394src), "incomplete frame dropped");
545         g_signal_emit (G_OBJECT (dv1394src),
546             gst_dv1394src_signals[SIGNAL_FRAME_DROPPED], 0);
547         if (dv1394src->frame) {
548           gst_buffer_unref (dv1394src->frame);
549         }
550       }
551       if ((dv1394src->frame_sequence + 1) % (dv1394src->skip +
552               dv1394src->consecutive) < dv1394src->consecutive) {
553         GstBuffer *buf;
554         gint64 i64;
555
556         buf = gst_buffer_new_and_alloc (dv1394src->frame_size);
557
558         /* fill in offset, duration, timestamp */
559         GST_BUFFER_OFFSET (buf) = dv1394src->frame_sequence;
560         dv1394src->frame = buf;
561       }
562       dv1394src->frame_sequence++;
563       dv1394src->bytes_in_frame = 0;
564     }
565
566     if (dv1394src->frame != NULL) {
567       guint8 *data = GST_BUFFER_DATA (dv1394src->frame);
568
569       switch (section_type) {
570         case 0:                /* 1 Header block */
571           /* p[3] |= 0x80; // hack to force PAL data */
572           memcpy (data + dif_sequence * 150 * 80, p, 480);
573           break;
574
575         case 1:                /* 2 Subcode blocks */
576           memcpy (data + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p,
577               480);
578           break;
579
580         case 2:                /* 3 VAUX blocks */
581           memcpy (data + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p,
582               480);
583           break;
584
585         case 3:                /* 9 Audio blocks interleaved with video */
586           memcpy (data + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p,
587               480);
588           break;
589
590         case 4:                /* 135 Video blocks interleaved with audio */
591           memcpy (data + dif_sequence * 150 * 80 + (7 + (dif_block / 15) +
592                   dif_block) * 80, p, 480);
593           break;
594
595         default:               /* we can't handle any other data */
596           break;
597       }
598       dv1394src->bytes_in_frame += 480;
599     }
600   }
601
602   return 0;
603 }
604 #endif
605 /*
606  * When an ieee1394 bus reset happens, usually a device has been removed
607  * or added.  We send a message on the message bus with the node count 
608  * and whether the capture device used in this element connected, disconnected 
609  * or was unchanged
610  * Message structure:
611  * nodecount - integer with number of nodes on bus
612  * current-device-change - integer (1 if device connected, 0 if no change to
613  *                         current device status, -1 if device disconnected)
614  */
615 static int
616 gst_dv1394src_bus_reset (raw1394handle_t handle, unsigned int generation)
617 {
618   GstDV1394Src *src;
619   gint nodecount;
620   GstMessage *message;
621   GstStructure *structure;
622   gint current_device_change;
623   gint i;
624
625   src = gst_dv1394src_from_raw1394handle (handle);
626
627   GST_INFO_OBJECT (src, "have bus reset");
628
629   /* update generation - told to do so by docs */
630   raw1394_update_generation (handle, generation);
631   nodecount = raw1394_get_nodecount (handle);
632   /* allocate memory for portinfo */
633
634   /* current_device_change is -1 if camera disconnected, 0 if other device
635    * connected or 1 if camera has now connected */
636   current_device_change = -1;
637   for (i = 0; i < nodecount; i++) {
638     if (src->guid == rom1394_get_guid (handle, i)) {
639       /* Camera is with us */
640       GST_DEBUG ("Camera is with us");
641       if (!src->connected) {
642         current_device_change = 1;
643         src->connected = TRUE;
644       } else
645         current_device_change = 0;
646     }
647   }
648   if (src->connected && current_device_change == -1) {
649     GST_DEBUG ("Camera has disconnected");
650     src->connected = FALSE;
651   } else if (!src->connected && current_device_change == -1) {
652     GST_DEBUG ("Camera is still not with us");
653     current_device_change = 0;
654   }
655
656   structure = gst_structure_new ("ieee1394-bus-reset", "nodecount", G_TYPE_INT,
657       nodecount, "current-device-change", G_TYPE_INT, current_device_change,
658       NULL);
659   message = gst_message_new_element (GST_OBJECT (src), structure);
660   gst_element_post_message (GST_ELEMENT (src), message);
661
662   return 0;
663 }
664
665 static GstFlowReturn
666 gst_dv1394src_create (GstPushSrc * psrc, GstBuffer ** buf)
667 {
668   GstDV1394Src *dv1394src = GST_DV1394SRC (psrc);
669   GstCaps *caps;
670   struct pollfd pollfds[2];
671
672   pollfds[0].fd = raw1394_get_fd (dv1394src->handle);
673   pollfds[0].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
674   pollfds[1].fd = READ_SOCKET (dv1394src);
675   pollfds[1].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
676
677   if (G_UNLIKELY (dv1394src->buf)) {
678     /* maybe we had an error before, and there's a stale buffer? */
679     gst_buffer_unref (dv1394src->buf);
680     dv1394src->buf = NULL;
681   }
682
683   while (TRUE) {
684     int res = poll (pollfds, 2, -1);
685
686     if (G_UNLIKELY (res < 0)) {
687       if (errno == EAGAIN || errno == EINTR)
688         continue;
689       else
690         goto error_while_polling;
691     }
692
693     if (G_UNLIKELY (pollfds[1].revents)) {
694       char command;
695
696       if (pollfds[1].revents & POLLIN)
697         READ_COMMAND (dv1394src, command, res);
698
699       goto told_to_stop;
700     } else if (G_LIKELY (pollfds[0].revents & POLLIN)) {
701       /* shouldn't block in theory */
702       raw1394_loop_iterate (dv1394src->handle);
703
704       if (dv1394src->buf)
705         break;
706     }
707   }
708
709   g_assert (dv1394src->buf);
710
711   caps = gst_pad_get_caps (GST_BASE_SRC_PAD (psrc));
712   gst_buffer_set_caps (dv1394src->buf, caps);
713   gst_caps_unref (caps);
714
715   *buf = dv1394src->buf;
716   dv1394src->buf = NULL;
717   return GST_FLOW_OK;
718
719 error_while_polling:
720   {
721     GST_ELEMENT_ERROR (dv1394src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
722     return GST_FLOW_UNEXPECTED;
723   }
724 told_to_stop:
725   {
726     GST_DEBUG_OBJECT (dv1394src, "told to stop, shutting down");
727     return GST_FLOW_WRONG_STATE;
728   }
729 }
730
731 static int
732 gst_dv1394src_discover_avc_node (GstDV1394Src * src)
733 {
734   int node = -1;
735   int i, j = 0;
736   int m = src->num_ports;
737
738   if (src->port >= 0) {
739     /* search on explicit port */
740     j = src->port;
741     m = j + 1;
742   }
743
744   /* loop over all our ports */
745   for (; j < m && node == -1; j++) {
746     raw1394handle_t handle;
747     struct raw1394_portinfo pinf[16];
748
749     /* open the port */
750     handle = raw1394_new_handle ();
751     if (!handle) {
752       GST_WARNING ("raw1394 - failed to get handle: %s.\n", strerror (errno));
753       continue;
754     }
755     if (raw1394_get_port_info (handle, pinf, 16) < 0) {
756       GST_WARNING ("raw1394 - failed to get port info: %s.\n",
757           strerror (errno));
758       goto next;
759     }
760
761     /* tell raw1394 which host adapter to use */
762     if (raw1394_set_port (handle, j) < 0) {
763       GST_WARNING ("raw1394 - failed to set set port: %s.\n", strerror (errno));
764       goto next;
765     }
766
767     /* now loop over all the nodes */
768     for (i = 0; i < raw1394_get_nodecount (handle); i++) {
769       /* are we looking for an explicit GUID ? */
770       if (src->guid != 0) {
771         if (src->guid == rom1394_get_guid (handle, i)) {
772           node = i;
773           src->port = j;
774           g_free (src->uri);
775           src->uri = g_strdup_printf ("dv://%d", src->port);
776           break;
777         }
778       } else {
779         rom1394_directory rom_dir;
780
781         /* select first AV/C Tape Recorder Player node */
782         if (rom1394_get_directory (handle, i, &rom_dir) < 0) {
783           GST_WARNING ("error reading config rom directory for node %d\n", i);
784           continue;
785         }
786         if ((rom1394_get_node_type (&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
787             avc1394_check_subunit_type (handle, i, AVC1394_SUBUNIT_TYPE_VCR)) {
788           node = i;
789           src->port = j;
790           src->guid = rom1394_get_guid (handle, i);
791           g_free (src->uri);
792           src->uri = g_strdup_printf ("dv://%d", src->port);
793           g_free (src->device_name);
794           src->device_name = g_strdup (rom_dir.label);
795           break;
796         }
797         rom1394_free_directory (&rom_dir);
798       }
799     }
800   next:
801     raw1394_destroy_handle (handle);
802   }
803   return node;
804 }
805
806 static gboolean
807 gst_dv1394src_start (GstBaseSrc * bsrc)
808 {
809   GstDV1394Src *src = GST_DV1394SRC (bsrc);
810   int control_sock[2];
811
812   src->connected = FALSE;
813
814   if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
815     goto socket_pair;
816
817   READ_SOCKET (src) = control_sock[0];
818   WRITE_SOCKET (src) = control_sock[1];
819
820   fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK);
821   fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK);
822
823   src->handle = raw1394_new_handle ();
824
825   if (!src->handle) {
826     if (errno == EACCES)
827       goto permission_denied;
828     else if (errno == ENOENT)
829       goto not_found;
830     else
831       goto no_handle;
832   }
833
834   src->num_ports = raw1394_get_port_info (src->handle, src->pinfo, 16);
835
836   if (src->num_ports == 0)
837     goto no_ports;
838
839   if (src->use_avc || src->port == -1)
840     src->avc_node = gst_dv1394src_discover_avc_node (src);
841
842   /* lets destroy handle and create one on port
843      this is more reliable than setting port on
844      the existing handle */
845   raw1394_destroy_handle (src->handle);
846   src->handle = raw1394_new_handle_on_port (src->port);
847   if (!src->handle)
848     goto cannot_set_port;
849
850   raw1394_set_userdata (src->handle, src);
851   raw1394_set_bus_reset_handler (src->handle, gst_dv1394src_bus_reset);
852
853 #ifdef HAVE_LIBIEC61883
854   if ((src->iec61883dv =
855           iec61883_dv_fb_init (src->handle,
856               gst_dv1394src_iec61883_receive, src)) == NULL)
857     goto cannot_initialise_dv;
858
859 #else
860   raw1394_set_iso_handler (src->handle, src->channel,
861       gst_dv1394src_iso_receive);
862 #endif
863
864   GST_DEBUG_OBJECT (src, "successfully opened up 1394 connection");
865   src->connected = TRUE;
866
867 #ifdef HAVE_LIBIEC61883
868   if (iec61883_dv_fb_start (src->iec61883dv, src->channel) != 0)
869     goto cannot_start;
870 #else
871   if (raw1394_start_iso_rcv (src->handle, src->channel) < 0)
872     goto cannot_start;
873 #endif
874
875   if (src->use_avc) {
876     raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);
877
878     /* start the VCR */
879     if (avc_handle) {
880       if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
881           && avc1394_vcr_is_playing (avc_handle, src->avc_node)
882           != AVC1394_VCR_OPERAND_PLAY_FORWARD)
883         avc1394_vcr_play (avc_handle, src->avc_node);
884       raw1394_destroy_handle (avc_handle);
885     } else {
886       GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
887           g_strerror (errno));
888     }
889   }
890
891   gst_1394_clock_set_handle (src->provided_clock, src->handle);
892
893   return TRUE;
894
895 socket_pair:
896   {
897     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
898         GST_ERROR_SYSTEM);
899     return FALSE;
900   }
901 permission_denied:
902   {
903     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
904     return FALSE;
905   }
906 not_found:
907   {
908     GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), GST_ERROR_SYSTEM);
909     return FALSE;
910   }
911 no_handle:
912   {
913     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
914         ("can't get raw1394 handle (%s)", g_strerror (errno)));
915     return FALSE;
916   }
917 no_ports:
918   {
919     raw1394_destroy_handle (src->handle);
920     src->handle = NULL;
921     GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
922         ("no ports available for raw1394"));
923     return FALSE;
924   }
925 cannot_set_port:
926   {
927     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
928         ("can't set 1394 port %d", src->port));
929     return FALSE;
930   }
931 cannot_start:
932   {
933     raw1394_destroy_handle (src->handle);
934     src->handle = NULL;
935 #ifdef HAVE_LIBIEC61883
936     iec61883_dv_fb_close (src->iec61883dv);
937     src->iec61883dv = NULL;
938 #endif
939     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
940         ("can't start 1394 iso receive"));
941     return FALSE;
942   }
943 #ifdef HAVE_LIBIEC61883
944 cannot_initialise_dv:
945   {
946     raw1394_destroy_handle (src->handle);
947     src->handle = NULL;
948     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
949         ("can't initialise iec61883 dv"));
950     return FALSE;
951   }
952 #endif
953 }
954
955 static gboolean
956 gst_dv1394src_stop (GstBaseSrc * bsrc)
957 {
958   GstDV1394Src *src = GST_DV1394SRC (bsrc);
959
960   close (READ_SOCKET (src));
961   close (WRITE_SOCKET (src));
962   READ_SOCKET (src) = -1;
963   WRITE_SOCKET (src) = -1;
964 #ifdef HAVE_LIBIEC61883
965   iec61883_dv_fb_close (src->iec61883dv);
966 #else
967   raw1394_stop_iso_rcv (src->handle, src->channel);
968 #endif
969
970   if (src->use_avc) {
971     raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);
972
973     /* pause and stop the VCR */
974     if (avc_handle) {
975       if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
976           && (avc1394_vcr_is_playing (avc_handle, src->avc_node)
977               != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE))
978         avc1394_vcr_pause (avc_handle, src->avc_node);
979       avc1394_vcr_stop (avc_handle, src->avc_node);
980       raw1394_destroy_handle (avc_handle);
981     } else {
982       GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
983           g_strerror (errno));
984     }
985   }
986
987   gst_1394_clock_unset_handle (src->provided_clock);
988
989   raw1394_destroy_handle (src->handle);
990
991   return TRUE;
992 }
993
994 static gboolean
995 gst_dv1394src_unlock (GstBaseSrc * bsrc)
996 {
997   GstDV1394Src *src = GST_DV1394SRC (bsrc);
998
999   SEND_COMMAND (src, CONTROL_STOP);
1000
1001   return TRUE;
1002 }
1003
1004 static gboolean
1005 gst_dv1394src_query (GstBaseSrc * basesrc, GstQuery * query)
1006 {
1007   switch (GST_QUERY_TYPE (query)) {
1008     case GST_QUERY_LATENCY:
1009     {
1010       gst_query_set_latency (query, TRUE, GST_SECOND / 25, GST_CLOCK_TIME_NONE);
1011     }
1012       break;
1013     default:
1014       goto not_supported;
1015   }
1016
1017   return TRUE;
1018
1019 not_supported:
1020   return GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
1021 }
1022
1023 static void
1024 gst_dv1394src_update_device_name (GstDV1394Src * src)
1025 {
1026   raw1394handle_t handle;
1027   gint portcount, port, nodecount, node;
1028   rom1394_directory directory;
1029
1030   g_free (src->device_name);
1031   src->device_name = NULL;
1032
1033   GST_LOG_OBJECT (src, "updating device name for current GUID");
1034
1035   handle = raw1394_new_handle ();
1036
1037   if (handle == NULL)
1038     goto gethandle_failed;
1039
1040   portcount = raw1394_get_port_info (handle, NULL, 0);
1041   for (port = 0; port < portcount; port++) {
1042     if (raw1394_set_port (handle, port) >= 0) {
1043       nodecount = raw1394_get_nodecount (handle);
1044       for (node = 0; node < nodecount; node++) {
1045         if (src->guid == rom1394_get_guid (handle, node)) {
1046           if (rom1394_get_directory (handle, node, &directory) >= 0) {
1047             g_free (src->device_name);
1048             src->device_name = g_strdup (directory.label);
1049             rom1394_free_directory (&directory);
1050             goto done;
1051           } else {
1052             GST_WARNING ("error reading rom directory for node %d", node);
1053           }
1054         }
1055       }
1056     }
1057   }
1058
1059   src->device_name = g_strdup ("Unknown");      /* FIXME: translate? */
1060
1061 done:
1062
1063   raw1394_destroy_handle (handle);
1064   return;
1065
1066 /* ERRORS */
1067 gethandle_failed:
1068   {
1069     GST_WARNING ("failed to get raw1394 handle: %s", g_strerror (errno));
1070     src->device_name = g_strdup ("Unknown");    /* FIXME: translate? */
1071     return;
1072   }
1073 }
1074
1075 /*** GSTURIHANDLER INTERFACE *************************************************/
1076
1077 static guint
1078 gst_dv1394src_uri_get_type (void)
1079 {
1080   return GST_URI_SRC;
1081 }
1082
1083 static gchar **
1084 gst_dv1394src_uri_get_protocols (void)
1085 {
1086   static gchar *protocols[] = { (char *) "dv", NULL };
1087
1088   return protocols;
1089 }
1090
1091 static const gchar *
1092 gst_dv1394src_uri_get_uri (GstURIHandler * handler)
1093 {
1094   GstDV1394Src *gst_dv1394src = GST_DV1394SRC (handler);
1095
1096   return gst_dv1394src->uri;
1097 }
1098
1099 static gboolean
1100 gst_dv1394src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
1101 {
1102   gchar *protocol, *location;
1103   gboolean ret = TRUE;
1104   GstDV1394Src *gst_dv1394src = GST_DV1394SRC (handler);
1105
1106   protocol = gst_uri_get_protocol (uri);
1107   if (strcmp (protocol, "dv") != 0) {
1108     g_free (protocol);
1109     return FALSE;
1110   }
1111   g_free (protocol);
1112
1113   location = gst_uri_get_location (uri);
1114   if (location && *location != '\0')
1115     gst_dv1394src->port = strtol (location, NULL, 10);
1116   else
1117     gst_dv1394src->port = DEFAULT_PORT;
1118   g_free (location);
1119   g_free (gst_dv1394src->uri);
1120   gst_dv1394src->uri = g_strdup_printf ("dv://%d", gst_dv1394src->port);
1121
1122   return ret;
1123 }
1124
1125 static void
1126 gst_dv1394src_uri_handler_init (gpointer g_iface, gpointer iface_data)
1127 {
1128   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
1129
1130   iface->get_type = gst_dv1394src_uri_get_type;
1131   iface->get_protocols = gst_dv1394src_uri_get_protocols;
1132   iface->get_uri = gst_dv1394src_uri_get_uri;
1133   iface->set_uri = gst_dv1394src_uri_set_uri;
1134 }