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