]> git.sesse.net Git - vlc/blob - modules/access/dc1394.c
dc1394: update to v2 API
[vlc] / modules / access / dc1394.c
1 /*****************************************************************************
2  * dc1394.c: firewire input module
3  *****************************************************************************
4  * Copyright (C) 2006-2009 VideoLAN
5  *
6  * Authors: Xant Majere <xant@xant.net>
7  *          Rob Shortt <rob@tvcentric.com> - libdc1394 V2 API updates
8  *          Frederic Benoist <fridorik@gmail.com> - updates from Rob's work
9  *
10  *****************************************************************************
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation;
14  * version 2 of the License.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  *
25  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_input.h>
38 #include <vlc_demux.h>
39 #include <vlc_charset.h>
40 #include <vlc_picture.h>
41
42 #ifdef HAVE_FCNTL_H
43 #   include <fcntl.h>
44 #endif
45 #ifdef HAVE_UNISTD_H
46 #   include <unistd.h>
47 #elif defined( WIN32 ) && !defined( UNDER_CE )
48 #   include <io.h>
49 #endif
50
51 #include <sys/ioctl.h>
52 #include <sys/soundcard.h>
53
54 #include <libraw1394/raw1394.h>
55 #include <dc1394/dc1394.h>
56
57 #define MAX_IEEE1394_HOSTS 32
58 #define MAX_CAMERA_NODES 32
59
60 /*****************************************************************************
61  * Module descriptor
62  *****************************************************************************/
63 static int  Open ( vlc_object_t * );
64 static void Close( vlc_object_t * );
65 static void OpenAudioDev( demux_t *p_demux );
66 static inline void CloseAudioDev( demux_t *p_demux );
67
68 vlc_module_begin ()
69     set_description( N_("dc1394 input") )
70     set_capability( "access_demux", 10 )
71     add_shortcut( "dc1394" )
72     set_callbacks( Open, Close )
73 vlc_module_end ()
74
75 struct demux_sys_t
76 {
77     /* camera info */
78     dc1394_t            *p_dccontext;
79     uint32_t            num_cameras;
80     dc1394camera_t      *camera;
81     int                 selected_camera;
82     uint64_t            selected_uid;
83     picture_t           pic;
84     uint32_t            dma_buffers;
85     dc1394featureset_t  features;
86     quadlet_t           supported_framerates;
87     bool                reset_bus;
88
89     /* video info */
90     char                *video_device;
91     dc1394video_mode_t  video_mode;
92     int                 width;
93     int                 height;
94     int                 frame_size;
95     int                 frame_rate;
96     unsigned int        brightness;
97     unsigned int        focus;
98     es_out_id_t         *p_es_video;
99     dc1394video_frame_t *frame;
100
101     /* audio stuff */
102     int                 i_sample_rate;
103     int                 channels;
104     int                 i_audio_max_frame_size;
105     int                 fd_audio;
106     char                *audio_device;
107 #define NO_ROTATION 0
108 #define ROTATION_LEFT 1
109 #define ROTATION_RIGHT 2
110     es_out_id_t         *p_es_audio;
111 };
112
113 /*****************************************************************************
114  * Local prototypes
115  *****************************************************************************/
116 static int Demux( demux_t *p_demux );
117 static int Control( demux_t *, int, va_list );
118 static block_t *GrabVideo( demux_t *p_demux );
119 static block_t *GrabAudio( demux_t *p_demux );
120 static int process_options( demux_t *p_demux);
121
122 /*****************************************************************************
123  * FindCameras
124  *****************************************************************************/
125 static int FindCamera( demux_sys_t *sys, demux_t *p_demux )
126 {
127     dc1394camera_list_t *list;
128
129     msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
130
131     if( dc1394_camera_enumerate (sys->p_dccontext, &list) != DC1394_SUCCESS )
132     {
133         msg_Err(p_demux, "Can not ennumerate cameras");
134         dc1394_camera_free_list (list);
135         dc1394_free( sys->p_dccontext );
136         free( sys );
137         p_demux->p_sys = NULL;
138         return VLC_EGENERIC;
139     }
140
141     if( list->num == 0 )
142     {
143         msg_Err(p_demux, "Can not find cameras");
144         dc1394_camera_free_list (list);
145         dc1394_free( sys->p_dccontext );
146         free( sys );
147         p_demux->p_sys = NULL;
148         return VLC_EGENERIC;
149     }
150
151     sys->num_cameras = list->num;
152     msg_Dbg( p_demux, "Found %d dc1394 cameras.", list->num);
153
154     if( sys->selected_uid )
155     {
156         int found = 0;
157         for( unsigned i = 0; i < sys->num_cameras; i++ )
158         {
159             if( list->ids[i].guid == sys->selected_uid )
160             {
161                 sys->camera = dc1394_camera_new(sys->p_dccontext,
162                                                 list->ids[i].guid);
163                 found++;
164                 break;
165             }
166         }
167         if( !found )
168         {
169             msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
170                      sys->selected_uid );
171             dc1394_camera_free_list (list);
172             dc1394_free( sys->p_dccontext );
173             free( sys );
174             p_demux->p_sys = NULL;
175             return VLC_EGENERIC;
176         }
177     }
178     else if( sys->selected_camera >= (int)list->num )
179     {
180         msg_Err( p_demux, "There are not this many cameras. (%d/%d)",
181                  sys->selected_camera, sys->num_cameras );
182         dc1394_camera_free_list (list);
183         dc1394_free( sys->p_dccontext );
184         free( sys );
185         p_demux->p_sys = NULL;
186         return VLC_EGENERIC;
187     }
188     else if( sys->selected_camera >= 0 )
189     {
190         sys->camera = dc1394_camera_new(sys->p_dccontext,
191                     list->ids[sys->selected_camera].guid);
192     }
193     else
194     {
195         sys->camera = dc1394_camera_new(sys->p_dccontext,
196                                           list->ids[0].guid);
197     }
198
199     dc1394_camera_free_list (list);
200     return VLC_SUCCESS;
201 }
202
203 /*****************************************************************************
204  * Open:
205  *****************************************************************************/
206 static int Open( vlc_object_t *p_this )
207 {
208     demux_t      *p_demux = (demux_t*)p_this;
209     demux_sys_t  *p_sys;
210     es_format_t   fmt;
211     dc1394error_t res;
212     int           i_width;
213     int           i_height;
214
215     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
216         return VLC_EGENERIC;
217
218     /* Set up p_demux */
219     p_demux->pf_demux = Demux;
220     p_demux->pf_control = Control;
221     p_demux->info.i_update = 0;
222     p_demux->info.i_title = 0;
223     p_demux->info.i_seekpoint = 0;
224
225     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
226     if( !p_sys )
227         return VLC_ENOMEM;
228
229     memset( &fmt, 0, sizeof( es_format_t ) );
230
231     /* DEFAULTS */
232     p_sys->video_mode      = DC1394_VIDEO_MODE_640x480_YUV422;
233     p_sys->width           = 640;
234     p_sys->height          = 480;
235     p_sys->frame_rate      = DC1394_FRAMERATE_15;
236     p_sys->brightness      = 200;
237     p_sys->focus           = 0;
238     p_sys->fd_audio        = -1;
239     p_sys->p_dccontext     = NULL;
240     p_sys->camera          = NULL;
241     p_sys->selected_camera = -1;
242     p_sys->dma_buffers     = 1;
243     p_sys->reset_bus       = 0;
244
245     /* PROCESS INPUT OPTIONS */
246     if( process_options(p_demux) != VLC_SUCCESS )
247     {
248         msg_Err( p_demux, "Bad MRL, please check the option line "
249                           "(MRL was: %s)",
250                           p_demux->psz_path );
251         free( p_sys );
252         p_demux->p_sys = NULL;
253         return VLC_EGENERIC;
254     }
255
256     p_sys->p_dccontext = dc1394_new();
257     if( !p_sys->p_dccontext )
258     {
259         msg_Err( p_demux, "Failed to initialise libdc1394");
260         free(p_demux->p_sys);
261         p_demux->p_sys = NULL;
262         return VLC_EGENERIC;
263     }
264
265     if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
266         return VLC_EGENERIC;
267
268     if( !p_sys->camera )
269     {
270         msg_Err( p_demux, "No camera found !!" );
271         dc1394_free( p_sys->p_dccontext );
272         free( p_sys );
273         p_demux->p_sys = NULL;
274         return VLC_EGENERIC;
275     }
276
277     if( p_sys->reset_bus )
278     {
279         if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
280         {
281             msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
282             Close( p_this );
283             return VLC_EGENERIC;
284         }
285         else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
286     }
287
288     if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
289     {
290         msg_Err( p_demux, "Unable to reset camera");
291         Close( p_this );
292         return VLC_EGENERIC;
293     }
294
295     if( dc1394_camera_print_info( p_sys->camera,
296                   stderr ) != DC1394_SUCCESS )
297     {
298         msg_Err( p_demux, "Unable to print camera info");
299         Close( p_this );
300         return VLC_EGENERIC;
301     }
302
303     if( dc1394_feature_get_all( p_sys->camera,
304                 &p_sys->features ) != DC1394_SUCCESS )
305     {
306         msg_Err( p_demux, "Unable to get feature set");
307         Close( p_this );
308         return VLC_EGENERIC;
309     }
310     // TODO: only print features if verbosity increased
311     dc1394_feature_print_all(&p_sys->features, stderr);
312
313 #if 0 //"Note that you need to execute this function only if you use exotic video1394 device names. /dev/video1394, /dev/video1394/* and /dev/video1394-* are automatically recognized." http://damien.douxchamps.net/ieee1394/libdc1394/v2.x/api/capture/
314     if( p_sys->video_device )
315     {
316         if( dc1394_capture_set_device_filename( p_sys->camera,
317                         p_sys->video_device ) != DC1394_SUCCESS )
318         {
319             msg_Err( p_demux, "Unable to set video device");
320             Close( p_this );
321             return VLC_EGENERIC;
322         }
323     }
324 #endif
325
326     if( p_sys->focus )
327     {
328         if( dc1394_feature_set_value( p_sys->camera,
329                       DC1394_FEATURE_FOCUS,
330                       p_sys->focus ) != DC1394_SUCCESS )
331         {
332             msg_Err( p_demux, "Unable to set initial focus to %u",
333                      p_sys->focus );
334         }
335         msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
336     }
337
338     if( dc1394_feature_set_value( p_sys->camera,
339                   DC1394_FEATURE_FOCUS,
340                   p_sys->brightness ) != DC1394_SUCCESS )
341     {
342         msg_Err( p_demux, "Unable to set initial brightness to %u",
343                  p_sys->brightness );
344     }
345     msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
346
347     if( dc1394_video_set_framerate( p_sys->camera,
348                     p_sys->frame_rate ) != DC1394_SUCCESS )
349     {
350         msg_Err( p_demux, "Unable to set framerate");
351         Close( p_this );
352         return VLC_EGENERIC;
353     }
354
355     if( dc1394_video_set_mode( p_sys->camera,
356                    p_sys->video_mode ) != DC1394_SUCCESS )
357     {
358         msg_Err( p_demux, "Unable to set video mode");
359         Close( p_this );
360         return VLC_EGENERIC;
361     }
362
363     if( dc1394_video_set_iso_speed( p_sys->camera,
364                     DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
365     {
366         msg_Err( p_demux, "Unable to set iso speed");
367         Close( p_this );
368         return VLC_EGENERIC;
369     }
370
371     /* and setup capture */
372     res = dc1394_capture_setup( p_sys->camera,
373                     p_sys->dma_buffers,
374                 DC1394_CAPTURE_FLAGS_DEFAULT);
375     if( res != DC1394_SUCCESS )
376     {
377         if( res == DC1394_NO_BANDWIDTH )
378         {
379             msg_Err( p_demux ,"No bandwidth: try adding the "
380              "\"resetbus\" option" );
381         }
382         else
383         {
384             msg_Err( p_demux ,"Unable to setup capture" );
385         }
386         Close( p_this );
387         return VLC_EGENERIC;
388     }
389
390     /* TODO - UYV444 chroma converter is missing, when it will be available
391      * fourcc will become variable (and not just a fixed value for UYVY)
392      */
393     i_width = p_sys->width;
394     i_height = p_sys->height;
395
396     if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
397                        i_width, i_height,
398                        i_width * VOUT_ASPECT_FACTOR / i_height ) )
399     {
400         msg_Err( p_demux ,"unknown chroma" );
401         Close( p_this );
402         return VLC_EGENERIC;
403     }
404
405     es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
406
407     fmt.video.i_width = i_width;
408     fmt.video.i_height = i_height;
409
410     msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
411              (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
412
413     p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
414
415     if( p_sys->audio_device )
416     {
417         OpenAudioDev( p_demux );
418         if( p_sys->fd_audio >= 0 )
419         {
420             es_format_t fmt;
421             es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L ); /* FIXME: hmm, ?? */
422
423             fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
424             fmt.audio.i_rate = p_sys->i_sample_rate;
425             fmt.audio.i_bitspersample = 16;
426             fmt.audio.i_blockalign = fmt.audio.i_channels *
427                                      fmt.audio.i_bitspersample / 8;
428             fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
429                             fmt.audio.i_bitspersample;
430
431             msg_Dbg( p_demux, "New audio es %d channels %dHz",
432             fmt.audio.i_channels, fmt.audio.i_rate );
433
434             p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
435         }
436     }
437
438     /* have the camera start sending us data */
439     if( dc1394_video_set_transmission( p_sys->camera,
440                        DC1394_ON ) != DC1394_SUCCESS )
441     {
442         msg_Err( p_demux, "Unable to start camera iso transmission" );
443         dc1394_capture_stop( p_sys->camera );
444         Close( p_this );
445         return VLC_EGENERIC;
446     }
447     msg_Dbg( p_demux, "Set iso transmission" );
448     // TODO: reread camera
449     return VLC_SUCCESS;
450 }
451
452 static void OpenAudioDev( demux_t *p_demux )
453 {
454     demux_sys_t *p_sys = p_demux->p_sys;
455     char *psz_device = p_sys->audio_device;
456     int i_format = AFMT_S16_LE;
457     int result;
458
459     p_sys->fd_audio = utf8_open( psz_device, O_RDONLY | O_NONBLOCK );
460     if( p_sys->fd_audio  < 0 )
461     {
462         msg_Err( p_demux, "Cannot open audio device (%s)", psz_device );
463         CloseAudioDev( p_demux );
464     }
465
466     if( !p_sys->i_sample_rate )
467         p_sys->i_sample_rate = 44100;
468
469     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format );
470     if( (result  < 0) || (i_format != AFMT_S16_LE) )
471     {
472         msg_Err( p_demux, "Cannot set audio format (16b little endian) "
473                           "(%d)", i_format );
474         CloseAudioDev( p_demux );
475     }
476
477     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
478     if( result < 0 )
479     {
480         msg_Err( p_demux, "Cannot set audio channels count (%d)",
481                  p_sys->channels );
482         CloseAudioDev( p_demux );
483     }
484
485     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
486     if( result < 0 )
487     {
488         msg_Err( p_demux, "Cannot set audio sample rate (%d)",
489          p_sys->i_sample_rate );
490         CloseAudioDev( p_demux );
491     }
492
493     msg_Dbg( p_demux, "Opened adev=`%s' %s %dHz",
494              psz_device,
495              (p_sys->channels > 1) ? "stereo" : "mono",
496              p_sys->i_sample_rate );
497
498     p_sys->i_audio_max_frame_size = 32 * 1024;
499 }
500
501 static inline void CloseAudioDev( demux_t *p_demux )
502 {
503     demux_sys_t *p_sys = NULL;
504
505     if( p_demux )
506     {
507         p_sys = p_demux->p_sys;
508         if( p_sys->fd_audio >= 0 )
509             close( p_sys->fd_audio );
510     }
511 }
512
513 /*****************************************************************************
514  * Close:
515  *****************************************************************************/
516 static void Close( vlc_object_t *p_this )
517 {
518     demux_t     *p_demux = (demux_t*)p_this;
519     demux_sys_t *p_sys = p_demux->p_sys;
520
521     /* Stop data transmission */
522     if( dc1394_video_set_transmission( p_sys->camera,
523                        DC1394_OFF ) != DC1394_SUCCESS )
524         msg_Err( p_demux, "Unable to stop camera iso transmission" );
525
526     /* Close camera */
527     dc1394_capture_stop( p_sys->camera );
528
529     CloseAudioDev( p_demux );
530
531     dc1394_camera_free(p_sys->camera);
532     dc1394_free(p_sys->p_dccontext);
533
534     if( p_sys->audio_device )
535         free( p_sys->audio_device );
536
537     free( p_sys );
538 }
539
540 #if 0
541 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
542 {
543     char u,v,y;
544     u_char  *sc;
545     u_char  *dc;
546
547     sc = (u_char *)src + (spos*2);
548     if( spos % 2 )
549     {
550         v = sc[0];
551         y = sc[1];
552         u = *(sc -2);
553     }
554     else
555     {
556         u = sc[0];
557         y = sc[1];
558         v = sc[2];
559     }
560     dc = (u_char *)dst+(dpos*2);
561     if( dpos % 2 )
562     {
563         dc[0] = v;
564         dc[1] = y;
565     }
566     else
567     {
568         dc[0] = u;
569         dc[1] = y;
570     }
571 }
572 #endif
573
574 /*****************************************************************************
575  * Demux:
576  *****************************************************************************/
577 static block_t *GrabVideo( demux_t *p_demux )
578 {
579     demux_sys_t *p_sys = p_demux->p_sys;
580     block_t     *p_block = NULL;
581
582     if( dc1394_capture_dequeue( p_sys->camera,
583                 DC1394_CAPTURE_POLICY_WAIT,
584                 &p_sys->frame ) != DC1394_SUCCESS )
585     {
586         msg_Err( p_demux, "Unable to capture a frame" );
587         return NULL;
588     }
589
590     p_block = block_New( p_demux, p_sys->frame->size[0] *
591                                   p_sys->frame->size[1] * 2 );
592     if( !p_block )
593     {
594         msg_Err( p_demux, "Can not get block" );
595         return NULL;
596     }
597
598     if( !p_sys->frame->image )
599     {
600         msg_Err (p_demux, "Capture buffer empty");
601         block_Release( p_block );
602         return NULL;
603     }
604
605     memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
606             p_sys->width * p_sys->height * 2 );
607
608     p_block->i_pts = p_block->i_dts = mdate();
609     dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
610     return p_block;
611 }
612
613 static block_t *GrabAudio( demux_t *p_demux )
614 {
615     demux_sys_t *p_sys = p_demux->p_sys;
616     struct audio_buf_info buf_info;
617     block_t *p_block = NULL;
618     int i_read = 0;
619     int i_correct = 0;
620     int result = 0;
621
622     p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
623     if( !p_block )
624     {
625         msg_Warn( p_demux, "Cannot get buffer" );
626         return NULL;
627     }
628
629     i_read = read( p_sys->fd_audio, p_block->p_buffer,
630                    p_sys->i_audio_max_frame_size );
631
632     if( i_read <= 0 )
633         return NULL;
634
635     p_block->i_buffer = i_read;
636
637     /* Correct the date because of kernel buffering */
638     i_correct = i_read;
639     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info );
640     if( result == 0 )
641         i_correct += buf_info.bytes;
642
643     p_block->i_pts = p_block->i_dts =
644                         mdate() - INT64_C(1000000) * (mtime_t)i_correct /
645                         2 / p_sys->channels / p_sys->i_sample_rate;
646     return p_block;
647 }
648
649 static int Demux( demux_t *p_demux )
650 {
651     demux_sys_t *p_sys = p_demux->p_sys;
652     block_t *p_blocka = NULL;
653     block_t *p_blockv = NULL;
654
655     /* Try grabbing audio frames first */
656     if( p_sys->fd_audio > 0 )
657         p_blocka = GrabAudio( p_demux );
658
659     /* Try grabbing video frame */
660     p_blockv = GrabVideo( p_demux );
661
662     if( !p_blocka && !p_blockv )
663     {
664         /* Sleep so we do not consume all the cpu, 10ms seems
665          * like a good value (100fps)
666          */
667         msleep( 10000 );
668         return 1;
669     }
670
671     if( p_blocka )
672     {
673         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blocka->i_pts );
674         es_out_Send( p_demux->out, p_sys->p_es_audio, p_blocka );
675     }
676
677     if( p_blockv )
678     {
679         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
680         es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
681     }
682     return 1;
683 }
684
685 /*****************************************************************************
686  * Control:
687  *****************************************************************************/
688 static int Control( demux_t *p_demux, int i_query, va_list args )
689 {
690     VLC_UNUSED( p_demux );
691     switch( i_query )
692     {
693         /* Special for access_demux */
694         case DEMUX_CAN_PAUSE:
695         case DEMUX_CAN_SEEK:
696         case DEMUX_SET_PAUSE_STATE:
697         case DEMUX_CAN_CONTROL_PACE:
698             *va_arg( args, bool * ) = false;
699             return VLC_SUCCESS;
700
701         case DEMUX_GET_PTS_DELAY:
702             *va_arg( args, int64_t * ) = (int64_t)DEFAULT_PTS_DELAY;
703             return VLC_SUCCESS;
704
705         case DEMUX_GET_TIME:
706             *va_arg( args, int64_t * ) = mdate();
707             return VLC_SUCCESS;
708
709         /* TODO implement others */
710         default:
711             return VLC_EGENERIC;
712     }
713     return VLC_EGENERIC;
714 }
715
716 static int process_options( demux_t *p_demux )
717 {
718     demux_sys_t *p_sys = p_demux->p_sys;
719     char *psz_dup;
720     char *psz_parser;
721     char *token = NULL;
722     char *state = NULL;
723     const char *in_size = NULL;
724     const char *in_fmt = NULL;
725     float rate_f;
726
727     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
728         return VLC_EGENERIC;
729
730     psz_dup = strdup( p_demux->psz_path );
731     psz_parser = psz_dup;
732     for( token = strtok_r( psz_parser,":",&state); token;
733          token = strtok_r( NULL, ":", &state ) )
734     {
735         if( strncmp( token, "size=", strlen("size=") ) == 0 )
736         {
737             token += strlen("size=");
738             if( strncmp( token, "160x120", 7 ) == 0 )
739             {
740                 /* TODO - UYV444 chroma converter is needed ...
741                     * video size of 160x120 is temporarily disabled
742                     */
743                 msg_Err( p_demux,
744                     "video size of 160x120 is actually disabled for lack of"
745                     "chroma support. It will relased ASAP, until then try "
746                     "an higher size (320x240 and 640x480 are fully supported)" );
747                 free(psz_dup);
748                 return VLC_EGENERIC;
749 #if 0
750                 in_size = "160x120";
751                 p_sys->width = 160;
752                 p_sys->height = 120;
753 #endif
754             }
755             else if( strncmp( token, "320x240", 7 ) == 0 )
756             {
757                 in_size = "320x240";
758                 p_sys->width = 320;
759                 p_sys->height = 240;
760             }
761             else if( strncmp( token, "640x480", 7 ) == 0 )
762             {
763                 in_size = "640x480";
764                 p_sys->width = 640;
765                 p_sys->height = 480;
766             }
767             else
768             {
769                 msg_Err( p_demux,
770                     "This program currently suppots frame sizes of"
771                     " 160x120, 320x240, and 640x480. "
772                     "Please specify one of them. You have specified %s.",
773                     token );
774                 free(psz_dup);
775                 return VLC_EGENERIC;
776             }
777             msg_Dbg( p_demux, "Requested video size : %s",token );
778         }
779         if( strncmp( token, "format=", strlen("format=") ) == 0 )
780         {
781             token += strlen("format=");
782             if( strncmp( token, "YUV411", 6 ) == 0 )
783             {
784                 in_fmt = "YUV411";
785             }
786             else if( strncmp( token, "YUV422", 6 ) == 0 )
787             {
788                 in_fmt = "YUV422";
789             }
790             else if( strncmp( token, "YUV444", 6 ) == 0 )
791             {
792                 in_fmt = "YUV444";
793             }
794             else if( strncmp( token, "RGB8", 4 ) == 0 )
795             {
796                 in_fmt = "RGB8";
797             }
798             else if( strncmp( token, "MONO8", 5 ) == 0 )
799             {
800                 in_fmt = "MONO8";
801             }
802             else if( strncmp( token, "MONO16", 6 ) == 0 )
803             {
804                 in_fmt = "MONO16";
805             }
806             else
807             {
808                 msg_Err( p_demux, "Invalid format %s.", token );
809                 free(psz_dup);
810                 return VLC_EGENERIC;
811             }
812             msg_Dbg( p_demux, "Requested video format : %s", token );
813         }
814         else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
815         {
816             token += strlen("fps=");
817             sscanf( token, "%g", &rate_f );
818             if( rate_f == 1.875 )
819                 p_sys->frame_rate = DC1394_FRAMERATE_1_875;
820             else if( rate_f == 3.75 )
821                 p_sys->frame_rate = DC1394_FRAMERATE_3_75;
822             else if( rate_f == 7.5 )
823                 p_sys->frame_rate = DC1394_FRAMERATE_7_5;
824             else if( rate_f == 15 )
825                 p_sys->frame_rate = DC1394_FRAMERATE_15;
826             else if( rate_f == 30 )
827                 p_sys->frame_rate = DC1394_FRAMERATE_30;
828             else if( rate_f == 60 )
829                 p_sys->frame_rate = DC1394_FRAMERATE_60;
830             else
831             {
832                 msg_Err( p_demux ,
833                     "This program supports framerates of"
834                     " 1.875, 3.75, 7.5, 15, 30, 60. "
835                     "Please specify one of them. You have specified %s.",
836                     token);
837                 free(psz_dup);
838                 return VLC_EGENERIC;
839             }
840             msg_Dbg( p_demux, "Requested frame rate : %s",token );
841         }
842         else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
843         {
844             token += strlen("resetbus");
845             p_sys->reset_bus = 1;
846         }
847         else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
848         {
849             int nr = 0;
850             token += strlen("brightness=");
851             nr = sscanf( token, "%u", &p_sys->brightness);
852             if( nr != 1 )
853             {
854                 msg_Err( p_demux, "Bad brightness value '%s', "
855                                   "must be an unsigned integer.",
856                                   token );
857                 free(psz_dup);
858                 return VLC_EGENERIC;
859             }
860         }
861         else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
862         {
863             int nr = 0;
864             int in_buf = 0;
865             token += strlen("buffers=");
866             nr = sscanf( token, "%d", &in_buf);
867             if( nr != 1 || in_buf < 1 )
868             {
869                 msg_Err( p_demux, "DMA buffers must be 1 or greater." );
870                 free(psz_dup);
871                 return VLC_EGENERIC;
872             }
873             else p_sys->dma_buffers = in_buf;
874         }
875 #if 0
876         // NOTE: If controller support is added back, more logic will needed to be added
877         //       after the cameras are scanned.
878         else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
879         {
880             int nr = 0;
881             token += strlen("controller=");
882             nr = sscanf( token, "%u", &p_sys->controller );
883             if( nr != 1)
884             {
885                 msg_Err(p_demux, "Bad controller value '%s', "
886                                  "must be an unsigned integer.",
887                                  token );
888                 return VLC_EGENERIC;
889             }
890         }
891 #endif
892         else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
893         {
894             int nr = 0;
895             token += strlen("camera=");
896             nr = sscanf(token,"%u",&p_sys->selected_camera);
897             if( nr != 1)
898             {
899                 msg_Err( p_demux, "Bad camera number '%s', "
900                                   "must be an unsigned integer.",
901                                   token );
902                 free(psz_dup);
903                 return VLC_EGENERIC;
904             }
905         }
906         else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
907         {
908             token += strlen("vdev=");
909             p_sys->video_device = strdup(token);
910             msg_Dbg( p_demux, "Using video device '%s'.", token );
911         }
912         else if( strncmp( token, "adev=", strlen( "adev=" ) ) == 0 )
913         {
914             token += strlen("adev=");
915             p_sys->audio_device = strdup(token);
916             msg_Dbg( p_demux, "Using audio device '%s'.", token );
917         }
918         else if( strncmp( token, "samplerate=", strlen( "samplerate=" ) ) == 0 )
919         {
920             token += strlen("samplerate=");
921             sscanf( token, "%d", &p_sys->i_sample_rate );
922         }
923         else if( strncmp( token, "channels=", strlen("channels=" ) ) == 0 )
924         {
925             token += strlen("channels=");
926             sscanf( token, "%d", &p_sys->channels );
927         }
928         else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
929         {
930             int nr = 0;
931             token += strlen("focus=");
932             nr = sscanf( token, "%u", &p_sys->focus );
933             if( nr != 1 )
934             {
935                 msg_Err( p_demux, "Bad focus value '%s', "
936                                   "must be an unsigned integer.",
937                                   token );
938                 free(psz_dup);
939                 return VLC_EGENERIC;
940             }
941         }
942         else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
943         {
944             token += strlen("uid=");
945             sscanf( token, "0x%llx", &p_sys->selected_uid );
946         }
947     }
948
949     // The mode is a combination of size and format and not every format
950     // is supported by every size.
951     if( in_size)
952     {
953         if( strcmp( in_size, "160x120") == 0)
954         {
955             if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
956                 msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
957             p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
958         }
959         else if( strcmp( in_size, "320x240") == 0)
960         {
961             if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
962                 msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
963             p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
964         }
965     }
966     else
967     { // 640x480 default
968         if( in_fmt )
969         {
970             if( strcmp( in_fmt, "RGB8") == 0)
971                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
972             else if( strcmp( in_fmt, "MONO8") == 0)
973                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
974             else if( strcmp( in_fmt, "MONO16") == 0)
975                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
976             else if( strcmp( in_fmt, "YUV411") == 0)
977                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
978             else // YUV422 default
979                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
980         }
981         else // YUV422 default
982             p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
983     }
984     return VLC_SUCCESS;
985 }