]> git.sesse.net Git - vlc/blob - modules/access/dc1394.c
Remove stdlib.h
[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 #include <vlc/vlc.h>
30 #include <vlc_input.h>
31 #include <vlc_vout.h>
32 #include <vlc_demux.h>
33
34 #include <stdio.h>
35 #include <string.h>
36
37 #ifdef HAVE_FCNTL_H
38 #   include <fcntl.h>
39 #endif
40 #ifdef HAVE_UNISTD_H
41 #   include <unistd.h>
42 #elif defined( WIN32 ) && !defined( UNDER_CE )
43 #   include <io.h>
44 #endif
45
46 #include <sys/ioctl.h>
47 #include <sys/soundcard.h>
48
49 #include <libraw1394/raw1394.h>
50 #include <libdc1394/dc1394_control.h>
51
52 #define MAX_IEEE1394_HOSTS 32
53 #define MAX_CAMERA_NODES 32
54
55 /*****************************************************************************
56  * Module descriptor
57  *****************************************************************************/
58 static int  Open ( vlc_object_t * );
59 static void Close( vlc_object_t * );
60 static void OpenAudioDev( demux_t *p_demux );
61 static inline void CloseAudioDev( demux_t *p_demux );
62
63 vlc_module_begin();
64     set_description( _("dc1394 input") );
65     set_capability( "access_demux", 10 );
66     add_shortcut( "dc1394" );
67     set_callbacks( Open, Close );
68 vlc_module_end();
69
70 typedef struct __dc_camera
71 {
72     int port;
73     nodeid_t node;
74     u_int64_t uid;
75 } dc_camera;
76
77 typedef struct demux_sys_t
78 {
79     dc1394_cameracapture camera;
80     picture_t            pic;
81     int                  dma_capture;
82 #define DMA_OFF 0
83 #define DMA_ON 1
84     int                 num_ports;
85     int                 num_cameras;
86     int                 selected_camera;
87     u_int64_t           selected_uid;
88
89     dc_camera           *camera_nodes;
90     dc1394_camerainfo   camera_info;
91     dc1394_miscinfo     misc_info;
92     raw1394handle_t     fd_video;
93     quadlet_t           supported_framerates;
94
95     int                 width;
96     int                 height;
97     int                 frame_size;
98     int                 frame_rate;
99     unsigned int        brightness;
100     unsigned int        focus;
101     char                *dma_device;
102     es_out_id_t         *p_es_video;
103
104     /* audio stuff */
105     int                 i_sample_rate;
106     int                 channels;
107     int                 i_audio_max_frame_size;
108     int                 fd_audio;
109     char                *audio_device;
110 #define NO_ROTATION 0
111 #define ROTATION_LEFT 1
112 #define ROTATION_RIGHT 2
113     es_out_id_t         *p_es_audio;
114 } dc1394_sys;
115
116 /*****************************************************************************
117  * Local prototypes
118  *****************************************************************************/
119 static int Demux( demux_t *p_demux );
120 static int Control( demux_t *, int, va_list );
121 static block_t *GrabVideo( demux_t *p_demux );
122 static block_t *GrabAudio( demux_t *p_demux );
123 static int process_options( demux_t *p_demux);
124
125 /*****************************************************************************
126  * ScanCameras
127  *****************************************************************************/
128 static void ScanCameras( dc1394_sys *sys, demux_t *p_demux )
129 {
130     struct raw1394_portinfo portinfo[MAX_IEEE1394_HOSTS];
131     raw1394handle_t tempFd;
132     dc1394_camerainfo  info;
133     dc_camera *node_list = NULL;
134     nodeid_t  *nodes = NULL;
135     int num_ports = 0;
136     int num_cameras = 0;
137     int nodecount;
138     int i, n;
139
140     memset( &portinfo, 0, sizeof(portinfo) );
141
142     msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
143
144     tempFd = raw1394_new_handle();
145     if( !tempFd )
146         return VLC_EGENERIC;
147     raw1394_get_port_info( tempFd, portinfo, MAX_IEEE1394_HOSTS);
148     raw1394_destroy_handle( tempFd );
149
150     for( i=0; i < MAX_IEEE1394_HOSTS; i++ )
151     {
152         /* check if port exists and has at least one node*/
153         if( !portinfo[i].nodes )
154             continue;
155         nodes = NULL;
156         nodecount = 0;
157         tempFd = dc1394_create_handle( i );
158
159         /* skip this port if we can't obtain a valid handle */
160         if( !tempFd )
161             continue;
162         msg_Dbg( p_demux, "Found ieee1394 port %d (%s) ... "
163                           "checking for camera nodes",
164                           i, portinfo[i].name );
165         num_ports++;
166
167         nodes = dc1394_get_camera_nodes( tempFd, &nodecount, 0 );
168         if( nodecount )
169         {
170             msg_Dbg( p_demux, "Found %d dc1394 cameras on port %d (%s)",
171                      nodecount, i, portinfo[i].name );
172
173             if( node_list )
174                 node_list = realloc( node_list, sizeof(dc_camera) * (num_cameras+nodecount) );
175             else
176                 node_list = malloc( sizeof(dc_camera) * nodecount);
177
178             for( n = 0; n < nodecount; n++ )
179             {
180                 int result = 0;
181
182                 result = dc1394_get_camera_info( tempFd, nodes[n], &info );
183                 if( result == DC1394_SUCCESS )
184                 {
185                     node_list[num_cameras+n].uid = info.euid_64;
186                 }
187                 node_list[num_cameras+n].node = nodes[n];
188                 node_list[num_cameras+n].port = i;
189             }
190             num_cameras += nodecount;
191         }
192         else
193             msg_Dbg( p_demux, "no cameras found  on port %d (%s)",
194                      i, portinfo[i].name );
195
196         if( tempFd )
197             dc1394_destroy_handle( tempFd );
198     }
199     sys->num_ports = num_ports;
200     sys->num_cameras = num_cameras;
201     sys->camera_nodes = node_list;
202 }
203
204 /*****************************************************************************
205  * Open:
206  *****************************************************************************/
207 static int Open( vlc_object_t *p_this )
208 {
209     demux_t     *p_demux = (demux_t*)p_this;
210     demux_sys_t *p_sys;
211     es_format_t fmt;
212     int i;
213     int i_width;
214     int i_height;
215     int i_aspect;
216     int result = 0;
217
218     /* Set up p_demux */
219     p_demux->pf_demux = Demux;
220     p_demux->pf_control = Control;
221     p_demux->info.i_update = 0;
222     p_demux->info.i_title = 0;
223     p_demux->info.i_seekpoint = 0;
224
225     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
226     if( !p_sys )
227     {
228         msg_Err( p_demux, "not enough memory available" );
229         return VLC_ENOMEM;
230     }
231     memset( p_sys, 0, sizeof( demux_sys_t ) );
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     i_aspect = vout_InitPicture( VLC_OBJECT(p_demux), &p_sys->pic,
479                     VLC_FOURCC('U', 'Y', 'V', 'Y'),
480                     i_width, i_height,
481                     i_width * VOUT_ASPECT_FACTOR / i_height );
482
483     es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC('U', 'Y', 'V', 'Y') );
484
485     fmt.video.i_width = i_width;
486     fmt.video.i_height = i_height;
487
488     msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
489              (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
490
491     p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
492
493     if( p_sys->audio_device )
494     {
495         OpenAudioDev( p_demux );
496         if( p_sys->fd_audio >= 0 )
497         {
498             es_format_t fmt;
499             es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
500
501             fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
502             fmt.audio.i_rate = p_sys->i_sample_rate;
503             fmt.audio.i_bitspersample = 16; /* FIXME: hmm, ?? */
504             fmt.audio.i_blockalign = fmt.audio.i_channels *
505                                      fmt.audio.i_bitspersample / 8;
506             fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
507                             fmt.audio.i_bitspersample;
508
509             msg_Dbg( p_demux, "new audio es %d channels %dHz",
510             fmt.audio.i_channels, fmt.audio.i_rate );
511
512             p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
513         }
514     }
515
516     /* have the camera start sending us data */
517     result = dc1394_start_iso_transmission( p_sys->camera_info.handle,
518                                             p_sys->camera_info.id );
519     if( result != DC1394_SUCCESS )
520     {
521         msg_Err( p_demux, "unable to start camera iso transmission" );
522         if( p_sys->dma_capture )
523         {
524             dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
525         }
526         else
527         {
528             dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
529         }
530         Close( p_this );
531         return VLC_EGENERIC;
532     }
533     p_sys->misc_info.is_iso_on = DC1394_TRUE;
534     return VLC_SUCCESS;
535 }
536
537 static void OpenAudioDev( demux_t *p_demux )
538 {
539     demux_sys_t *p_sys = p_demux->p_sys;
540     char *psz_device = p_sys->audio_device;
541     int i_format = AFMT_S16_LE;
542     int result;
543
544     p_sys->fd_audio = open( psz_device, O_RDONLY | O_NONBLOCK );
545     if( p_sys->fd_audio  < 0 )
546     {
547         msg_Err( p_demux, "cannot open audio device (%s)", psz_device );
548         CloseAudioDev( p_demux );
549     }
550
551     if( !p_sys->i_sample_rate )
552         p_sys->i_sample_rate = 44100;
553
554     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format );
555     if( (result  < 0) || (i_format != AFMT_S16_LE) )
556     {
557         msg_Err( p_demux, "cannot set audio format (16b little endian) "
558                           "(%d)", i_format );
559         CloseAudioDev( p_demux );
560     }
561
562     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
563     if( result < 0 )
564     {
565         msg_Err( p_demux, "cannot set audio channels count (%d)",
566                  p_sys->channels );
567         CloseAudioDev( p_demux );
568     }
569
570     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
571     if( result < 0 )
572     {
573         msg_Err( p_demux, "cannot set audio sample rate (%s)", p_sys->i_sample_rate );
574         CloseAudioDev( p_demux );
575     }
576
577     msg_Dbg( p_demux, "openened adev=`%s' %s %dHz",
578              psz_device,
579              (p_sys->channels > 1) ? "stereo" : "mono",
580              p_sys->i_sample_rate );
581
582     p_sys->i_audio_max_frame_size = 32 * 1024;
583 }
584
585 static inline void CloseAudioDev( demux_t *p_demux )
586 {
587     demux_sys_t *p_sys = NULL;
588
589     if( p_demux )
590     {
591         p_sys = p_demux->p_sys;
592         if( p_sys->fd_audio >= 0 )
593             close( p_sys->fd_audio );
594     }
595 }
596
597 /*****************************************************************************
598  * Close:
599  *****************************************************************************/
600 static void Close( vlc_object_t *p_this )
601 {
602     demux_t     *p_demux = (demux_t*)p_this;
603     demux_sys_t *p_sys = p_demux->p_sys;
604     int result = 0;
605
606     /* Stop data transmission */
607     result = dc1394_stop_iso_transmission( p_sys->fd_video,
608                                            p_sys->camera.node );
609     if( result != DC1394_SUCCESS )
610     {
611         msg_Err( p_demux, "couldn't stop the camera" );
612     }
613
614     /* Close camera */
615     if( p_sys->dma_capture )
616     {
617         dc1394_dma_unlisten( p_sys->fd_video, &p_sys->camera );
618         dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
619     }
620     else
621     {
622         dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
623     }
624
625     if( p_sys->fd_video )
626         dc1394_destroy_handle( p_sys->fd_video );
627     CloseAudioDev( p_demux );
628
629     if( p_sys->camera_nodes )
630         free( p_sys->camera_nodes );
631     if( p_sys->audio_device )
632         free( p_sys->audio_device );
633
634     free( p_sys );
635 }
636
637 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
638 {
639     char u,v,y;
640     u_char  *sc;
641     u_char  *dc;
642
643     sc = (u_char *)src + (spos*2);
644     if( spos % 2 )
645     {
646         v = sc[0];
647         y = sc[1];
648         u = *(sc -2);
649     }
650     else
651     {
652         u = sc[0];
653         y = sc[1];
654         v = sc[2];
655     }
656     dc = (u_char *)dst+(dpos*2);
657     if( dpos % 2 )
658     {
659         dc[0] = v;
660         dc[1] = y;
661     }
662     else
663     {
664         dc[0] = u;
665         dc[1] = y;
666     }
667 }
668
669 /*****************************************************************************
670  * Demux:
671  *****************************************************************************/
672 static block_t *GrabVideo( demux_t *p_demux )
673 {
674     demux_sys_t *p_sys = p_demux->p_sys;
675     block_t     *p_block = NULL;
676     int result = 0;
677
678     if( p_sys->dma_capture )
679     {
680         result = dc1394_dma_single_capture( &p_sys->camera );
681         if( result != DC1394_SUCCESS )
682         {
683             msg_Err( p_demux, "unable to capture a frame" );
684             return NULL;
685         }
686     }
687     else
688     {
689         result = dc1394_single_capture( p_sys->camera_info.handle,
690                                         &p_sys->camera );
691         if( result != DC1394_SUCCESS )
692         {
693             msg_Err( p_demux, "unable to capture a frame" );
694             return NULL;
695         }
696     }
697
698     p_block = block_New( p_demux, p_sys->camera.frame_width *
699                                   p_sys->camera.frame_height * 2 );
700     if( !p_block )
701     {
702         msg_Err( p_demux, "cannot get block" );
703         return NULL;
704     }
705
706     if( !p_sys->camera.capture_buffer )
707     {
708         msg_Err (p_demux, "caputer buffer empty");
709         block_Release( p_block );
710         return NULL;
711     }
712
713     memcpy( p_block->p_buffer, (const char *)p_sys->camera.capture_buffer,
714             p_sys->camera.frame_width * p_sys->camera.frame_height * 2 );
715
716     p_block->i_pts = p_block->i_dts = mdate();
717     if( p_sys->dma_capture )
718         dc1394_dma_done_with_buffer( &p_sys->camera );
719     return p_block;
720 }
721
722 static block_t *GrabAudio( demux_t *p_demux )
723 {
724     demux_sys_t *p_sys = p_demux->p_sys;
725     struct audio_buf_info buf_info;
726     block_t *p_block = NULL;
727     int i_read = 0;
728     int i_correct = 0;
729     int result = 0;
730
731     p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
732     if( !p_block )
733     {
734         msg_Warn( p_demux, "cannot get buffer" );
735         return NULL;
736     }
737
738     i_read = read( p_sys->fd_audio, p_block->p_buffer,
739                    p_sys->i_audio_max_frame_size );
740
741     if( i_read <= 0 )
742         return NULL;
743
744     p_block->i_buffer = i_read;
745
746     /* Correct the date because of kernel buffering */
747     i_correct = i_read;
748     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info );
749     if( result == 0 )
750         i_correct += buf_info.bytes;
751
752     p_block->i_pts = p_block->i_dts =
753                         mdate() - I64C(1000000) * (mtime_t)i_correct /
754                         2 / p_sys->channels / p_sys->i_sample_rate;
755     return p_block;
756 }
757
758 static int Demux( demux_t *p_demux )
759 {
760     demux_sys_t *p_sys = p_demux->p_sys;
761     block_t *p_blocka = NULL;
762     block_t *p_blockv = NULL;
763
764     /* Try grabbing audio frames first */
765     if( p_sys->fd_audio > 0 )
766         p_blocka = GrabAudio( p_demux );
767
768     /* Try grabbing video frame */
769     if( (int)p_sys->fd_video > 0 )
770         p_blockv = GrabVideo( p_demux );
771
772     if( !p_blocka && !p_blockv )
773     {
774         /* Sleep so we do not consume all the cpu, 10ms seems
775          * like a good value (100fps)
776          */
777         msleep( 10000 );
778         return 1;
779     }
780
781     if( p_blocka )
782     {
783         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blocka->i_pts );
784         es_out_Send( p_demux->out, p_sys->p_es_audio, p_blocka );
785     }
786
787     if( p_blockv )
788     {
789         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
790         es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
791     }
792     return 1;
793 }
794
795 /*****************************************************************************
796  * Control:
797  *****************************************************************************/
798 static int Control( demux_t *p_demux, int i_query, va_list args )
799 {
800     vlc_bool_t *pb;
801     int64_t    *pi64;
802
803     switch( i_query )
804     {
805         /* Special for access_demux */
806         case DEMUX_CAN_PAUSE:
807         case DEMUX_SET_PAUSE_STATE:
808         case DEMUX_CAN_CONTROL_PACE:
809             pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
810             *pb = VLC_FALSE;
811             return VLC_SUCCESS;
812
813         case DEMUX_GET_PTS_DELAY:
814             pi64 = (int64_t*)va_arg( args, int64_t * );
815             *pi64 = (int64_t)DEFAULT_PTS_DELAY;
816             return VLC_SUCCESS;
817
818         case DEMUX_GET_TIME:
819             pi64 = (int64_t*)va_arg( args, int64_t * );
820             *pi64 = mdate();
821             return VLC_SUCCESS;
822
823         /* TODO implement others */
824         default:
825             return VLC_EGENERIC;
826     }
827     return VLC_EGENERIC;
828 }
829
830 static int process_options( demux_t *p_demux )
831 {
832     demux_sys_t *p_sys = p_demux->p_sys;
833     char *psz_dup; 
834     char *psz_parser;
835     char *token = NULL;
836     char *state = NULL;
837     float rate_f;
838
839     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
840         return VLC_EGENERIC;
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     if( psz_dup ) free( psz_dup );
1012     return VLC_SUCCESS;
1013 }
1014