]> git.sesse.net Git - vlc/blob - modules/access/dc1394.c
Merge branch 1.0-bugfix
[vlc] / modules / access / dc1394.c
1 /*****************************************************************************
2  * dc1394.c: firewire input module
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  *
6  * Authors: Xant Majere <xant@xant.net>
7  *
8  *****************************************************************************
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation;
12  * version 2 of the License.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_input.h>
36 #include <vlc_demux.h>
37
38
39 #ifdef HAVE_FCNTL_H
40 #   include <fcntl.h>
41 #endif
42 #ifdef HAVE_UNISTD_H
43 #   include <unistd.h>
44 #elif defined( WIN32 ) && !defined( UNDER_CE )
45 #   include <io.h>
46 #endif
47
48 #include <sys/ioctl.h>
49 #include <sys/soundcard.h>
50
51 #include <libraw1394/raw1394.h>
52 #include <libdc1394/dc1394_control.h>
53
54 #define MAX_IEEE1394_HOSTS 32
55 #define MAX_CAMERA_NODES 32
56
57 /*****************************************************************************
58  * Module descriptor
59  *****************************************************************************/
60 static int  Open ( vlc_object_t * );
61 static void Close( vlc_object_t * );
62 static void OpenAudioDev( demux_t *p_demux );
63 static inline void CloseAudioDev( demux_t *p_demux );
64
65 vlc_module_begin ()
66     set_description( N_("dc1394 input") )
67     set_capability( "access_demux", 10 )
68     add_shortcut( "dc1394" )
69     set_callbacks( Open, Close )
70 vlc_module_end ()
71
72 typedef struct __dc_camera
73 {
74     int port;
75     nodeid_t node;
76     u_int64_t uid;
77 } dc_camera;
78
79 typedef struct demux_sys_t
80 {
81     dc1394_cameracapture camera;
82     picture_t            pic;
83     int                  dma_capture;
84 #define DMA_OFF 0
85 #define DMA_ON 1
86     int                 num_ports;
87     int                 num_cameras;
88     int                 selected_camera;
89     u_int64_t           selected_uid;
90
91     dc_camera           *camera_nodes;
92     dc1394_camerainfo   camera_info;
93     dc1394_miscinfo     misc_info;
94     raw1394handle_t     fd_video;
95     quadlet_t           supported_framerates;
96
97     int                 width;
98     int                 height;
99     int                 frame_size;
100     int                 frame_rate;
101     unsigned int        brightness;
102     unsigned int        focus;
103     char                *dma_device;
104     es_out_id_t         *p_es_video;
105
106     /* audio stuff */
107     int                 i_sample_rate;
108     int                 channels;
109     int                 i_audio_max_frame_size;
110     int                 fd_audio;
111     char                *audio_device;
112 #define NO_ROTATION 0
113 #define ROTATION_LEFT 1
114 #define ROTATION_RIGHT 2
115     es_out_id_t         *p_es_audio;
116 } dc1394_sys;
117
118 /*****************************************************************************
119  * Local prototypes
120  *****************************************************************************/
121 static int Demux( demux_t *p_demux );
122 static int Control( demux_t *, int, va_list );
123 static block_t *GrabVideo( demux_t *p_demux );
124 static block_t *GrabAudio( demux_t *p_demux );
125 static int process_options( demux_t *p_demux);
126
127 /*****************************************************************************
128  * ScanCameras
129  *****************************************************************************/
130 static void ScanCameras( dc1394_sys *sys, demux_t *p_demux )
131 {
132     struct raw1394_portinfo portinfo[MAX_IEEE1394_HOSTS];
133     raw1394handle_t tempFd;
134     dc1394_camerainfo  info;
135     dc_camera *node_list = NULL;
136     nodeid_t  *nodes = NULL;
137     int num_ports = 0;
138     int num_cameras = 0;
139     int nodecount;
140     int i, n;
141
142     memset( &portinfo, 0, sizeof(portinfo) );
143
144     msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
145
146     tempFd = raw1394_new_handle();
147     if( !tempFd )
148         return VLC_EGENERIC;
149     raw1394_get_port_info( tempFd, portinfo, MAX_IEEE1394_HOSTS);
150     raw1394_destroy_handle( tempFd );
151
152     for( i=0; i < MAX_IEEE1394_HOSTS; i++ )
153     {
154         /* check if port exists and has at least one node*/
155         if( !portinfo[i].nodes )
156             continue;
157         nodes = NULL;
158         nodecount = 0;
159         tempFd = dc1394_create_handle( i );
160
161         /* skip this port if we can't obtain a valid handle */
162         if( !tempFd )
163             continue;
164         msg_Dbg( p_demux, "Found ieee1394 port %d (%s) ... "
165                           "checking for camera nodes",
166                           i, portinfo[i].name );
167         num_ports++;
168
169         nodes = dc1394_get_camera_nodes( tempFd, &nodecount, 0 );
170         if( nodecount )
171         {
172             msg_Dbg( p_demux, "Found %d dc1394 cameras on port %d (%s)",
173                      nodecount, i, portinfo[i].name );
174
175             if( node_list )
176                 node_list = realloc( node_list, sizeof(dc_camera) * (num_cameras+nodecount) );
177             else
178                 node_list = malloc( sizeof(dc_camera) * nodecount);
179
180             for( n = 0; n < nodecount; n++ )
181             {
182                 int result = 0;
183
184                 result = dc1394_get_camera_info( tempFd, nodes[n], &info );
185                 if( result == DC1394_SUCCESS )
186                 {
187                     node_list[num_cameras+n].uid = info.euid_64;
188                 }
189                 node_list[num_cameras+n].node = nodes[n];
190                 node_list[num_cameras+n].port = i;
191             }
192             num_cameras += nodecount;
193         }
194         else
195             msg_Dbg( p_demux, "no cameras found  on port %d (%s)",
196                      i, portinfo[i].name );
197
198         if( tempFd )
199             dc1394_destroy_handle( tempFd );
200     }
201     sys->num_ports = num_ports;
202     sys->num_cameras = num_cameras;
203     sys->camera_nodes = node_list;
204 }
205
206 /*****************************************************************************
207  * Open:
208  *****************************************************************************/
209 static int Open( vlc_object_t *p_this )
210 {
211     demux_t     *p_demux = (demux_t*)p_this;
212     demux_sys_t *p_sys;
213     es_format_t fmt;
214     int i;
215     int i_width;
216     int i_height;
217     int result = 0;
218
219     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
220         return VLC_EGENERIC;
221
222     /* Set up p_demux */
223     p_demux->pf_demux = Demux;
224     p_demux->pf_control = Control;
225     p_demux->info.i_update = 0;
226     p_demux->info.i_title = 0;
227     p_demux->info.i_seekpoint = 0;
228
229     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
230     if( !p_sys )
231         return VLC_ENOMEM;
232     memset( &fmt, 0, sizeof( es_format_t ) );
233
234     /* DEFAULTS */
235     p_sys->frame_size = MODE_640x480_YUV422;
236     p_sys->width      = 640;
237     p_sys->height     = 480;
238     p_sys->frame_rate = FRAMERATE_30;
239     p_sys->brightness = 200;
240     p_sys->focus      = 0;
241     p_sys->dma_capture = DMA_ON; /* defaults to VIDEO1394 capture mode */
242     p_sys->fd_audio   = -1;
243     p_sys->fd_video   = NULL;
244     p_sys->camera_nodes = NULL;
245     p_sys->selected_camera = 0;
246     p_sys->dma_device = NULL;
247     p_sys->selected_uid = 0;
248
249     /* PROCESS INPUT OPTIONS */
250     if( process_options(p_demux) != VLC_SUCCESS )
251     {
252         msg_Err( p_demux, "Bad MRL, please check the option line "
253                           "(MRL was: %s)",
254                           p_demux->psz_path );
255         free( p_sys );
256         p_demux->p_sys = NULL;
257         return VLC_EGENERIC;
258     }
259
260     msg_Dbg( p_demux, "Selected camera %d", p_sys->selected_camera );
261     msg_Dbg( p_demux, "Selected uid 0x%llx", p_sys->selected_uid );
262
263     ScanCameras( p_sys, p_demux );
264     if( !p_sys->camera_nodes )
265     {
266         msg_Err( p_demux, "No camera found !!" );
267         free( p_sys );
268         p_demux->p_sys = NULL;
269         return VLC_EGENERIC;
270     }
271
272     if( p_sys->selected_uid )
273     {
274         int found = 0;
275         for( i=0; i < p_sys->num_cameras; i++ )
276         {
277             if( p_sys->camera_nodes[i].uid == p_sys->selected_uid )
278             {
279                 p_sys->selected_camera = i;
280                 found++;
281                 break;
282             }
283         }
284         if( !found )
285         {
286             msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
287                      p_sys->selected_uid );
288             Close( p_this );
289             return VLC_EGENERIC;
290         }
291     }
292     else if( p_sys->selected_camera >= p_sys->num_cameras )
293     {
294         msg_Err( p_demux, "there are not this many cameras. (%d/%d)",
295                           p_sys->selected_camera, p_sys->num_cameras );
296         Close( p_this );
297         return VLC_EGENERIC;
298     }
299
300     p_sys->fd_video = dc1394_create_handle(
301                         p_sys->camera_nodes[p_sys->selected_camera].port );
302     if( (int)p_sys->fd_video < 0 )
303     {
304         msg_Err( p_demux, "Can't init dc1394 handle" );
305         Close( p_this );
306         return VLC_EGENERIC;
307     }
308
309     /* get camera info */
310     result = dc1394_get_camera_info( p_sys->fd_video,
311                         p_sys->camera_nodes[p_sys->selected_camera].node,
312                         &p_sys->camera_info );
313     if( result != DC1394_SUCCESS )
314     {
315         msg_Err( p_demux ,"unable to get camera info" );
316         Close( p_this );
317         return VLC_EGENERIC;
318     }
319
320     dc1394_print_camera_info( &p_sys->camera_info );
321     result = dc1394_get_camera_misc_info( p_sys->fd_video,
322                         p_sys->camera_nodes[p_sys->selected_camera].node,
323                         &p_sys->misc_info );
324     if( result != DC1394_SUCCESS )
325     {
326         msg_Err( p_demux, "unable to get camera misc info" );
327         Close( p_this );
328         return VLC_EGENERIC;
329     }
330
331     /* init camera and set some video options  */
332     result = dc1394_init_camera( p_sys->camera_info.handle,
333                                  p_sys->camera_info.id );
334     if( result != DC1394_SUCCESS )
335     {
336         msg_Err( p_demux, "unable to get init dc1394 camera" );
337         Close( p_this );
338         return VLC_EGENERIC;
339     }
340
341     if( p_sys->focus )
342     {
343         result = dc1394_set_focus( p_sys->camera_info.handle,
344                         p_sys->camera_nodes[p_sys->selected_camera].node,
345                         p_sys->focus );
346         if( result != DC1394_SUCCESS )
347         {
348             msg_Err( p_demux, "unable to set initial focus to %u",
349                      p_sys->focus );
350         }
351         msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
352     }
353
354     result = dc1394_set_brightness( p_sys->camera_info.handle,
355                         p_sys->camera_nodes[p_sys->selected_camera].node,
356                         p_sys->brightness );
357     if( result != DC1394_SUCCESS )
358     {
359         msg_Err( p_demux, "unable to set init brightness to %d",
360                  p_sys->brightness);
361         Close( p_this );
362         return VLC_EGENERIC;
363     }
364
365     result = dc1394_set_video_framerate( p_sys->camera_info.handle,
366                         p_sys->camera_nodes[p_sys->selected_camera].node,
367                         p_sys->frame_rate );
368     if( result != DC1394_SUCCESS )
369     {
370         msg_Err( p_demux, "unable to set framerate to %d",
371                  p_sys->frame_rate );
372         Close( p_this );
373         return VLC_EGENERIC;
374     }
375     p_sys->misc_info.framerate = p_sys->frame_rate;
376
377     result = dc1394_set_video_format( p_sys->camera_info.handle,
378                         p_sys->camera_nodes[p_sys->selected_camera].node,
379                         FORMAT_VGA_NONCOMPRESSED );
380     if( result != DC1394_SUCCESS )
381     {
382         msg_Err( p_demux, "unable to set video format to VGA_NONCOMPRESSED" );
383         Close( p_this );
384         return VLC_EGENERIC;
385     }
386     p_sys->misc_info.format = FORMAT_VGA_NONCOMPRESSED;
387
388     result = dc1394_set_video_mode( p_sys->camera_info.handle,
389                         p_sys->camera_nodes[p_sys->selected_camera].node,
390                         p_sys->frame_size );
391     if( result != DC1394_SUCCESS )
392     {
393         msg_Err( p_demux, "unable to set video mode" );
394         Close( p_this );
395         return VLC_EGENERIC;
396     }
397     p_sys->misc_info.mode = p_sys->frame_size;
398
399     /* reprobe everything */
400     result = dc1394_get_camera_info( p_sys->camera_info.handle,
401                                      p_sys->camera_info.id,
402                                      &p_sys->camera_info );
403     if( result != DC1394_SUCCESS )
404     {
405         msg_Err( p_demux, "Could not get camera basic information!" );
406         Close( p_this );
407         return VLC_EGENERIC;
408     }
409
410     result = dc1394_get_camera_misc_info( p_sys->camera_info.handle,
411                                           p_sys->camera_info.id,
412                                           &p_sys->misc_info );
413     if( result != DC1394_SUCCESS )
414     {
415         msg_Err( p_demux, "Could not get camera misc information!" );
416         Close( p_this );
417         return VLC_EGENERIC;
418     }
419
420     /* set iso_channel */
421     result = dc1394_set_iso_channel_and_speed( p_sys->camera_info.handle,
422                                                p_sys->camera_info.id,
423                                                p_sys->selected_camera,
424                                                SPEED_400 );
425     if( result != DC1394_SUCCESS )
426     {
427         msg_Err( p_demux, "Could not set iso channel!" );
428         Close( p_this );
429         return VLC_EGENERIC;
430     }
431     msg_Dbg( p_demux, "Using ISO channel %d", p_sys->misc_info.iso_channel );
432     p_sys->misc_info.iso_channel = p_sys->selected_camera;
433
434     /* and setup capture */
435     if( p_sys->dma_capture )
436     {
437         result = dc1394_dma_setup_capture( p_sys->camera_info.handle,
438                         p_sys->camera_info.id,
439                         p_sys->misc_info.iso_channel,
440                         p_sys->misc_info.format,
441                         p_sys->misc_info.mode,
442                         SPEED_400,
443                         p_sys->misc_info.framerate,
444                         10, 0,
445                         p_sys->dma_device,
446                         &p_sys->camera );
447         if( result != DC1394_SUCCESS )
448         {
449             msg_Err( p_demux ,"unable to setup camera" );
450             Close( p_this );
451             return VLC_EGENERIC;
452         }
453     }
454     else
455     {
456         result = dc1394_setup_capture( p_sys->camera_info.handle,
457                     p_sys->camera_info.id,
458                     p_sys->misc_info.iso_channel,
459                     p_sys->misc_info.format,
460                     p_sys->misc_info.mode,
461                     SPEED_400,
462                     p_sys->misc_info.framerate,
463                     &p_sys->camera );
464         if( result != DC1394_SUCCESS)
465         {
466             msg_Err( p_demux ,"unable to setup camera" );
467             Close( p_this );
468             return VLC_EGENERIC;
469         }
470     }
471
472     /* TODO - UYV444 chroma converter is missing, when it will be available
473      * fourcc will become variable (and not just a fixed value for UYVY)
474      */
475     i_width = p_sys->camera.frame_width;
476     i_height = p_sys->camera.frame_height;
477
478     if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
479                        i_width, i_height,
480                        i_width * VOUT_ASPECT_FACTOR / i_height ) )
481     {
482         msg_Err( p_demux ,"unknown chroma" );
483         Close( p_this );
484         return VLC_EGENERIC;
485     }
486
487     es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
488
489     fmt.video.i_width = i_width;
490     fmt.video.i_height = i_height;
491
492     msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
493              (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
494
495     p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
496
497     if( p_sys->audio_device )
498     {
499         OpenAudioDev( p_demux );
500         if( p_sys->fd_audio >= 0 )
501         {
502             es_format_t fmt;
503             es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L ); /* FIXME: hmm, ?? */
504
505             fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
506             fmt.audio.i_rate = p_sys->i_sample_rate;
507             fmt.audio.i_bitspersample = 16;
508             fmt.audio.i_blockalign = fmt.audio.i_channels *
509                                      fmt.audio.i_bitspersample / 8;
510             fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
511                             fmt.audio.i_bitspersample;
512
513             msg_Dbg( p_demux, "new audio es %d channels %dHz",
514             fmt.audio.i_channels, fmt.audio.i_rate );
515
516             p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
517         }
518     }
519
520     /* have the camera start sending us data */
521     result = dc1394_start_iso_transmission( p_sys->camera_info.handle,
522                                             p_sys->camera_info.id );
523     if( result != DC1394_SUCCESS )
524     {
525         msg_Err( p_demux, "unable to start camera iso transmission" );
526         if( p_sys->dma_capture )
527         {
528             dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
529         }
530         else
531         {
532             dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
533         }
534         Close( p_this );
535         return VLC_EGENERIC;
536     }
537     p_sys->misc_info.is_iso_on = DC1394_TRUE;
538     return VLC_SUCCESS;
539 }
540
541 static void OpenAudioDev( demux_t *p_demux )
542 {
543     demux_sys_t *p_sys = p_demux->p_sys;
544     char *psz_device = p_sys->audio_device;
545     int i_format = AFMT_S16_LE;
546     int result;
547
548     p_sys->fd_audio = open( psz_device, O_RDONLY | O_NONBLOCK );
549     if( p_sys->fd_audio  < 0 )
550     {
551         msg_Err( p_demux, "cannot open audio device (%s)", psz_device );
552         CloseAudioDev( p_demux );
553     }
554
555     if( !p_sys->i_sample_rate )
556         p_sys->i_sample_rate = 44100;
557
558     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format );
559     if( (result  < 0) || (i_format != AFMT_S16_LE) )
560     {
561         msg_Err( p_demux, "cannot set audio format (16b little endian) "
562                           "(%d)", i_format );
563         CloseAudioDev( p_demux );
564     }
565
566     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
567     if( result < 0 )
568     {
569         msg_Err( p_demux, "cannot set audio channels count (%d)",
570                  p_sys->channels );
571         CloseAudioDev( p_demux );
572     }
573
574     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
575     if( result < 0 )
576     {
577         msg_Err( p_demux, "cannot set audio sample rate (%s)", p_sys->i_sample_rate );
578         CloseAudioDev( p_demux );
579     }
580
581     msg_Dbg( p_demux, "opened adev=`%s' %s %dHz",
582              psz_device,
583              (p_sys->channels > 1) ? "stereo" : "mono",
584              p_sys->i_sample_rate );
585
586     p_sys->i_audio_max_frame_size = 32 * 1024;
587 }
588
589 static inline void CloseAudioDev( demux_t *p_demux )
590 {
591     demux_sys_t *p_sys = NULL;
592
593     if( p_demux )
594     {
595         p_sys = p_demux->p_sys;
596         if( p_sys->fd_audio >= 0 )
597             close( p_sys->fd_audio );
598     }
599 }
600
601 /*****************************************************************************
602  * Close:
603  *****************************************************************************/
604 static void Close( vlc_object_t *p_this )
605 {
606     demux_t     *p_demux = (demux_t*)p_this;
607     demux_sys_t *p_sys = p_demux->p_sys;
608     int result = 0;
609
610     /* Stop data transmission */
611     result = dc1394_stop_iso_transmission( p_sys->fd_video,
612                                            p_sys->camera.node );
613     if( result != DC1394_SUCCESS )
614     {
615         msg_Err( p_demux, "couldn't stop the camera" );
616     }
617
618     /* Close camera */
619     if( p_sys->dma_capture )
620     {
621         dc1394_dma_unlisten( p_sys->fd_video, &p_sys->camera );
622         dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
623     }
624     else
625     {
626         dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
627     }
628
629     if( p_sys->fd_video )
630         dc1394_destroy_handle( p_sys->fd_video );
631     CloseAudioDev( p_demux );
632
633     free( p_sys->camera_nodes );
634     free( p_sys->audio_device );
635
636     free( p_sys );
637 }
638
639 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
640 {
641     char u,v,y;
642     u_char  *sc;
643     u_char  *dc;
644
645     sc = (u_char *)src + (spos*2);
646     if( spos % 2 )
647     {
648         v = sc[0];
649         y = sc[1];
650         u = *(sc -2);
651     }
652     else
653     {
654         u = sc[0];
655         y = sc[1];
656         v = sc[2];
657     }
658     dc = (u_char *)dst+(dpos*2);
659     if( dpos % 2 )
660     {
661         dc[0] = v;
662         dc[1] = y;
663     }
664     else
665     {
666         dc[0] = u;
667         dc[1] = y;
668     }
669 }
670
671 /*****************************************************************************
672  * Demux:
673  *****************************************************************************/
674 static block_t *GrabVideo( demux_t *p_demux )
675 {
676     demux_sys_t *p_sys = p_demux->p_sys;
677     block_t     *p_block = NULL;
678     int result = 0;
679
680     if( p_sys->dma_capture )
681     {
682         result = dc1394_dma_single_capture( &p_sys->camera );
683         if( result != DC1394_SUCCESS )
684         {
685             msg_Err( p_demux, "unable to capture a frame" );
686             return NULL;
687         }
688     }
689     else
690     {
691         result = dc1394_single_capture( p_sys->camera_info.handle,
692                                         &p_sys->camera );
693         if( result != DC1394_SUCCESS )
694         {
695             msg_Err( p_demux, "unable to capture a frame" );
696             return NULL;
697         }
698     }
699
700     p_block = block_New( p_demux, p_sys->camera.frame_width *
701                                   p_sys->camera.frame_height * 2 );
702     if( !p_block )
703     {
704         msg_Err( p_demux, "cannot get block" );
705         return NULL;
706     }
707
708     if( !p_sys->camera.capture_buffer )
709     {
710         msg_Err (p_demux, "caputer buffer empty");
711         block_Release( p_block );
712         return NULL;
713     }
714
715     memcpy( p_block->p_buffer, (const char *)p_sys->camera.capture_buffer,
716             p_sys->camera.frame_width * p_sys->camera.frame_height * 2 );
717
718     p_block->i_pts = p_block->i_dts = mdate();
719     if( p_sys->dma_capture )
720         dc1394_dma_done_with_buffer( &p_sys->camera );
721     return p_block;
722 }
723
724 static block_t *GrabAudio( demux_t *p_demux )
725 {
726     demux_sys_t *p_sys = p_demux->p_sys;
727     struct audio_buf_info buf_info;
728     block_t *p_block = NULL;
729     int i_read = 0;
730     int i_correct = 0;
731     int result = 0;
732
733     p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
734     if( !p_block )
735     {
736         msg_Warn( p_demux, "cannot get buffer" );
737         return NULL;
738     }
739
740     i_read = read( p_sys->fd_audio, p_block->p_buffer,
741                    p_sys->i_audio_max_frame_size );
742
743     if( i_read <= 0 )
744         return NULL;
745
746     p_block->i_buffer = i_read;
747
748     /* Correct the date because of kernel buffering */
749     i_correct = i_read;
750     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info );
751     if( result == 0 )
752         i_correct += buf_info.bytes;
753
754     p_block->i_pts = p_block->i_dts =
755                         mdate() - INT64_C(1000000) * (mtime_t)i_correct /
756                         2 / p_sys->channels / p_sys->i_sample_rate;
757     return p_block;
758 }
759
760 static int Demux( demux_t *p_demux )
761 {
762     demux_sys_t *p_sys = p_demux->p_sys;
763     block_t *p_blocka = NULL;
764     block_t *p_blockv = NULL;
765
766     /* Try grabbing audio frames first */
767     if( p_sys->fd_audio > 0 )
768         p_blocka = GrabAudio( p_demux );
769
770     /* Try grabbing video frame */
771     if( (int)p_sys->fd_video > 0 )
772         p_blockv = GrabVideo( p_demux );
773
774     if( !p_blocka && !p_blockv )
775     {
776         /* Sleep so we do not consume all the cpu, 10ms seems
777          * like a good value (100fps)
778          */
779         msleep( 10000 );
780         return 1;
781     }
782
783     if( p_blocka )
784     {
785         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blocka->i_pts );
786         es_out_Send( p_demux->out, p_sys->p_es_audio, p_blocka );
787     }
788
789     if( p_blockv )
790     {
791         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
792         es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
793     }
794     return 1;
795 }
796
797 /*****************************************************************************
798  * Control:
799  *****************************************************************************/
800 static int Control( demux_t *p_demux, int i_query, va_list args )
801 {
802     bool *pb;
803     int64_t    *pi64;
804
805     switch( i_query )
806     {
807         /* Special for access_demux */
808         case DEMUX_CAN_PAUSE:
809         case DEMUX_CAN_SEEK:
810         case DEMUX_SET_PAUSE_STATE:
811         case DEMUX_CAN_CONTROL_PACE:
812             pb = (bool*)va_arg( args, bool * );
813             *pb = false;
814             return VLC_SUCCESS;
815
816         case DEMUX_GET_PTS_DELAY:
817             pi64 = (int64_t*)va_arg( args, int64_t * );
818             *pi64 = (int64_t)DEFAULT_PTS_DELAY;
819             return VLC_SUCCESS;
820
821         case DEMUX_GET_TIME:
822             pi64 = (int64_t*)va_arg( args, int64_t * );
823             *pi64 = mdate();
824             return VLC_SUCCESS;
825
826         /* TODO implement others */
827         default:
828             return VLC_EGENERIC;
829     }
830     return VLC_EGENERIC;
831 }
832
833 static int process_options( demux_t *p_demux )
834 {
835     demux_sys_t *p_sys = p_demux->p_sys;
836     char *psz_dup;
837     char *psz_parser;
838     char *token = NULL;
839     char *state = NULL;
840     float rate_f;
841
842     psz_dup = strdup( p_demux->psz_path );
843     psz_parser = psz_dup;
844     for( token = strtok_r( psz_parser,":",&state); token;
845          token = strtok_r( NULL, ":", &state ) )
846     {
847         if( strncmp( token, "size=", strlen("size=") ) == 0 )
848         {
849             token += strlen("size=");
850             if( strncmp( token, "160x120", 7 ) == 0 )
851             {
852                 /* TODO - UYV444 chroma converter is needed ...
853                     * video size of 160x120 is temporarily disabled
854                     */
855                 msg_Err( p_demux,
856                     "video size of 160x120 is actually disabled for lack of chroma "
857                     "support. It will relased ASAP, until then try an higher size "
858                     "(320x240 and 640x480 are fully supported)" );
859                 free( psz_dup );
860                 return VLC_EGENERIC;
861 #if 0
862                 p_sys->frame_size = MODE_160x120_YUV444;
863                 p_sys->width = 160;
864                 p_sys->height = 120;
865 #endif
866             }
867             else if( strncmp( token, "320x240", 7 ) == 0 )
868             {
869                 p_sys->frame_size = MODE_320x240_YUV422;
870                 p_sys->width = 320;
871                 p_sys->height = 240;
872             }
873             else if( strncmp( token, "640x480", 7 ) == 0 )
874             {
875                 p_sys->frame_size = MODE_640x480_YUV422;
876                 p_sys->width = 640;
877                 p_sys->height = 480;
878             }
879             else
880             {
881                 msg_Err( p_demux,
882                     "This program currently suppots frame sizes of"
883                     " 160x120, 320x240, and 640x480. "
884                     "Please specify one of them. You have specified %s.",
885                     token );
886                 free( psz_dup );
887                 return VLC_EGENERIC;
888             }
889             msg_Dbg( p_demux, "Requested video size : %s",token );
890         }
891         else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
892         {
893             token += strlen("fps=");
894             sscanf( token, "%g", &rate_f );
895             if( rate_f == 1.875 )
896                 p_sys->frame_rate = FRAMERATE_1_875;
897             else if( rate_f == 3.75 )
898                 p_sys->frame_rate = FRAMERATE_3_75;
899             else if( rate_f == 7.5 )
900                 p_sys->frame_rate = FRAMERATE_7_5;
901             else if( rate_f == 15 )
902                 p_sys->frame_rate = FRAMERATE_15;
903             else if( rate_f == 30 )
904                 p_sys->frame_rate = FRAMERATE_30;
905             else if( rate_f == 60 )
906                 p_sys->frame_rate = FRAMERATE_60;
907             else
908             {
909                 msg_Err( p_demux ,
910                     "This program supports framerates of"
911                     " 1.875, 3.75, 7.5, 15, 30, 60. "
912                     "Please specify one of them. You have specified %s.",
913                     token);
914                 free( psz_dup );
915                 return VLC_EGENERIC;
916             }
917             msg_Dbg( p_demux, "Requested frame rate : %s",token );
918         }
919         else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
920         {
921             int nr = 0;
922             token += strlen("brightness=");
923             nr = sscanf( token, "%u", &p_sys->brightness);
924             if( nr != 1 )
925             {
926                 msg_Err( p_demux, "Bad brightness value '%s', "
927                                   "must be an unsigned integer.",
928                                   token );
929                 free( psz_dup );
930                 return VLC_EGENERIC;
931             }
932         }
933 #if 0
934         else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
935         {
936             int nr = 0;
937             token += strlen("controller=");
938             nr = sscanf( token, "%u", &p_sys->controller );
939             if( nr != 1)
940             {
941                 msg_Err(p_demux, "Bad controller value '%s', "
942                                  "must be an unsigned integer.",
943                                  token );
944                 return VLC_EGENERIC;
945             }
946         }
947 #endif
948         else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
949         {
950             int nr = 0;
951             token += strlen("camera=");
952             nr = sscanf(token,"%u",&p_sys->selected_camera);
953             if( nr != 1)
954             {
955                 msg_Err( p_demux, "Bad camera number '%s', "
956                                   "must be an unsigned integer.",
957                                   token );
958                 free( psz_dup );
959                 return VLC_EGENERIC;
960             }
961         }
962         else if( strncmp( token, "capture=", strlen( "capture=" ) ) == 0)
963         {
964             token += strlen("capture=");
965             if( strncmp(token, "raw1394",7) == 0 )
966             {
967                 msg_Dbg( p_demux, "DMA capture disabled!" );
968                 p_sys->dma_capture = DMA_OFF;
969             }
970             else if( strncmp(token,"video1394",9) == 0 )
971             {
972                 msg_Dbg( p_demux, "DMA capture enabled!" );
973                 p_sys->dma_capture = DMA_ON;
974             }
975             else
976             {
977                 msg_Err(p_demux, "Bad capture method value '%s', "
978                                  "it can be 'raw1394' or 'video1394'.",
979                                 token );
980                 free( psz_dup );
981                 return VLC_EGENERIC;
982             }
983         }
984         else if( strncmp( token, "adev=", strlen( "adev=" ) ) == 0 )
985         {
986             token += strlen("adev=");
987             p_sys->audio_device = strdup(token);
988             msg_Dbg( p_demux, "Using audio device '%s'.", token );
989         }
990         else if( strncmp( token, "samplerate=", strlen( "samplerate=" ) ) == 0 )
991         {
992             token += strlen("samplerate=");
993             sscanf( token, "%d", &p_sys->i_sample_rate );
994         }
995         else if( strncmp( token, "channels=", strlen("channels=" ) ) == 0 )
996         {
997             token += strlen("channels=");
998             sscanf( token, "%d", &p_sys->channels );
999         }
1000         else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
1001         {
1002             token += strlen("focus=");
1003             sscanf( token, "%u", &p_sys->focus );
1004         }
1005         else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
1006         {
1007             token += strlen("uid=");
1008             sscanf( token, "0x%llx", &p_sys->selected_uid );
1009         }
1010     }
1011     free( psz_dup );
1012     return VLC_SUCCESS;
1013 }
1014