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 /*****************************************************************************
29 *****************************************************************************/
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 /*****************************************************************************
46 *****************************************************************************/
47 static int Open ( vlc_object_t * );
48 static void Close( vlc_object_t * );
51 set_shortname( N_("DC1394") )
52 set_description( N_("IIDC Digital Camera (FireWire) input") )
53 set_capability( "access_demux", 10 )
54 set_callbacks( Open, Close )
60 dc1394_t *p_dccontext;
62 dc1394camera_t *camera;
64 uint64_t selected_uid;
66 dc1394featureset_t features;
71 dc1394video_mode_t video_mode;
76 unsigned int brightness;
78 es_out_id_t *p_es_video;
79 dc1394video_frame_t *frame;
82 /*****************************************************************************
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 /*****************************************************************************
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");
108 msg_Err(p_demux, "Can not find cameras");
112 sys->num_cameras = list->num;
113 msg_Dbg( p_demux, "Found %d dc1394 cameras.", list->num);
115 if( sys->selected_uid )
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,
130 msg_Err( p_demux, "Can't find camera with uid : 0x%"PRIx64".",
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 );
141 else if( sys->selected_camera >= 0 )
143 sys->camera = dc1394_camera_new(sys->p_dccontext,
144 list->ids[sys->selected_camera].guid);
148 sys->camera = dc1394_camera_new(sys->p_dccontext,
155 dc1394_camera_free_list (list);
159 /*****************************************************************************
161 *****************************************************************************/
162 static int Open( vlc_object_t *p_this )
164 demux_t *p_demux = (demux_t*)p_this;
169 if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
173 p_demux->pf_demux = Demux;
174 p_demux->pf_control = Control;
175 p_demux->info.i_update = 0;
176 p_demux->info.i_title = 0;
177 p_demux->info.i_seekpoint = 0;
179 p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
183 memset( &fmt, 0, sizeof( es_format_t ) );
186 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
189 p_sys->frame_rate = DC1394_FRAMERATE_15;
190 p_sys->brightness = 200;
192 p_sys->p_dccontext = NULL;
193 p_sys->camera = NULL;
194 p_sys->selected_camera = -1;
195 p_sys->dma_buffers = 1;
196 p_sys->reset_bus = 0;
198 /* PROCESS INPUT OPTIONS */
199 if( process_options(p_demux) != VLC_SUCCESS )
201 msg_Err( p_demux, "Bad MRL, please check the option line "
203 p_demux->psz_location );
208 p_sys->p_dccontext = dc1394_new();
209 if( !p_sys->p_dccontext )
211 msg_Err( p_demux, "Failed to initialise libdc1394");
216 if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
218 dc1394_free( p_sys->p_dccontext );
225 msg_Err( p_demux, "No camera found !!" );
226 dc1394_free( p_sys->p_dccontext );
231 if( p_sys->reset_bus )
233 if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
235 msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
239 else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
242 if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
244 msg_Err( p_demux, "Unable to reset camera");
249 if( dc1394_camera_print_info( p_sys->camera,
250 stderr ) != DC1394_SUCCESS )
252 msg_Err( p_demux, "Unable to print camera info");
257 if( dc1394_feature_get_all( p_sys->camera,
258 &p_sys->features ) != DC1394_SUCCESS )
260 msg_Err( p_demux, "Unable to get feature set");
264 // TODO: only print features if verbosity increased
265 dc1394_feature_print_all(&p_sys->features, stderr);
267 #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/
268 if( p_sys->video_device )
270 if( dc1394_capture_set_device_filename( p_sys->camera,
271 p_sys->video_device ) != DC1394_SUCCESS )
273 msg_Err( p_demux, "Unable to set video device");
282 if( dc1394_feature_set_value( p_sys->camera,
283 DC1394_FEATURE_FOCUS,
284 p_sys->focus ) != DC1394_SUCCESS )
286 msg_Err( p_demux, "Unable to set initial focus to %u",
290 msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
293 if( dc1394_feature_set_value( p_sys->camera,
294 DC1394_FEATURE_FOCUS,
295 p_sys->brightness ) != DC1394_SUCCESS )
297 msg_Err( p_demux, "Unable to set initial brightness to %u",
301 msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
303 if( dc1394_video_set_framerate( p_sys->camera,
304 p_sys->frame_rate ) != DC1394_SUCCESS )
306 msg_Err( p_demux, "Unable to set framerate");
311 if( dc1394_video_set_mode( p_sys->camera,
312 p_sys->video_mode ) != DC1394_SUCCESS )
314 msg_Err( p_demux, "Unable to set video mode");
319 if( dc1394_video_set_iso_speed( p_sys->camera,
320 DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
322 msg_Err( p_demux, "Unable to set iso speed");
327 /* and setup capture */
328 res = dc1394_capture_setup( p_sys->camera,
330 DC1394_CAPTURE_FLAGS_DEFAULT);
331 if( res != DC1394_SUCCESS )
333 if( res == DC1394_NO_BANDWIDTH )
335 msg_Err( p_demux ,"No bandwidth: try adding the "
336 "\"resetbus\" option" );
340 msg_Err( p_demux ,"Unable to setup capture" );
346 /* TODO - UYV444 chroma converter is missing, when it will be available
347 * fourcc will become variable (and not just a fixed value for UYVY)
349 es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
351 fmt.video.i_width = p_sys->width;
352 fmt.video.i_height = p_sys->height;
354 msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
355 (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
357 p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
359 /* have the camera start sending us data */
360 if( dc1394_video_set_transmission( p_sys->camera,
361 DC1394_ON ) != DC1394_SUCCESS )
363 msg_Err( p_demux, "Unable to start camera iso transmission" );
364 dc1394_capture_stop( p_sys->camera );
368 msg_Dbg( p_demux, "Set iso transmission" );
369 // TODO: reread camera
373 /*****************************************************************************
375 *****************************************************************************/
376 static void Close( vlc_object_t *p_this )
378 demux_t *p_demux = (demux_t*)p_this;
379 demux_sys_t *p_sys = p_demux->p_sys;
381 /* Stop data transmission */
382 if( dc1394_video_set_transmission( p_sys->camera,
383 DC1394_OFF ) != DC1394_SUCCESS )
384 msg_Err( p_demux, "Unable to stop camera iso transmission" );
387 dc1394_capture_stop( p_sys->camera );
389 dc1394_camera_free(p_sys->camera);
390 dc1394_free(p_sys->p_dccontext);
392 free( p_sys->video_device );
397 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
403 sc = (u_char *)src + (spos*2);
416 dc = (u_char *)dst+(dpos*2);
430 /*****************************************************************************
432 *****************************************************************************/
433 static block_t *GrabVideo( demux_t *p_demux )
435 demux_sys_t *p_sys = p_demux->p_sys;
436 block_t *p_block = NULL;
438 if( dc1394_capture_dequeue( p_sys->camera,
439 DC1394_CAPTURE_POLICY_WAIT,
440 &p_sys->frame ) != DC1394_SUCCESS )
442 msg_Err( p_demux, "Unable to capture a frame" );
446 p_block = block_New( p_demux, p_sys->frame->size[0] *
447 p_sys->frame->size[1] * 2 );
450 msg_Err( p_demux, "Can not get block" );
454 if( !p_sys->frame->image )
456 msg_Err (p_demux, "Capture buffer empty");
457 block_Release( p_block );
461 memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
462 p_sys->width * p_sys->height * 2 );
464 p_block->i_pts = p_block->i_dts = mdate();
465 dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
469 static int Demux( demux_t *p_demux )
471 demux_sys_t *p_sys = p_demux->p_sys;
472 block_t *p_blockv = NULL;
474 /* Try grabbing video frame */
475 p_blockv = GrabVideo( p_demux );
479 /* Sleep so we do not consume all the cpu, 10ms seems
480 * like a good value (100fps)
488 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
489 es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
494 /*****************************************************************************
496 *****************************************************************************/
497 static int Control( demux_t *p_demux, int i_query, va_list args )
499 VLC_UNUSED( p_demux );
502 /* Special for access_demux */
503 case DEMUX_CAN_PAUSE:
505 case DEMUX_SET_PAUSE_STATE:
506 case DEMUX_CAN_CONTROL_PACE:
507 *va_arg( args, bool * ) = false;
510 case DEMUX_GET_PTS_DELAY:
511 *va_arg( args, int64_t * ) = (int64_t)DEFAULT_PTS_DELAY;
515 *va_arg( args, int64_t * ) = mdate();
518 /* TODO implement others */
525 static int process_options( demux_t *p_demux )
527 demux_sys_t *p_sys = p_demux->p_sys;
532 const char *in_size = NULL;
533 const char *in_fmt = NULL;
536 psz_dup = strdup( p_demux->psz_location );
537 psz_parser = psz_dup;
538 for( token = strtok_r( psz_parser,":",&state); token;
539 token = strtok_r( NULL, ":", &state ) )
541 if( strncmp( token, "size=", strlen("size=") ) == 0 )
543 token += strlen("size=");
544 if( strncmp( token, "160x120", 7 ) == 0 )
546 /* TODO - UYV444 chroma converter is needed ...
547 * video size of 160x120 is temporarily disabled
550 "video size of 160x120 is actually disabled for lack of"
551 "chroma support. It will relased ASAP, until then try "
552 "an higher size (320x240 and 640x480 are fully supported)" );
561 else if( strncmp( token, "320x240", 7 ) == 0 )
567 else if( strncmp( token, "640x480", 7 ) == 0 )
576 "This program currently suppots frame sizes of"
577 " 160x120, 320x240, and 640x480. "
578 "Please specify one of them. You have specified %s.",
583 msg_Dbg( p_demux, "Requested video size : %s",token );
585 if( strncmp( token, "format=", strlen("format=") ) == 0 )
587 token += strlen("format=");
588 if( strncmp( token, "YUV411", 6 ) == 0 )
592 else if( strncmp( token, "YUV422", 6 ) == 0 )
596 else if( strncmp( token, "YUV444", 6 ) == 0 )
600 else if( strncmp( token, "RGB8", 4 ) == 0 )
604 else if( strncmp( token, "MONO8", 5 ) == 0 )
608 else if( strncmp( token, "MONO16", 6 ) == 0 )
614 msg_Err( p_demux, "Invalid format %s.", token );
618 msg_Dbg( p_demux, "Requested video format : %s", token );
620 else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
622 token += strlen("fps=");
623 sscanf( token, "%g", &rate_f );
624 if( rate_f == 1.875 )
625 p_sys->frame_rate = DC1394_FRAMERATE_1_875;
626 else if( rate_f == 3.75 )
627 p_sys->frame_rate = DC1394_FRAMERATE_3_75;
628 else if( rate_f == 7.5 )
629 p_sys->frame_rate = DC1394_FRAMERATE_7_5;
630 else if( rate_f == 15 )
631 p_sys->frame_rate = DC1394_FRAMERATE_15;
632 else if( rate_f == 30 )
633 p_sys->frame_rate = DC1394_FRAMERATE_30;
634 else if( rate_f == 60 )
635 p_sys->frame_rate = DC1394_FRAMERATE_60;
639 "This program supports framerates of"
640 " 1.875, 3.75, 7.5, 15, 30, 60. "
641 "Please specify one of them. You have specified %s.",
646 msg_Dbg( p_demux, "Requested frame rate : %s",token );
648 else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
650 token += strlen("resetbus");
651 p_sys->reset_bus = 1;
653 else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
656 token += strlen("brightness=");
657 nr = sscanf( token, "%u", &p_sys->brightness);
660 msg_Err( p_demux, "Bad brightness value '%s', "
661 "must be an unsigned integer.",
667 else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
671 token += strlen("buffers=");
672 nr = sscanf( token, "%d", &in_buf);
673 if( nr != 1 || in_buf < 1 )
675 msg_Err( p_demux, "DMA buffers must be 1 or greater." );
679 else p_sys->dma_buffers = in_buf;
682 // NOTE: If controller support is added back, more logic will needed to be added
683 // after the cameras are scanned.
684 else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
687 token += strlen("controller=");
688 nr = sscanf( token, "%u", &p_sys->controller );
691 msg_Err(p_demux, "Bad controller value '%s', "
692 "must be an unsigned integer.",
698 else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
701 token += strlen("camera=");
702 nr = sscanf(token,"%u",&p_sys->selected_camera);
705 msg_Err( p_demux, "Bad camera number '%s', "
706 "must be an unsigned integer.",
712 else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
714 token += strlen("vdev=");
715 p_sys->video_device = strdup(token);
716 msg_Dbg( p_demux, "Using video device '%s'.", token );
718 else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
721 token += strlen("focus=");
722 nr = sscanf( token, "%u", &p_sys->focus );
725 msg_Err( p_demux, "Bad focus value '%s', "
726 "must be an unsigned integer.",
732 else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
734 token += strlen("uid=");
735 sscanf( token, "0x%"SCNx64, &p_sys->selected_uid );
739 // The mode is a combination of size and format and not every format
740 // is supported by every size.
743 if( strcmp( in_size, "160x120") == 0)
745 if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
746 msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
747 p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
749 else if( strcmp( in_size, "320x240") == 0)
751 if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
752 msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
753 p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
760 if( strcmp( in_fmt, "RGB8") == 0)
761 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
762 else if( strcmp( in_fmt, "MONO8") == 0)
763 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
764 else if( strcmp( in_fmt, "MONO16") == 0)
765 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
766 else if( strcmp( in_fmt, "YUV411") == 0)
767 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
768 else // YUV422 default
769 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
771 else // YUV422 default
772 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;