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