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