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