contrib: soxr: enable by default
[vlc.git] / modules / access / dc1394.c
blobcf523fbf3c859a1cac63b06e098c0637b47d7eb4
1 /*****************************************************************************
2 * dc1394.c: IIDC (DCAM) FireWire input module
3 *****************************************************************************
4 * Copyright (C) 2006-2009 VideoLAN
6 * Authors: Xant Majere <xant@xant.net>
7 * Rob Shortt <rob@tvcentric.com> - libdc1394 V2 API updates
8 * Frederic Benoist <fridorik@gmail.com> - updates from Rob's work
10 *****************************************************************************
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
28 * Preamble
29 *****************************************************************************/
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_demux.h>
39 #include <dc1394/dc1394.h>
41 #define MAX_IEEE1394_HOSTS 32
42 #define MAX_CAMERA_NODES 32
44 /*****************************************************************************
45 * Module descriptor
46 *****************************************************************************/
47 static int Open ( vlc_object_t * );
48 static void Close( vlc_object_t * );
50 vlc_module_begin()
51 set_shortname( N_("DC1394") )
52 set_description( N_("IIDC Digital Camera (FireWire) input") )
53 set_capability( "access_demux", 0 )
54 set_callbacks( Open, Close )
55 vlc_module_end()
57 struct demux_sys_t
59 /* camera info */
60 dc1394_t *p_dccontext;
61 uint32_t num_cameras;
62 dc1394camera_t *camera;
63 int selected_camera;
64 uint64_t selected_uid;
65 uint32_t dma_buffers;
66 dc1394featureset_t features;
67 bool reset_bus;
69 /* video info */
70 char *video_device;
71 dc1394video_mode_t video_mode;
72 int width;
73 int height;
74 int frame_size;
75 int frame_rate;
76 unsigned int brightness;
77 unsigned int focus;
78 es_out_id_t *p_es_video;
79 dc1394video_frame_t *frame;
82 /*****************************************************************************
83 * Local prototypes
84 *****************************************************************************/
85 static int Demux( demux_t *p_demux );
86 static int Control( demux_t *, int, va_list );
87 static block_t *GrabVideo( demux_t *p_demux );
88 static int process_options( demux_t *p_demux);
90 /*****************************************************************************
91 * FindCameras
92 *****************************************************************************/
93 static int FindCamera( demux_sys_t *sys, demux_t *p_demux )
95 dc1394camera_list_t *list;
96 int i_ret = VLC_EGENERIC;
98 msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
100 if( dc1394_camera_enumerate (sys->p_dccontext, &list) != DC1394_SUCCESS )
102 msg_Err(p_demux, "Can not ennumerate cameras");
103 goto end;
106 if( list->num == 0 )
108 msg_Err(p_demux, "Can not find cameras");
109 goto end;
112 sys->num_cameras = list->num;
113 msg_Dbg( p_demux, "Found %d dc1394 cameras.", list->num);
115 if( sys->selected_uid )
117 int found = 0;
118 for( unsigned i = 0; i < sys->num_cameras; i++ )
120 if( list->ids[i].guid == sys->selected_uid )
122 sys->camera = dc1394_camera_new(sys->p_dccontext,
123 list->ids[i].guid);
124 found++;
125 break;
128 if( !found )
130 msg_Err( p_demux, "Can't find camera with uid : 0x%"PRIx64".",
131 sys->selected_uid );
132 goto end;
135 else if( sys->selected_camera >= (int)list->num )
137 msg_Err( p_demux, "There are not this many cameras. (%d/%d)",
138 sys->selected_camera, sys->num_cameras );
139 goto end;
141 else if( sys->selected_camera >= 0 )
143 sys->camera = dc1394_camera_new(sys->p_dccontext,
144 list->ids[sys->selected_camera].guid);
146 else
148 sys->camera = dc1394_camera_new(sys->p_dccontext,
149 list->ids[0].guid);
152 i_ret = VLC_SUCCESS;
154 end:
155 dc1394_camera_free_list (list);
156 return i_ret;
159 /*****************************************************************************
160 * Open:
161 *****************************************************************************/
162 static int Open( vlc_object_t *p_this )
164 demux_t *p_demux = (demux_t*)p_this;
165 demux_sys_t *p_sys;
166 es_format_t fmt;
167 dc1394error_t res;
169 /* Set up p_demux */
170 p_demux->pf_demux = Demux;
171 p_demux->pf_control = Control;
173 p_demux->p_sys = p_sys = vlc_obj_calloc( p_this, 1, sizeof( demux_sys_t ) );
174 if( !p_sys )
175 return VLC_ENOMEM;
177 memset( &fmt, 0, sizeof( es_format_t ) );
179 /* DEFAULTS */
180 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
181 p_sys->width = 640;
182 p_sys->height = 480;
183 p_sys->frame_rate = DC1394_FRAMERATE_15;
184 p_sys->brightness = 200;
185 p_sys->focus = 0;
186 p_sys->p_dccontext = NULL;
187 p_sys->camera = NULL;
188 p_sys->selected_camera = -1;
189 p_sys->dma_buffers = 1;
190 p_sys->reset_bus = 0;
192 /* PROCESS INPUT OPTIONS */
193 if( process_options(p_demux) != VLC_SUCCESS )
195 msg_Err( p_demux, "Bad MRL, please check the option line "
196 "(MRL was: %s)",
197 p_demux->psz_location );
198 return VLC_EGENERIC;
201 p_sys->p_dccontext = dc1394_new();
202 if( !p_sys->p_dccontext )
204 msg_Err( p_demux, "Failed to initialise libdc1394");
205 return VLC_EGENERIC;
208 if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
210 dc1394_free( p_sys->p_dccontext );
211 return VLC_EGENERIC;
214 if( !p_sys->camera )
216 msg_Err( p_demux, "No camera found !!" );
217 dc1394_free( p_sys->p_dccontext );
218 return VLC_EGENERIC;
221 if( p_sys->reset_bus )
223 if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
225 msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
226 Close( p_this );
227 return VLC_EGENERIC;
229 else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
232 if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
234 msg_Err( p_demux, "Unable to reset camera");
235 Close( p_this );
236 return VLC_EGENERIC;
239 if( dc1394_camera_print_info( p_sys->camera,
240 stderr ) != DC1394_SUCCESS )
242 msg_Err( p_demux, "Unable to print camera info");
243 Close( p_this );
244 return VLC_EGENERIC;
247 if( dc1394_feature_get_all( p_sys->camera,
248 &p_sys->features ) != DC1394_SUCCESS )
250 msg_Err( p_demux, "Unable to get feature set");
251 Close( p_this );
252 return VLC_EGENERIC;
254 // TODO: only print features if verbosity increased
255 dc1394_feature_print_all(&p_sys->features, stderr);
257 #if 0 //"Note that you need to execute this function only if you use exotic video1394 device names. /dev/video1394, /dev/video1394/* and /dev/video1394-* are automatically recognized." http://damien.douxchamps.net/ieee1394/libdc1394/v2.x/api/capture/
258 if( p_sys->video_device )
260 if( dc1394_capture_set_device_filename( p_sys->camera,
261 p_sys->video_device ) != DC1394_SUCCESS )
263 msg_Err( p_demux, "Unable to set video device");
264 Close( p_this );
265 return VLC_EGENERIC;
268 #endif
270 if( p_sys->focus )
272 if( dc1394_feature_set_value( p_sys->camera,
273 DC1394_FEATURE_FOCUS,
274 p_sys->focus ) != DC1394_SUCCESS )
276 msg_Err( p_demux, "Unable to set initial focus to %u",
277 p_sys->focus );
279 else
280 msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
283 if( dc1394_feature_set_value( p_sys->camera,
284 DC1394_FEATURE_FOCUS,
285 p_sys->brightness ) != DC1394_SUCCESS )
287 msg_Err( p_demux, "Unable to set initial brightness to %u",
288 p_sys->brightness );
290 else
291 msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
293 if( dc1394_video_set_framerate( p_sys->camera,
294 p_sys->frame_rate ) != DC1394_SUCCESS )
296 msg_Err( p_demux, "Unable to set framerate");
297 Close( p_this );
298 return VLC_EGENERIC;
301 if( dc1394_video_set_mode( p_sys->camera,
302 p_sys->video_mode ) != DC1394_SUCCESS )
304 msg_Err( p_demux, "Unable to set video mode");
305 Close( p_this );
306 return VLC_EGENERIC;
309 if( dc1394_video_set_iso_speed( p_sys->camera,
310 DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
312 msg_Err( p_demux, "Unable to set iso speed");
313 Close( p_this );
314 return VLC_EGENERIC;
317 /* and setup capture */
318 res = dc1394_capture_setup( p_sys->camera,
319 p_sys->dma_buffers,
320 DC1394_CAPTURE_FLAGS_DEFAULT);
321 if( res != DC1394_SUCCESS )
323 if( res == DC1394_NO_BANDWIDTH )
325 msg_Err( p_demux ,"No bandwidth: try adding the "
326 "\"resetbus\" option" );
328 else
330 msg_Err( p_demux ,"Unable to setup capture" );
332 Close( p_this );
333 return VLC_EGENERIC;
336 /* TODO - UYV444 chroma converter is missing, when it will be available
337 * fourcc will become variable (and not just a fixed value for UYVY)
339 es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
341 fmt.video.i_width = p_sys->width;
342 fmt.video.i_height = p_sys->height;
344 msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
345 (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
347 p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
349 /* have the camera start sending us data */
350 if( dc1394_video_set_transmission( p_sys->camera,
351 DC1394_ON ) != DC1394_SUCCESS )
353 msg_Err( p_demux, "Unable to start camera iso transmission" );
354 dc1394_capture_stop( p_sys->camera );
355 Close( p_this );
356 return VLC_EGENERIC;
358 msg_Dbg( p_demux, "Set iso transmission" );
359 // TODO: reread camera
360 return VLC_SUCCESS;
363 /*****************************************************************************
364 * Close:
365 *****************************************************************************/
366 static void Close( vlc_object_t *p_this )
368 demux_t *p_demux = (demux_t*)p_this;
369 demux_sys_t *p_sys = p_demux->p_sys;
371 /* Stop data transmission */
372 if( dc1394_video_set_transmission( p_sys->camera,
373 DC1394_OFF ) != DC1394_SUCCESS )
374 msg_Err( p_demux, "Unable to stop camera iso transmission" );
376 /* Close camera */
377 dc1394_capture_stop( p_sys->camera );
379 dc1394_camera_free(p_sys->camera);
380 dc1394_free(p_sys->p_dccontext);
382 free( p_sys->video_device );
385 #if 0
386 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
388 char u,v,y;
389 u_char *sc;
390 u_char *dc;
392 sc = (u_char *)src + (spos*2);
393 if( spos % 2 )
395 v = sc[0];
396 y = sc[1];
397 u = *(sc -2);
399 else
401 u = sc[0];
402 y = sc[1];
403 v = sc[2];
405 dc = (u_char *)dst+(dpos*2);
406 if( dpos % 2 )
408 dc[0] = v;
409 dc[1] = y;
411 else
413 dc[0] = u;
414 dc[1] = y;
417 #endif
419 /*****************************************************************************
420 * Demux:
421 *****************************************************************************/
422 static block_t *GrabVideo( demux_t *p_demux )
424 demux_sys_t *p_sys = p_demux->p_sys;
425 block_t *p_block = NULL;
427 if( dc1394_capture_dequeue( p_sys->camera,
428 DC1394_CAPTURE_POLICY_WAIT,
429 &p_sys->frame ) != DC1394_SUCCESS )
431 msg_Err( p_demux, "Unable to capture a frame" );
432 return NULL;
435 p_block = block_Alloc( p_sys->frame->size[0] * p_sys->frame->size[1] * 2 );
436 if( !p_block )
438 msg_Err( p_demux, "Can not get block" );
439 return NULL;
442 if( !p_sys->frame->image )
444 msg_Err (p_demux, "Capture buffer empty");
445 block_Release( p_block );
446 return NULL;
449 memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
450 p_sys->width * p_sys->height * 2 );
452 p_block->i_pts = p_block->i_dts = mdate();
453 dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
454 return p_block;
457 static int Demux( demux_t *p_demux )
459 demux_sys_t *p_sys = p_demux->p_sys;
460 block_t *p_blockv = NULL;
462 /* Try grabbing video frame */
463 p_blockv = GrabVideo( p_demux );
465 if( !p_blockv )
467 /* Sleep so we do not consume all the cpu, 10ms seems
468 * like a good value (100fps)
470 msleep( 10000 );
471 return 1;
474 if( p_blockv )
476 es_out_SetPCR( p_demux->out, p_blockv->i_pts );
477 es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
479 return 1;
482 /*****************************************************************************
483 * Control:
484 *****************************************************************************/
485 static int Control( demux_t *p_demux, int i_query, va_list args )
487 VLC_UNUSED( p_demux );
488 switch( i_query )
490 /* Special for access_demux */
491 case DEMUX_CAN_PAUSE:
492 case DEMUX_CAN_SEEK:
493 case DEMUX_CAN_CONTROL_PACE:
494 *va_arg( args, bool * ) = false;
495 return VLC_SUCCESS;
497 case DEMUX_GET_PTS_DELAY:
498 *va_arg( args, int64_t * ) = (int64_t)DEFAULT_PTS_DELAY;
499 return VLC_SUCCESS;
501 case DEMUX_GET_TIME:
502 *va_arg( args, int64_t * ) = mdate();
503 return VLC_SUCCESS;
505 /* TODO implement others */
506 default:
507 return VLC_EGENERIC;
509 return VLC_EGENERIC;
512 static int process_options( demux_t *p_demux )
514 demux_sys_t *p_sys = p_demux->p_sys;
515 char *psz_dup;
516 char *psz_parser;
517 char *token = NULL;
518 char *state = NULL;
519 const char *in_size = NULL;
520 const char *in_fmt = NULL;
521 float rate_f;
523 psz_dup = strdup( p_demux->psz_location );
524 psz_parser = psz_dup;
525 for( token = strtok_r( psz_parser,":",&state); token;
526 token = strtok_r( NULL, ":", &state ) )
528 if( strncmp( token, "size=", strlen("size=") ) == 0 )
530 token += strlen("size=");
531 if( strncmp( token, "160x120", 7 ) == 0 )
533 /* TODO - UYV444 chroma converter is needed ...
534 * video size of 160x120 is temporarily disabled
536 msg_Err( p_demux,
537 "video size of 160x120 is actually disabled for lack of"
538 "chroma support. It will be released ASAP, until then try "
539 "an higher size (320x240 and 640x480 are fully supported)" );
540 free(psz_dup);
541 return VLC_EGENERIC;
542 #if 0
543 in_size = "160x120";
544 p_sys->width = 160;
545 p_sys->height = 120;
546 #endif
548 else if( strncmp( token, "320x240", 7 ) == 0 )
550 in_size = "320x240";
551 p_sys->width = 320;
552 p_sys->height = 240;
554 else if( strncmp( token, "640x480", 7 ) == 0 )
556 in_size = "640x480";
557 p_sys->width = 640;
558 p_sys->height = 480;
560 else
562 msg_Err( p_demux,
563 "This program currently suppots frame sizes of"
564 " 160x120, 320x240, and 640x480. "
565 "Please specify one of them. You have specified %s.",
566 token );
567 free(psz_dup);
568 return VLC_EGENERIC;
570 msg_Dbg( p_demux, "Requested video size : %s",token );
572 if( strncmp( token, "format=", strlen("format=") ) == 0 )
574 token += strlen("format=");
575 if( strncmp( token, "YUV411", 6 ) == 0 )
577 in_fmt = "YUV411";
579 else if( strncmp( token, "YUV422", 6 ) == 0 )
581 in_fmt = "YUV422";
583 else if( strncmp( token, "YUV444", 6 ) == 0 )
585 in_fmt = "YUV444";
587 else if( strncmp( token, "RGB8", 4 ) == 0 )
589 in_fmt = "RGB8";
591 else if( strncmp( token, "MONO8", 5 ) == 0 )
593 in_fmt = "MONO8";
595 else if( strncmp( token, "MONO16", 6 ) == 0 )
597 in_fmt = "MONO16";
599 else
601 msg_Err( p_demux, "Invalid format %s.", token );
602 free(psz_dup);
603 return VLC_EGENERIC;
605 msg_Dbg( p_demux, "Requested video format : %s", token );
607 else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
609 token += strlen("fps=");
610 sscanf( token, "%g", &rate_f );
611 if( rate_f == 1.875 )
612 p_sys->frame_rate = DC1394_FRAMERATE_1_875;
613 else if( rate_f == 3.75 )
614 p_sys->frame_rate = DC1394_FRAMERATE_3_75;
615 else if( rate_f == 7.5 )
616 p_sys->frame_rate = DC1394_FRAMERATE_7_5;
617 else if( rate_f == 15 )
618 p_sys->frame_rate = DC1394_FRAMERATE_15;
619 else if( rate_f == 30 )
620 p_sys->frame_rate = DC1394_FRAMERATE_30;
621 else if( rate_f == 60 )
622 p_sys->frame_rate = DC1394_FRAMERATE_60;
623 else
625 msg_Err( p_demux ,
626 "This program supports framerates of"
627 " 1.875, 3.75, 7.5, 15, 30, 60. "
628 "Please specify one of them. You have specified %s.",
629 token);
630 free(psz_dup);
631 return VLC_EGENERIC;
633 msg_Dbg( p_demux, "Requested frame rate : %s",token );
635 else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
637 token += strlen("resetbus");
638 p_sys->reset_bus = 1;
640 else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
642 int nr = 0;
643 token += strlen("brightness=");
644 nr = sscanf( token, "%u", &p_sys->brightness);
645 if( nr != 1 )
647 msg_Err( p_demux, "Bad brightness value '%s', "
648 "must be an unsigned integer.",
649 token );
650 free(psz_dup);
651 return VLC_EGENERIC;
654 else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
656 int nr = 0;
657 int in_buf = 0;
658 token += strlen("buffers=");
659 nr = sscanf( token, "%d", &in_buf);
660 if( nr != 1 || in_buf < 1 )
662 msg_Err( p_demux, "DMA buffers must be 1 or greater." );
663 free(psz_dup);
664 return VLC_EGENERIC;
666 else p_sys->dma_buffers = in_buf;
668 #if 0
669 // NOTE: If controller support is added back, more logic will needed to be added
670 // after the cameras are scanned.
671 else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
673 int nr = 0;
674 token += strlen("controller=");
675 nr = sscanf( token, "%u", &p_sys->controller );
676 if( nr != 1)
678 msg_Err(p_demux, "Bad controller value '%s', "
679 "must be an unsigned integer.",
680 token );
681 return VLC_EGENERIC;
684 #endif
685 else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
687 int nr = 0;
688 token += strlen("camera=");
689 nr = sscanf(token,"%u",&p_sys->selected_camera);
690 if( nr != 1)
692 msg_Err( p_demux, "Bad camera number '%s', "
693 "must be an unsigned integer.",
694 token );
695 free(psz_dup);
696 return VLC_EGENERIC;
699 else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
701 token += strlen("vdev=");
702 p_sys->video_device = strdup(token);
703 msg_Dbg( p_demux, "Using video device '%s'.", token );
705 else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
707 int nr = 0;
708 token += strlen("focus=");
709 nr = sscanf( token, "%u", &p_sys->focus );
710 if( nr != 1 )
712 msg_Err( p_demux, "Bad focus value '%s', "
713 "must be an unsigned integer.",
714 token );
715 free(psz_dup);
716 return VLC_EGENERIC;
719 else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
721 token += strlen("uid=");
722 sscanf( token, "0x%"SCNx64, &p_sys->selected_uid );
726 // The mode is a combination of size and format and not every format
727 // is supported by every size.
728 if( in_size)
730 if( strcmp( in_size, "160x120") == 0)
732 if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
733 msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
734 p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
736 else if( strcmp( in_size, "320x240") == 0)
738 if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
739 msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
740 p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
743 else
744 { // 640x480 default
745 if( in_fmt )
747 if( strcmp( in_fmt, "RGB8") == 0)
748 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
749 else if( strcmp( in_fmt, "MONO8") == 0)
750 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
751 else if( strcmp( in_fmt, "MONO16") == 0)
752 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
753 else if( strcmp( in_fmt, "YUV411") == 0)
754 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
755 else // YUV422 default
756 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
758 else // YUV422 default
759 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
762 free( psz_dup );
763 return VLC_SUCCESS;