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