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