Way, way, way too many files: Remove crack comment from the 2000 era.
[platform/upstream/gst-plugins-good.git] / ext / raw1394 / gstdv1394src.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2 /* GStreamer
3  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4  *               <2000> Daniel Fischer <dan@f3c.com>
5  *               <2004> Wim Taymans <wim@fluendo.com>
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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include <gst/gst.h>
27 #include <string.h>
28 #include <libavc1394/avc1394.h>
29 #include <libavc1394/avc1394_vcr.h>
30 #include <libavc1394/rom1394.h>
31
32 #include "gstdv1394src.h"
33
34 GST_DEBUG_CATEGORY_STATIC (dv1394src_debug);
35 #define GST_CAT_DEFAULT (dv1394src_debug)
36
37 #define PAL_FRAMESIZE 144000
38 #define PAL_FRAMERATE 25
39
40 #define NTSC_FRAMESIZE 120000
41 #define NTSC_FRAMERATE 30
42
43 /* Filter signals and args */
44 enum
45 {
46   SIGNAL_FRAME_DROPPED,
47   /* FILL ME */
48   LAST_SIGNAL
49 };
50
51 #define DEFAULT_PORT            -1
52 #define DEFAULT_CHANNEL         63
53 #define DEFAULT_CONSECUTIVE     1
54 #define DEFAULT_SKIP            0
55 #define DEFAULT_DROP_INCOMPLETE TRUE
56 #define DEFAULT_USE_AVC         TRUE
57 #define DEFAULT_GUID            0
58
59 enum
60 {
61   ARG_0,
62   ARG_PORT,
63   ARG_CHANNEL,
64   ARG_CONSECUTIVE,
65   ARG_SKIP,
66   ARG_DROP_INCOMPLETE,
67   ARG_USE_AVC,
68   ARG_GUID
69 };
70
71 static GstElementDetails gst_dv1394src_details =
72 GST_ELEMENT_DETAILS ("Firewire (1394) DV Source",
73     "Source/Video",
74     "Source for DV video data from firewire port",
75     "Erik Walthinsen <omega@temple-baptist.com>\n"
76     "Daniel Fischer <dan@f3c.com>\n" "Wim Taymans <wim@fluendo.com>");
77
78 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
79     GST_PAD_SRC,
80     GST_PAD_ALWAYS,
81     GST_STATIC_CAPS ("video/x-dv, "
82         "format = (string) { NTSC, PAL }, " "systemstream = (boolean) true")
83     );
84
85 static void gst_dv1394src_base_init (gpointer g_class);
86 static void gst_dv1394src_class_init (GstDV1394SrcClass * klass);
87 static void gst_dv1394src_init (GstDV1394Src * filter);
88 static void gst_dv1394src_dispose (GObject * obj);
89
90 static void gst_dv1394src_set_property (GObject * object, guint prop_id,
91     const GValue * value, GParamSpec * pspec);
92 static void gst_dv1394src_get_property (GObject * object, guint prop_id,
93     GValue * value, GParamSpec * pspec);
94
95 static GstElementStateReturn gst_dv1394src_change_state (GstElement * element);
96
97 static GstData *gst_dv1394src_get (GstPad * pad);
98
99 static const GstEventMask *gst_dv1394src_get_event_mask (GstPad * pad);
100 static gboolean gst_dv1394src_event (GstPad * pad, GstEvent * event);
101 static const GstFormat *gst_dv1394src_get_formats (GstPad * pad);
102 static gboolean gst_dv1394src_convert (GstPad * pad,
103     GstFormat src_format, gint64 src_value,
104     GstFormat * dest_format, gint64 * dest_value);
105
106 static const GstQueryType *gst_dv1394src_get_query_types (GstPad * pad);
107 static gboolean gst_dv1394src_query (GstPad * pad, GstQueryType type,
108     GstFormat * format, gint64 * value);
109
110
111 static GstElementClass *parent_class = NULL;
112
113 static void gst_dv1394src_uri_handler_init (gpointer g_iface,
114     gpointer iface_data);
115
116 static guint gst_dv1394src_signals[LAST_SIGNAL] = { 0 };
117
118 GType
119 gst_dv1394src_get_type (void)
120 {
121   static GType gst_dv1394src_type = 0;
122
123   if (!gst_dv1394src_type) {
124     static const GTypeInfo gst_dv1394src_info = {
125       sizeof (GstDV1394Src),
126       gst_dv1394src_base_init,
127       NULL,
128       (GClassInitFunc) gst_dv1394src_class_init,
129       NULL,
130       NULL,
131       sizeof (GstDV1394Src),
132       0,
133       (GInstanceInitFunc) gst_dv1394src_init,
134     };
135     static const GInterfaceInfo urihandler_info = {
136       gst_dv1394src_uri_handler_init,
137       NULL,
138       NULL,
139     };
140
141     gst_dv1394src_type =
142         g_type_register_static (GST_TYPE_ELEMENT, "DV1394Src",
143         &gst_dv1394src_info, 0);
144
145     g_type_add_interface_static (gst_dv1394src_type, GST_TYPE_URI_HANDLER,
146         &urihandler_info);
147
148     GST_DEBUG_CATEGORY_INIT (dv1394src_debug, "dv1394src", 0,
149         "DV firewire source");
150   }
151   return gst_dv1394src_type;
152 }
153
154 static void
155 gst_dv1394src_base_init (gpointer g_class)
156 {
157   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
158
159   gst_element_class_add_pad_template (element_class,
160       gst_static_pad_template_get (&src_factory));
161
162   gst_element_class_set_details (element_class, &gst_dv1394src_details);
163 }
164
165 static void
166 gst_dv1394src_class_init (GstDV1394SrcClass * klass)
167 {
168   GObjectClass *gobject_class;
169   GstElementClass *gstelement_class;
170
171   gobject_class = (GObjectClass *) klass;
172   gstelement_class = (GstElementClass *) klass;
173
174   gst_dv1394src_signals[SIGNAL_FRAME_DROPPED] =
175       g_signal_new ("frame-dropped", G_TYPE_FROM_CLASS (klass),
176       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDV1394SrcClass, frame_dropped),
177       NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
178
179   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
180       g_param_spec_int ("port", "Port", "Port number (-1 automatic)",
181           -1, 16, DEFAULT_PORT, G_PARAM_READWRITE));
182   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHANNEL,
183       g_param_spec_int ("channel", "Channel", "Channel number for listening",
184           0, 64, DEFAULT_CHANNEL, G_PARAM_READWRITE));
185   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CONSECUTIVE,
186       g_param_spec_int ("consecutive", "consecutive frames",
187           "send n consecutive frames after skipping", 1, G_MAXINT,
188           DEFAULT_CONSECUTIVE, G_PARAM_READWRITE));
189   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP,
190       g_param_spec_int ("skip", "skip frames", "skip n frames",
191           0, G_MAXINT, DEFAULT_SKIP, G_PARAM_READWRITE));
192   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DROP_INCOMPLETE,
193       g_param_spec_boolean ("drop_incomplete", "drop_incomplete",
194           "drop incomplete frames", DEFAULT_DROP_INCOMPLETE,
195           G_PARAM_READWRITE));
196   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_USE_AVC,
197       g_param_spec_boolean ("use-avc", "Use AV/C", "Use AV/C VTR control",
198           DEFAULT_USE_AVC, G_PARAM_READWRITE));
199   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GUID,
200       g_param_spec_uint64 ("guid", "GUID",
201           "select one of multiple DV devices by its GUID. use a hexadecimal "
202           "like 0xhhhhhhhhhhhhhhhh. (0 = no guid)", 0, G_MAXUINT64,
203           DEFAULT_GUID, G_PARAM_READWRITE));
204
205   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
206
207   gobject_class->set_property = gst_dv1394src_set_property;
208   gobject_class->get_property = gst_dv1394src_get_property;
209   gobject_class->dispose = gst_dv1394src_dispose;
210
211   gstelement_class->change_state = gst_dv1394src_change_state;
212 }
213
214 static void
215 gst_dv1394src_init (GstDV1394Src * dv1394src)
216 {
217   dv1394src->srcpad =
218       gst_pad_new_from_template (gst_element_get_pad_template (GST_ELEMENT
219           (dv1394src), "src"), "src");
220   gst_pad_set_get_function (dv1394src->srcpad, gst_dv1394src_get);
221   gst_pad_use_explicit_caps (dv1394src->srcpad);
222   gst_pad_set_event_function (dv1394src->srcpad, gst_dv1394src_event);
223   gst_pad_set_event_mask_function (dv1394src->srcpad,
224       gst_dv1394src_get_event_mask);
225   gst_pad_set_convert_function (dv1394src->srcpad, gst_dv1394src_convert);
226   gst_pad_set_query_function (dv1394src->srcpad, gst_dv1394src_query);
227   gst_pad_set_query_type_function (dv1394src->srcpad,
228       gst_dv1394src_get_query_types);
229   gst_pad_set_formats_function (dv1394src->srcpad, gst_dv1394src_get_formats);
230
231   gst_element_add_pad (GST_ELEMENT (dv1394src), dv1394src->srcpad);
232
233   dv1394src->port = DEFAULT_PORT;
234   dv1394src->channel = DEFAULT_CHANNEL;
235
236   dv1394src->consecutive = DEFAULT_CONSECUTIVE;
237   dv1394src->skip = DEFAULT_SKIP;
238   dv1394src->drop_incomplete = DEFAULT_DROP_INCOMPLETE;
239   dv1394src->use_avc = DEFAULT_USE_AVC;
240   dv1394src->guid = DEFAULT_GUID;
241
242   /* initialized when first header received */
243   dv1394src->frame_size = 0;
244
245   dv1394src->buf = NULL;
246   dv1394src->frame = NULL;
247   dv1394src->frame_sequence = 0;
248 }
249
250 static void
251 gst_dv1394src_dispose (GObject * obj)
252 {
253   GstDV1394Src *dv1394src;
254
255   dv1394src = GST_DV1394SRC (obj);
256
257   G_OBJECT_CLASS (parent_class)->dispose (obj);
258 }
259
260 static void
261 gst_dv1394src_set_property (GObject * object, guint prop_id,
262     const GValue * value, GParamSpec * pspec)
263 {
264   GstDV1394Src *filter;
265
266   g_return_if_fail (GST_IS_DV1394SRC (object));
267   filter = GST_DV1394SRC (object);
268
269   switch (prop_id) {
270     case ARG_PORT:
271       filter->port = g_value_get_int (value);
272       break;
273     case ARG_CHANNEL:
274       filter->channel = g_value_get_int (value);
275       break;
276     case ARG_SKIP:
277       filter->skip = g_value_get_int (value);
278       break;
279     case ARG_CONSECUTIVE:
280       filter->consecutive = g_value_get_int (value);
281       break;
282     case ARG_DROP_INCOMPLETE:
283       filter->drop_incomplete = g_value_get_boolean (value);
284       break;
285     case ARG_USE_AVC:
286       filter->use_avc = g_value_get_boolean (value);
287       break;
288     case ARG_GUID:
289       filter->guid = g_value_get_uint64 (value);
290       break;
291     default:
292       break;
293   }
294 }
295
296 static void
297 gst_dv1394src_get_property (GObject * object, guint prop_id, GValue * value,
298     GParamSpec * pspec)
299 {
300   GstDV1394Src *filter;
301
302   g_return_if_fail (GST_IS_DV1394SRC (object));
303   filter = GST_DV1394SRC (object);
304
305   switch (prop_id) {
306     case ARG_PORT:
307       g_value_set_int (value, filter->port);
308       break;
309     case ARG_CHANNEL:
310       g_value_set_int (value, filter->channel);
311       break;
312     case ARG_SKIP:
313       g_value_set_int (value, filter->skip);
314       break;
315     case ARG_CONSECUTIVE:
316       g_value_set_int (value, filter->consecutive);
317       break;
318     case ARG_DROP_INCOMPLETE:
319       g_value_set_boolean (value, filter->drop_incomplete);
320       break;
321     case ARG_USE_AVC:
322       g_value_set_boolean (value, filter->use_avc);
323       break;
324     case ARG_GUID:
325       g_value_set_uint64 (value, filter->guid);
326       break;
327     default:
328       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
329       break;
330   }
331 }
332
333 static int
334 gst_dv1394src_iso_receive (raw1394handle_t handle, int channel, size_t len,
335     quadlet_t * data)
336 {
337   GstDV1394Src *dv1394src = GST_DV1394SRC (raw1394_get_userdata (handle));
338
339   if (len > 16) {
340     /*
341        the following code taken from kino-0.51 (Dan Dennedy/Charles Yates)
342      */
343     unsigned char *p = (unsigned char *) &data[3];
344     int section_type = p[0] >> 5;       /* section type is in bits 5 - 7 */
345     int dif_sequence = p[1] >> 4;       /* dif sequence number is in bits 4 - 7 */
346     int dif_block = p[2];
347
348     /* if we are at the beginning of a frame, 
349        we set buf=frame, and alloc a new buffer for frame
350      */
351
352     if (section_type == 0 && dif_sequence == 0) {       // dif header
353
354       if (!dv1394src->negotiated) {
355         // figure format (NTSC/PAL)
356         if (p[3] & 0x80) {
357           // PAL
358           dv1394src->frame_size = PAL_FRAMESIZE;
359           dv1394src->frame_rate = PAL_FRAMERATE;
360           GST_DEBUG ("PAL data");
361           if (!gst_pad_set_explicit_caps (dv1394src->srcpad,
362                   gst_caps_new_simple ("video/x-dv",
363                       "format", G_TYPE_STRING, "PAL",
364                       "systemstream", G_TYPE_BOOLEAN, TRUE, NULL))) {
365             GST_ELEMENT_ERROR (dv1394src, CORE, NEGOTIATION, (NULL),
366                 ("Could not set source caps for PAL"));
367             return 0;
368           }
369         } else {
370           // NTSC (untested)
371           dv1394src->frame_size = NTSC_FRAMESIZE;
372           dv1394src->frame_rate = NTSC_FRAMERATE;
373           GST_DEBUG
374               ("NTSC data [untested] - please report success/failure to <dan@f3c.com>");
375           if (!gst_pad_set_explicit_caps (dv1394src->srcpad,
376                   gst_caps_new_simple ("video/x-dv", "format", G_TYPE_STRING,
377                       "NTSC", "systemstream", G_TYPE_BOOLEAN, TRUE, NULL))) {
378             GST_ELEMENT_ERROR (dv1394src, CORE, NEGOTIATION, (NULL),
379                 ("Could not set source caps for NTSC"));
380             return 0;
381           }
382         }
383         dv1394src->negotiated = TRUE;
384       }
385       // drop last frame when not complete
386       if (!dv1394src->drop_incomplete
387           || dv1394src->bytes_in_frame == dv1394src->frame_size) {
388         dv1394src->buf = dv1394src->frame;
389       } else {
390         GST_INFO_OBJECT (GST_ELEMENT (dv1394src), "incomplete frame dropped");
391         g_signal_emit (G_OBJECT (dv1394src),
392             gst_dv1394src_signals[SIGNAL_FRAME_DROPPED], 0);
393         if (dv1394src->frame) {
394           gst_buffer_unref (dv1394src->frame);
395         }
396       }
397       dv1394src->frame = NULL;
398       if ((dv1394src->frame_sequence + 1) % (dv1394src->skip +
399               dv1394src->consecutive) < dv1394src->consecutive) {
400         GstFormat format;
401         GstBuffer *buf;
402
403         buf = gst_buffer_new_and_alloc (dv1394src->frame_size);
404         /* fill in default offset */
405         format = GST_FORMAT_DEFAULT;
406         gst_dv1394src_query (dv1394src->srcpad, GST_QUERY_POSITION, &format,
407             &GST_BUFFER_OFFSET (buf));
408         /* fill in timestamp */
409         format = GST_FORMAT_TIME;
410         gst_dv1394src_query (dv1394src->srcpad, GST_QUERY_POSITION, &format,
411             &GST_BUFFER_TIMESTAMP (buf));
412         /* fill in duration by converting one frame to time */
413         gst_dv1394src_convert (dv1394src->srcpad, GST_FORMAT_DEFAULT, 1,
414             &format, &GST_BUFFER_DURATION (buf));
415
416         dv1394src->frame = buf;
417       }
418       dv1394src->frame_sequence++;
419       dv1394src->bytes_in_frame = 0;
420     }
421
422     if (dv1394src->frame != NULL) {
423       guint8 *data = GST_BUFFER_DATA (dv1394src->frame);
424
425       switch (section_type) {
426         case 0:                /* 1 Header block */
427           /* p[3] |= 0x80; // hack to force PAL data */
428           memcpy (data + dif_sequence * 150 * 80, p, 480);
429           break;
430
431         case 1:                /* 2 Subcode blocks */
432           memcpy (data + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p,
433               480);
434           break;
435
436         case 2:                /* 3 VAUX blocks */
437           memcpy (data + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p,
438               480);
439           break;
440
441         case 3:                /* 9 Audio blocks interleaved with video */
442           memcpy (data + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p,
443               480);
444           break;
445
446         case 4:                /* 135 Video blocks interleaved with audio */
447           memcpy (data + dif_sequence * 150 * 80 + (7 + (dif_block / 15) +
448                   dif_block) * 80, p, 480);
449           break;
450
451         default:               /* we can't handle any other data */
452           break;
453       }
454       dv1394src->bytes_in_frame += 480;
455     }
456   }
457
458   return 0;
459 }
460
461 static int
462 gst_dv1394src_bus_reset (raw1394handle_t handle, unsigned int generation)
463 {
464   GST_INFO_OBJECT (GST_DV1394SRC (raw1394_get_userdata (handle)),
465       "have bus reset");
466   return 0;
467 }
468
469 static GstData *
470 gst_dv1394src_get (GstPad * pad)
471 {
472   GstDV1394Src *dv1394src = GST_DV1394SRC (GST_PAD_PARENT (pad));
473
474   dv1394src->buf = NULL;
475   while (dv1394src->buf == NULL)
476     raw1394_loop_iterate (dv1394src->handle);
477
478   return GST_DATA (dv1394src->buf);
479 }
480
481 static int
482 gst_dv1394src_discover_avc_node (GstDV1394Src * src)
483 {
484   int node = -1;
485   int i, j = 0;
486   int m = src->num_ports;
487
488   if (src->port >= 0) {
489     /* search on explicit port */
490     j = src->port;
491     m = j + 1;
492   }
493
494   /* loop over all our ports */
495   for (; j < m && node == -1; j++) {
496     raw1394handle_t handle;
497     gint n_ports;
498     struct raw1394_portinfo pinf[16];
499
500     /* open the port */
501     handle = raw1394_new_handle ();
502     if (!handle) {
503       g_warning ("raw1394 - failed to get handle: %s.\n", strerror (errno));
504       continue;
505     }
506     if ((n_ports = raw1394_get_port_info (handle, pinf, 16)) < 0) {
507       g_warning ("raw1394 - failed to get port info: %s.\n", strerror (errno));
508       goto next;
509     }
510
511     /* tell raw1394 which host adapter to use */
512     if (raw1394_set_port (handle, j) < 0) {
513       g_warning ("raw1394 - failed to set set port: %s.\n", strerror (errno));
514       goto next;
515     }
516
517     /* now loop over all the nodes */
518     for (i = 0; i < raw1394_get_nodecount (handle); i++) {
519       /* are we looking for an explicit GUID */
520       if (src->guid != 0) {
521         if (src->guid == rom1394_get_guid (handle, i)) {
522           node = i;
523           src->port = j;
524           break;
525         }
526       } else {
527         rom1394_directory rom_dir;
528
529         /* select first AV/C Tape Reccorder Player node */
530         if (rom1394_get_directory (handle, i, &rom_dir) < 0) {
531           g_warning ("error reading config rom directory for node %d\n", i);
532           continue;
533         }
534         if ((rom1394_get_node_type (&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
535             avc1394_check_subunit_type (handle, i, AVC1394_SUBUNIT_TYPE_VCR)) {
536           node = i;
537           src->port = j;
538           break;
539         }
540       }
541     }
542   next:
543     raw1394_destroy_handle (handle);
544   }
545   return node;
546 }
547
548 static GstElementStateReturn
549 gst_dv1394src_change_state (GstElement * element)
550 {
551   GstDV1394Src *dv1394src;
552
553   g_return_val_if_fail (GST_IS_DV1394SRC (element), GST_STATE_FAILURE);
554   dv1394src = GST_DV1394SRC (element);
555
556   switch (GST_STATE_TRANSITION (element)) {
557     case GST_STATE_NULL_TO_READY:
558       /* create a handle */
559       if ((dv1394src->handle = raw1394_new_handle ()) == NULL) {
560         GST_ELEMENT_ERROR (dv1394src, RESOURCE, NOT_FOUND, (NULL),
561             ("can't get raw1394 handle"));
562         return GST_STATE_FAILURE;
563       }
564       /* set this plugin as the user data */
565       raw1394_set_userdata (dv1394src->handle, dv1394src);
566       /* get number of ports */
567       dv1394src->num_ports =
568           raw1394_get_port_info (dv1394src->handle, dv1394src->pinfo, 16);
569       if (dv1394src->num_ports == 0) {
570         GST_ELEMENT_ERROR (dv1394src, RESOURCE, NOT_FOUND, (NULL),
571             ("no ports available for raw1394"));
572         return GST_STATE_FAILURE;
573       }
574
575       if (dv1394src->use_avc || dv1394src->port == -1) {
576         /* discover AVC and optionally the port */
577         dv1394src->avc_node = gst_dv1394src_discover_avc_node (dv1394src);
578       }
579
580       /* configure our port now */
581       if (raw1394_set_port (dv1394src->handle, dv1394src->port) < 0) {
582         GST_ELEMENT_ERROR (dv1394src, RESOURCE, SETTINGS, (NULL),
583             ("can't set 1394 port %d", dv1394src->port));
584         return GST_STATE_FAILURE;
585       }
586       /* set the callbacks */
587       raw1394_set_iso_handler (dv1394src->handle, dv1394src->channel,
588           gst_dv1394src_iso_receive);
589       raw1394_set_bus_reset_handler (dv1394src->handle,
590           gst_dv1394src_bus_reset);
591       dv1394src->started = FALSE;
592
593       GST_DEBUG_OBJECT (dv1394src, "successfully opened up 1394 connection");
594       break;
595     case GST_STATE_PAUSED_TO_PLAYING:
596       if (raw1394_start_iso_rcv (dv1394src->handle, dv1394src->channel) < 0) {
597         GST_ELEMENT_ERROR (dv1394src, RESOURCE, READ, (NULL),
598             ("can't start 1394 iso receive"));
599         return GST_STATE_FAILURE;
600       }
601       if (dv1394src->use_avc) {
602         /* start the VCR */
603         if (!avc1394_vcr_is_recording (dv1394src->handle, dv1394src->avc_node)
604             && avc1394_vcr_is_playing (dv1394src->handle, dv1394src->avc_node)
605             != AVC1394_VCR_OPERAND_PLAY_FORWARD) {
606           avc1394_vcr_play (dv1394src->handle, dv1394src->avc_node);
607         }
608       }
609       break;
610     case GST_STATE_PLAYING_TO_PAUSED:
611       raw1394_stop_iso_rcv (dv1394src->handle, dv1394src->channel);
612       if (dv1394src->use_avc) {
613         /* pause the VCR */
614         if (!avc1394_vcr_is_recording (dv1394src->handle, dv1394src->avc_node)
615             && (avc1394_vcr_is_playing (dv1394src->handle, dv1394src->avc_node)
616                 != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE)) {
617           avc1394_vcr_pause (dv1394src->handle, dv1394src->avc_node);
618         }
619       }
620       break;
621     case GST_STATE_PAUSED_TO_READY:
622       dv1394src->negotiated = FALSE;
623       break;
624     case GST_STATE_READY_TO_NULL:
625       if (dv1394src->use_avc) {
626         /* stop the VCR */
627         avc1394_vcr_stop (dv1394src->handle, dv1394src->avc_node);
628       }
629       raw1394_destroy_handle (dv1394src->handle);
630       break;
631     default:
632       break;
633   }
634
635   /* if we haven't failed already, give the parent class a chance to ;-) */
636   if (GST_ELEMENT_CLASS (parent_class)->change_state)
637     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
638
639   return GST_STATE_SUCCESS;
640 }
641
642
643 static const GstEventMask *
644 gst_dv1394src_get_event_mask (GstPad * pad)
645 {
646   static const GstEventMask masks[] = {
647     {0,}
648   };
649
650   return masks;
651 }
652
653 static gboolean
654 gst_dv1394src_event (GstPad * pad, GstEvent * event)
655 {
656   return FALSE;
657 }
658
659 static const GstFormat *
660 gst_dv1394src_get_formats (GstPad * pad)
661 {
662   static GstFormat formats[] = {
663     GST_FORMAT_TIME,
664     GST_FORMAT_BYTES,
665     GST_FORMAT_DEFAULT,
666     0
667   };
668
669   return formats;
670 }
671
672 static gboolean
673 gst_dv1394src_convert (GstPad * pad,
674     GstFormat src_format, gint64 src_value,
675     GstFormat * dest_format, gint64 * dest_value)
676 {
677   GstDV1394Src *src;
678
679   src = GST_DV1394SRC (gst_pad_get_parent (pad));
680
681   switch (src_format) {
682     case GST_FORMAT_TIME:
683       switch (*dest_format) {
684         case GST_FORMAT_BYTES:
685           src_value *= src->frame_size;
686         case GST_FORMAT_DEFAULT:
687           *dest_value = src_value * src->frame_rate / GST_SECOND;
688           break;
689         default:
690           return FALSE;
691       }
692       break;
693     case GST_FORMAT_BYTES:
694       src_value /= src->frame_size;
695     case GST_FORMAT_DEFAULT:
696       switch (*dest_format) {
697         case GST_FORMAT_BYTES:
698           *dest_value = src_value * src->frame_size;
699           break;
700         case GST_FORMAT_TIME:
701           if (src->frame_rate != 0)
702             *dest_value = src_value * GST_SECOND / src->frame_rate;
703           else
704             return FALSE;
705           break;
706         default:
707           return FALSE;
708       }
709       break;
710     default:
711       break;
712   }
713
714   return TRUE;
715 }
716
717 static const GstQueryType *
718 gst_dv1394src_get_query_types (GstPad * pad)
719 {
720   static const GstQueryType src_query_types[] = {
721     GST_QUERY_POSITION,
722     0
723   };
724
725   return src_query_types;
726 }
727
728 static gboolean
729 gst_dv1394src_query (GstPad * pad, GstQueryType type,
730     GstFormat * format, gint64 * value)
731 {
732   gboolean res = TRUE;
733   GstDV1394Src *src;
734
735   src = GST_DV1394SRC (gst_pad_get_parent (pad));
736
737   switch (type) {
738     case GST_QUERY_POSITION:
739       /* bring our current frame to the requested format */
740       res = gst_pad_convert (src->srcpad,
741           GST_FORMAT_DEFAULT, src->frame_sequence, format, value);
742       break;
743     default:
744       res = FALSE;
745       break;
746   }
747   return res;
748 }
749
750 /*** GSTURIHANDLER INTERFACE *************************************************/
751
752 static guint
753 gst_dv1394src_uri_get_type (void)
754 {
755   return GST_URI_SRC;
756 }
757 static gchar **
758 gst_dv1394src_uri_get_protocols (void)
759 {
760   static gchar *protocols[] = { "dv", NULL };
761
762   return protocols;
763 }
764 static const gchar *
765 gst_dv1394src_uri_get_uri (GstURIHandler * handler)
766 {
767   GstDV1394Src *gst_dv1394src = GST_DV1394SRC (handler);
768
769   return gst_dv1394src->uri;
770 }
771
772 static gboolean
773 gst_dv1394src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
774 {
775   gchar *protocol, *location;
776   gboolean ret;
777
778   ret = TRUE;
779
780   GstDV1394Src *gst_dv1394src = GST_DV1394SRC (handler);
781
782   protocol = gst_uri_get_protocol (uri);
783   if (strcmp (protocol, "dv") != 0) {
784     g_free (protocol);
785     return FALSE;
786   }
787   g_free (protocol);
788
789   location = gst_uri_get_location (uri);
790   gst_dv1394src->port = strtol (location, NULL, 10);
791   g_free (location);
792
793   return ret;
794 }
795
796 static void
797 gst_dv1394src_uri_handler_init (gpointer g_iface, gpointer iface_data)
798 {
799   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
800
801   iface->get_type = gst_dv1394src_uri_get_type;
802   iface->get_protocols = gst_dv1394src_uri_get_protocols;
803   iface->get_uri = gst_dv1394src_uri_get_uri;
804   iface->set_uri = gst_dv1394src_uri_set_uri;
805 }