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