]> git.sesse.net Git - vlc/blob - modules/access/dc1394.c
LGPL
[vlc] / modules / access / dc1394.c
1 /*****************************************************************************
2  * dc1394.c: IIDC (DCAM) 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_demux.h>
38
39 #include <dc1394/dc1394.h>
40
41 #define MAX_IEEE1394_HOSTS 32
42 #define MAX_CAMERA_NODES 32
43
44 /*****************************************************************************
45  * Module descriptor
46  *****************************************************************************/
47 static int  Open ( vlc_object_t * );
48 static void Close( vlc_object_t * );
49
50 vlc_module_begin()
51     set_shortname( N_("DC1394") )
52     set_description( N_("IIDC Digital Camera (FireWire) input") )
53     set_capability( "access_demux", 10 )
54     set_callbacks( Open, Close )
55 vlc_module_end()
56
57 struct demux_sys_t
58 {
59     /* camera info */
60     dc1394_t            *p_dccontext;
61     uint32_t            num_cameras;
62     dc1394camera_t      *camera;
63     int                 selected_camera;
64     uint64_t            selected_uid;
65     uint32_t            dma_buffers;
66     dc1394featureset_t  features;
67     bool                reset_bus;
68
69     /* video info */
70     char                *video_device;
71     dc1394video_mode_t  video_mode;
72     int                 width;
73     int                 height;
74     int                 frame_size;
75     int                 frame_rate;
76     unsigned int        brightness;
77     unsigned int        focus;
78     es_out_id_t         *p_es_video;
79     dc1394video_frame_t *frame;
80 };
81
82 /*****************************************************************************
83  * Local prototypes
84  *****************************************************************************/
85 static int Demux( demux_t *p_demux );
86 static int Control( demux_t *, int, va_list );
87 static block_t *GrabVideo( demux_t *p_demux );
88 static int process_options( demux_t *p_demux);
89
90 /*****************************************************************************
91  * FindCameras
92  *****************************************************************************/
93 static int FindCamera( demux_sys_t *sys, demux_t *p_demux )
94 {
95     dc1394camera_list_t *list;
96     int i_ret = VLC_EGENERIC;
97
98     msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
99
100     if( dc1394_camera_enumerate (sys->p_dccontext, &list) != DC1394_SUCCESS )
101     {
102         msg_Err(p_demux, "Can not ennumerate cameras");
103         goto end;
104     }
105
106     if( list->num == 0 )
107     {
108         msg_Err(p_demux, "Can not find cameras");
109         goto end;
110     }
111
112     sys->num_cameras = list->num;
113     msg_Dbg( p_demux, "Found %d dc1394 cameras.", list->num);
114
115     if( sys->selected_uid )
116     {
117         int found = 0;
118         for( unsigned i = 0; i < sys->num_cameras; i++ )
119         {
120             if( list->ids[i].guid == sys->selected_uid )
121             {
122                 sys->camera = dc1394_camera_new(sys->p_dccontext,
123                                                 list->ids[i].guid);
124                 found++;
125                 break;
126             }
127         }
128         if( !found )
129         {
130             msg_Err( p_demux, "Can't find camera with uid : 0x%"PRIx64".",
131                      sys->selected_uid );
132             goto end;
133         }
134     }
135     else if( sys->selected_camera >= (int)list->num )
136     {
137         msg_Err( p_demux, "There are not this many cameras. (%d/%d)",
138                  sys->selected_camera, sys->num_cameras );
139         goto end;
140     }
141     else if( sys->selected_camera >= 0 )
142     {
143         sys->camera = dc1394_camera_new(sys->p_dccontext,
144                     list->ids[sys->selected_camera].guid);
145     }
146     else
147     {
148         sys->camera = dc1394_camera_new(sys->p_dccontext,
149                                           list->ids[0].guid);
150     }
151
152     i_ret = VLC_SUCCESS;
153
154 end:
155     dc1394_camera_free_list (list);
156     return i_ret;
157 }
158
159 /*****************************************************************************
160  * Open:
161  *****************************************************************************/
162 static int Open( vlc_object_t *p_this )
163 {
164     demux_t      *p_demux = (demux_t*)p_this;
165     demux_sys_t  *p_sys;
166     es_format_t   fmt;
167     dc1394error_t res;
168
169     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
170         return VLC_EGENERIC;
171
172     /* Set up p_demux */
173     p_demux->pf_demux = Demux;
174     p_demux->pf_control = Control;
175     p_demux->info.i_update = 0;
176     p_demux->info.i_title = 0;
177     p_demux->info.i_seekpoint = 0;
178
179     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
180     if( !p_sys )
181         return VLC_ENOMEM;
182
183     memset( &fmt, 0, sizeof( es_format_t ) );
184
185     /* DEFAULTS */
186     p_sys->video_mode      = DC1394_VIDEO_MODE_640x480_YUV422;
187     p_sys->width           = 640;
188     p_sys->height          = 480;
189     p_sys->frame_rate      = DC1394_FRAMERATE_15;
190     p_sys->brightness      = 200;
191     p_sys->focus           = 0;
192     p_sys->p_dccontext     = NULL;
193     p_sys->camera          = NULL;
194     p_sys->selected_camera = -1;
195     p_sys->dma_buffers     = 1;
196     p_sys->reset_bus       = 0;
197
198     /* PROCESS INPUT OPTIONS */
199     if( process_options(p_demux) != VLC_SUCCESS )
200     {
201         msg_Err( p_demux, "Bad MRL, please check the option line "
202                           "(MRL was: %s)",
203                           p_demux->psz_location );
204         free( p_sys );
205         return VLC_EGENERIC;
206     }
207
208     p_sys->p_dccontext = dc1394_new();
209     if( !p_sys->p_dccontext )
210     {
211         msg_Err( p_demux, "Failed to initialise libdc1394");
212         free( p_sys );
213         return VLC_EGENERIC;
214     }
215
216     if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
217     {
218         dc1394_free( p_sys->p_dccontext );
219         free( p_sys );
220         return VLC_EGENERIC;
221     }
222
223     if( !p_sys->camera )
224     {
225         msg_Err( p_demux, "No camera found !!" );
226         dc1394_free( p_sys->p_dccontext );
227         free( p_sys );
228         return VLC_EGENERIC;
229     }
230
231     if( p_sys->reset_bus )
232     {
233         if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
234         {
235             msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
236             Close( p_this );
237             return VLC_EGENERIC;
238         }
239         else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
240     }
241
242     if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
243     {
244         msg_Err( p_demux, "Unable to reset camera");
245         Close( p_this );
246         return VLC_EGENERIC;
247     }
248
249     if( dc1394_camera_print_info( p_sys->camera,
250                   stderr ) != DC1394_SUCCESS )
251     {
252         msg_Err( p_demux, "Unable to print camera info");
253         Close( p_this );
254         return VLC_EGENERIC;
255     }
256
257     if( dc1394_feature_get_all( p_sys->camera,
258                 &p_sys->features ) != DC1394_SUCCESS )
259     {
260         msg_Err( p_demux, "Unable to get feature set");
261         Close( p_this );
262         return VLC_EGENERIC;
263     }
264     // TODO: only print features if verbosity increased
265     dc1394_feature_print_all(&p_sys->features, stderr);
266
267 #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/
268     if( p_sys->video_device )
269     {
270         if( dc1394_capture_set_device_filename( p_sys->camera,
271                         p_sys->video_device ) != DC1394_SUCCESS )
272         {
273             msg_Err( p_demux, "Unable to set video device");
274             Close( p_this );
275             return VLC_EGENERIC;
276         }
277     }
278 #endif
279
280     if( p_sys->focus )
281     {
282         if( dc1394_feature_set_value( p_sys->camera,
283                       DC1394_FEATURE_FOCUS,
284                       p_sys->focus ) != DC1394_SUCCESS )
285         {
286             msg_Err( p_demux, "Unable to set initial focus to %u",
287                      p_sys->focus );
288         }
289         else
290             msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
291     }
292
293     if( dc1394_feature_set_value( p_sys->camera,
294                   DC1394_FEATURE_FOCUS,
295                   p_sys->brightness ) != DC1394_SUCCESS )
296     {
297         msg_Err( p_demux, "Unable to set initial brightness to %u",
298                  p_sys->brightness );
299     }
300     else
301         msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
302
303     if( dc1394_video_set_framerate( p_sys->camera,
304                     p_sys->frame_rate ) != DC1394_SUCCESS )
305     {
306         msg_Err( p_demux, "Unable to set framerate");
307         Close( p_this );
308         return VLC_EGENERIC;
309     }
310
311     if( dc1394_video_set_mode( p_sys->camera,
312                    p_sys->video_mode ) != DC1394_SUCCESS )
313     {
314         msg_Err( p_demux, "Unable to set video mode");
315         Close( p_this );
316         return VLC_EGENERIC;
317     }
318
319     if( dc1394_video_set_iso_speed( p_sys->camera,
320                     DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
321     {
322         msg_Err( p_demux, "Unable to set iso speed");
323         Close( p_this );
324         return VLC_EGENERIC;
325     }
326
327     /* and setup capture */
328     res = dc1394_capture_setup( p_sys->camera,
329                     p_sys->dma_buffers,
330                 DC1394_CAPTURE_FLAGS_DEFAULT);
331     if( res != DC1394_SUCCESS )
332     {
333         if( res == DC1394_NO_BANDWIDTH )
334         {
335             msg_Err( p_demux ,"No bandwidth: try adding the "
336              "\"resetbus\" option" );
337         }
338         else
339         {
340             msg_Err( p_demux ,"Unable to setup capture" );
341         }
342         Close( p_this );
343         return VLC_EGENERIC;
344     }
345
346     /* TODO - UYV444 chroma converter is missing, when it will be available
347      * fourcc will become variable (and not just a fixed value for UYVY)
348      */
349     es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
350
351     fmt.video.i_width = p_sys->width;
352     fmt.video.i_height = p_sys->height;
353
354     msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
355              (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
356
357     p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
358
359     /* have the camera start sending us data */
360     if( dc1394_video_set_transmission( p_sys->camera,
361                        DC1394_ON ) != DC1394_SUCCESS )
362     {
363         msg_Err( p_demux, "Unable to start camera iso transmission" );
364         dc1394_capture_stop( p_sys->camera );
365         Close( p_this );
366         return VLC_EGENERIC;
367     }
368     msg_Dbg( p_demux, "Set iso transmission" );
369     // TODO: reread camera
370     return VLC_SUCCESS;
371 }
372
373 /*****************************************************************************
374  * Close:
375  *****************************************************************************/
376 static void Close( vlc_object_t *p_this )
377 {
378     demux_t     *p_demux = (demux_t*)p_this;
379     demux_sys_t *p_sys = p_demux->p_sys;
380
381     /* Stop data transmission */
382     if( dc1394_video_set_transmission( p_sys->camera,
383                        DC1394_OFF ) != DC1394_SUCCESS )
384         msg_Err( p_demux, "Unable to stop camera iso transmission" );
385
386     /* Close camera */
387     dc1394_capture_stop( p_sys->camera );
388
389     dc1394_camera_free(p_sys->camera);
390     dc1394_free(p_sys->p_dccontext);
391
392     free( p_sys->video_device );
393     free( p_sys );
394 }
395
396 #if 0
397 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
398 {
399     char u,v,y;
400     u_char  *sc;
401     u_char  *dc;
402
403     sc = (u_char *)src + (spos*2);
404     if( spos % 2 )
405     {
406         v = sc[0];
407         y = sc[1];
408         u = *(sc -2);
409     }
410     else
411     {
412         u = sc[0];
413         y = sc[1];
414         v = sc[2];
415     }
416     dc = (u_char *)dst+(dpos*2);
417     if( dpos % 2 )
418     {
419         dc[0] = v;
420         dc[1] = y;
421     }
422     else
423     {
424         dc[0] = u;
425         dc[1] = y;
426     }
427 }
428 #endif
429
430 /*****************************************************************************
431  * Demux:
432  *****************************************************************************/
433 static block_t *GrabVideo( demux_t *p_demux )
434 {
435     demux_sys_t *p_sys = p_demux->p_sys;
436     block_t     *p_block = NULL;
437
438     if( dc1394_capture_dequeue( p_sys->camera,
439                 DC1394_CAPTURE_POLICY_WAIT,
440                 &p_sys->frame ) != DC1394_SUCCESS )
441     {
442         msg_Err( p_demux, "Unable to capture a frame" );
443         return NULL;
444     }
445
446     p_block = block_New( p_demux, p_sys->frame->size[0] *
447                                   p_sys->frame->size[1] * 2 );
448     if( !p_block )
449     {
450         msg_Err( p_demux, "Can not get block" );
451         return NULL;
452     }
453
454     if( !p_sys->frame->image )
455     {
456         msg_Err (p_demux, "Capture buffer empty");
457         block_Release( p_block );
458         return NULL;
459     }
460
461     memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
462             p_sys->width * p_sys->height * 2 );
463
464     p_block->i_pts = p_block->i_dts = mdate();
465     dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
466     return p_block;
467 }
468
469 static int Demux( demux_t *p_demux )
470 {
471     demux_sys_t *p_sys = p_demux->p_sys;
472     block_t *p_blockv = NULL;
473
474     /* Try grabbing video frame */
475     p_blockv = GrabVideo( p_demux );
476
477     if( !p_blockv )
478     {
479         /* Sleep so we do not consume all the cpu, 10ms seems
480          * like a good value (100fps)
481          */
482         msleep( 10000 );
483         return 1;
484     }
485
486     if( p_blockv )
487     {
488         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
489         es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
490     }
491     return 1;
492 }
493
494 /*****************************************************************************
495  * Control:
496  *****************************************************************************/
497 static int Control( demux_t *p_demux, int i_query, va_list args )
498 {
499     VLC_UNUSED( p_demux );
500     switch( i_query )
501     {
502         /* Special for access_demux */
503         case DEMUX_CAN_PAUSE:
504         case DEMUX_CAN_SEEK:
505         case DEMUX_SET_PAUSE_STATE:
506         case DEMUX_CAN_CONTROL_PACE:
507             *va_arg( args, bool * ) = false;
508             return VLC_SUCCESS;
509
510         case DEMUX_GET_PTS_DELAY:
511             *va_arg( args, int64_t * ) = (int64_t)DEFAULT_PTS_DELAY;
512             return VLC_SUCCESS;
513
514         case DEMUX_GET_TIME:
515             *va_arg( args, int64_t * ) = mdate();
516             return VLC_SUCCESS;
517
518         /* TODO implement others */
519         default:
520             return VLC_EGENERIC;
521     }
522     return VLC_EGENERIC;
523 }
524
525 static int process_options( demux_t *p_demux )
526 {
527     demux_sys_t *p_sys = p_demux->p_sys;
528     char *psz_dup;
529     char *psz_parser;
530     char *token = NULL;
531     char *state = NULL;
532     const char *in_size = NULL;
533     const char *in_fmt = NULL;
534     float rate_f;
535
536     psz_dup = strdup( p_demux->psz_location );
537     psz_parser = psz_dup;
538     for( token = strtok_r( psz_parser,":",&state); token;
539          token = strtok_r( NULL, ":", &state ) )
540     {
541         if( strncmp( token, "size=", strlen("size=") ) == 0 )
542         {
543             token += strlen("size=");
544             if( strncmp( token, "160x120", 7 ) == 0 )
545             {
546                 /* TODO - UYV444 chroma converter is needed ...
547                     * video size of 160x120 is temporarily disabled
548                     */
549                 msg_Err( p_demux,
550                     "video size of 160x120 is actually disabled for lack of"
551                     "chroma support. It will relased ASAP, until then try "
552                     "an higher size (320x240 and 640x480 are fully supported)" );
553                 free(psz_dup);
554                 return VLC_EGENERIC;
555 #if 0
556                 in_size = "160x120";
557                 p_sys->width = 160;
558                 p_sys->height = 120;
559 #endif
560             }
561             else if( strncmp( token, "320x240", 7 ) == 0 )
562             {
563                 in_size = "320x240";
564                 p_sys->width = 320;
565                 p_sys->height = 240;
566             }
567             else if( strncmp( token, "640x480", 7 ) == 0 )
568             {
569                 in_size = "640x480";
570                 p_sys->width = 640;
571                 p_sys->height = 480;
572             }
573             else
574             {
575                 msg_Err( p_demux,
576                     "This program currently suppots frame sizes of"
577                     " 160x120, 320x240, and 640x480. "
578                     "Please specify one of them. You have specified %s.",
579                     token );
580                 free(psz_dup);
581                 return VLC_EGENERIC;
582             }
583             msg_Dbg( p_demux, "Requested video size : %s",token );
584         }
585         if( strncmp( token, "format=", strlen("format=") ) == 0 )
586         {
587             token += strlen("format=");
588             if( strncmp( token, "YUV411", 6 ) == 0 )
589             {
590                 in_fmt = "YUV411";
591             }
592             else if( strncmp( token, "YUV422", 6 ) == 0 )
593             {
594                 in_fmt = "YUV422";
595             }
596             else if( strncmp( token, "YUV444", 6 ) == 0 )
597             {
598                 in_fmt = "YUV444";
599             }
600             else if( strncmp( token, "RGB8", 4 ) == 0 )
601             {
602                 in_fmt = "RGB8";
603             }
604             else if( strncmp( token, "MONO8", 5 ) == 0 )
605             {
606                 in_fmt = "MONO8";
607             }
608             else if( strncmp( token, "MONO16", 6 ) == 0 )
609             {
610                 in_fmt = "MONO16";
611             }
612             else
613             {
614                 msg_Err( p_demux, "Invalid format %s.", token );
615                 free(psz_dup);
616                 return VLC_EGENERIC;
617             }
618             msg_Dbg( p_demux, "Requested video format : %s", token );
619         }
620         else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
621         {
622             token += strlen("fps=");
623             sscanf( token, "%g", &rate_f );
624             if( rate_f == 1.875 )
625                 p_sys->frame_rate = DC1394_FRAMERATE_1_875;
626             else if( rate_f == 3.75 )
627                 p_sys->frame_rate = DC1394_FRAMERATE_3_75;
628             else if( rate_f == 7.5 )
629                 p_sys->frame_rate = DC1394_FRAMERATE_7_5;
630             else if( rate_f == 15 )
631                 p_sys->frame_rate = DC1394_FRAMERATE_15;
632             else if( rate_f == 30 )
633                 p_sys->frame_rate = DC1394_FRAMERATE_30;
634             else if( rate_f == 60 )
635                 p_sys->frame_rate = DC1394_FRAMERATE_60;
636             else
637             {
638                 msg_Err( p_demux ,
639                     "This program supports framerates of"
640                     " 1.875, 3.75, 7.5, 15, 30, 60. "
641                     "Please specify one of them. You have specified %s.",
642                     token);
643                 free(psz_dup);
644                 return VLC_EGENERIC;
645             }
646             msg_Dbg( p_demux, "Requested frame rate : %s",token );
647         }
648         else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
649         {
650             token += strlen("resetbus");
651             p_sys->reset_bus = 1;
652         }
653         else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
654         {
655             int nr = 0;
656             token += strlen("brightness=");
657             nr = sscanf( token, "%u", &p_sys->brightness);
658             if( nr != 1 )
659             {
660                 msg_Err( p_demux, "Bad brightness value '%s', "
661                                   "must be an unsigned integer.",
662                                   token );
663                 free(psz_dup);
664                 return VLC_EGENERIC;
665             }
666         }
667         else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
668         {
669             int nr = 0;
670             int in_buf = 0;
671             token += strlen("buffers=");
672             nr = sscanf( token, "%d", &in_buf);
673             if( nr != 1 || in_buf < 1 )
674             {
675                 msg_Err( p_demux, "DMA buffers must be 1 or greater." );
676                 free(psz_dup);
677                 return VLC_EGENERIC;
678             }
679             else p_sys->dma_buffers = in_buf;
680         }
681 #if 0
682         // NOTE: If controller support is added back, more logic will needed to be added
683         //       after the cameras are scanned.
684         else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
685         {
686             int nr = 0;
687             token += strlen("controller=");
688             nr = sscanf( token, "%u", &p_sys->controller );
689             if( nr != 1)
690             {
691                 msg_Err(p_demux, "Bad controller value '%s', "
692                                  "must be an unsigned integer.",
693                                  token );
694                 return VLC_EGENERIC;
695             }
696         }
697 #endif
698         else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
699         {
700             int nr = 0;
701             token += strlen("camera=");
702             nr = sscanf(token,"%u",&p_sys->selected_camera);
703             if( nr != 1)
704             {
705                 msg_Err( p_demux, "Bad camera number '%s', "
706                                   "must be an unsigned integer.",
707                                   token );
708                 free(psz_dup);
709                 return VLC_EGENERIC;
710             }
711         }
712         else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
713         {
714             token += strlen("vdev=");
715             p_sys->video_device = strdup(token);
716             msg_Dbg( p_demux, "Using video device '%s'.", token );
717         }
718         else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
719         {
720             int nr = 0;
721             token += strlen("focus=");
722             nr = sscanf( token, "%u", &p_sys->focus );
723             if( nr != 1 )
724             {
725                 msg_Err( p_demux, "Bad focus value '%s', "
726                                   "must be an unsigned integer.",
727                                   token );
728                 free(psz_dup);
729                 return VLC_EGENERIC;
730             }
731         }
732         else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
733         {
734             token += strlen("uid=");
735             sscanf( token, "0x%"SCNx64, &p_sys->selected_uid );
736         }
737     }
738
739     // The mode is a combination of size and format and not every format
740     // is supported by every size.
741     if( in_size)
742     {
743         if( strcmp( in_size, "160x120") == 0)
744         {
745             if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
746                 msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
747             p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
748         }
749         else if( strcmp( in_size, "320x240") == 0)
750         {
751             if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
752                 msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
753             p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
754         }
755     }
756     else
757     { // 640x480 default
758         if( in_fmt )
759         {
760             if( strcmp( in_fmt, "RGB8") == 0)
761                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
762             else if( strcmp( in_fmt, "MONO8") == 0)
763                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
764             else if( strcmp( in_fmt, "MONO16") == 0)
765                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
766             else if( strcmp( in_fmt, "YUV411") == 0)
767                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
768             else // YUV422 default
769                 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
770         }
771         else // YUV422 default
772             p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
773     }
774
775     free( psz_dup );
776     return VLC_SUCCESS;
777 }