d3d9: fix compilation after opengl rework
[vlc.git] / modules / access / dc1394.c
blobd994d37f2ddefa1c7e89f2585263322483a91955
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", 0 )
54 set_callbacks( Open, Close )
55 vlc_module_end()
57 typedef struct
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;
80 } demux_sys_t;
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 if (p_demux->out == NULL)
170 return VLC_EGENERIC;
172 /* Set up p_demux */
173 p_demux->pf_demux = Demux;
174 p_demux->pf_control = Control;
176 p_demux->p_sys = p_sys = vlc_obj_calloc( p_this, 1, sizeof( demux_sys_t ) );
177 if( !p_sys )
178 return VLC_ENOMEM;
180 memset( &fmt, 0, sizeof( es_format_t ) );
182 /* DEFAULTS */
183 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
184 p_sys->width = 640;
185 p_sys->height = 480;
186 p_sys->frame_rate = DC1394_FRAMERATE_15;
187 p_sys->brightness = 200;
188 p_sys->focus = 0;
189 p_sys->p_dccontext = NULL;
190 p_sys->camera = NULL;
191 p_sys->selected_camera = -1;
192 p_sys->dma_buffers = 1;
193 p_sys->reset_bus = 0;
195 /* PROCESS INPUT OPTIONS */
196 if( process_options(p_demux) != VLC_SUCCESS )
198 msg_Err( p_demux, "Bad MRL, please check the option line "
199 "(MRL was: %s)",
200 p_demux->psz_location );
201 return VLC_EGENERIC;
204 p_sys->p_dccontext = dc1394_new();
205 if( !p_sys->p_dccontext )
207 msg_Err( p_demux, "Failed to initialise libdc1394");
208 return VLC_EGENERIC;
211 if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
213 dc1394_free( p_sys->p_dccontext );
214 return VLC_EGENERIC;
217 if( !p_sys->camera )
219 msg_Err( p_demux, "No camera found !!" );
220 dc1394_free( p_sys->p_dccontext );
221 return VLC_EGENERIC;
224 if( p_sys->reset_bus )
226 if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
228 msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
229 Close( p_this );
230 return VLC_EGENERIC;
232 else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
235 if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
237 msg_Err( p_demux, "Unable to reset camera");
238 Close( p_this );
239 return VLC_EGENERIC;
242 if( dc1394_camera_print_info( p_sys->camera,
243 stderr ) != DC1394_SUCCESS )
245 msg_Err( p_demux, "Unable to print camera info");
246 Close( p_this );
247 return VLC_EGENERIC;
250 if( dc1394_feature_get_all( p_sys->camera,
251 &p_sys->features ) != DC1394_SUCCESS )
253 msg_Err( p_demux, "Unable to get feature set");
254 Close( p_this );
255 return VLC_EGENERIC;
257 // TODO: only print features if verbosity increased
258 dc1394_feature_print_all(&p_sys->features, stderr);
260 #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/
261 if( p_sys->video_device )
263 if( dc1394_capture_set_device_filename( p_sys->camera,
264 p_sys->video_device ) != DC1394_SUCCESS )
266 msg_Err( p_demux, "Unable to set video device");
267 Close( p_this );
268 return VLC_EGENERIC;
271 #endif
273 if( p_sys->focus )
275 if( dc1394_feature_set_value( p_sys->camera,
276 DC1394_FEATURE_FOCUS,
277 p_sys->focus ) != DC1394_SUCCESS )
279 msg_Err( p_demux, "Unable to set initial focus to %u",
280 p_sys->focus );
282 else
283 msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
286 if( dc1394_feature_set_value( p_sys->camera,
287 DC1394_FEATURE_FOCUS,
288 p_sys->brightness ) != DC1394_SUCCESS )
290 msg_Err( p_demux, "Unable to set initial brightness to %u",
291 p_sys->brightness );
293 else
294 msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
296 if( dc1394_video_set_framerate( p_sys->camera,
297 p_sys->frame_rate ) != DC1394_SUCCESS )
299 msg_Err( p_demux, "Unable to set framerate");
300 Close( p_this );
301 return VLC_EGENERIC;
304 if( dc1394_video_set_mode( p_sys->camera,
305 p_sys->video_mode ) != DC1394_SUCCESS )
307 msg_Err( p_demux, "Unable to set video mode");
308 Close( p_this );
309 return VLC_EGENERIC;
312 if( dc1394_video_set_iso_speed( p_sys->camera,
313 DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
315 msg_Err( p_demux, "Unable to set iso speed");
316 Close( p_this );
317 return VLC_EGENERIC;
320 /* and setup capture */
321 res = dc1394_capture_setup( p_sys->camera,
322 p_sys->dma_buffers,
323 DC1394_CAPTURE_FLAGS_DEFAULT);
324 if( res != DC1394_SUCCESS )
326 if( res == DC1394_NO_BANDWIDTH )
328 msg_Err( p_demux ,"No bandwidth: try adding the "
329 "\"resetbus\" option" );
331 else
333 msg_Err( p_demux ,"Unable to setup capture" );
335 Close( p_this );
336 return VLC_EGENERIC;
339 /* TODO - UYV444 chroma converter is missing, when it will be available
340 * fourcc will become variable (and not just a fixed value for UYVY)
342 es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
344 fmt.video.i_width = p_sys->width;
345 fmt.video.i_height = p_sys->height;
347 msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
348 (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
350 p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
352 /* have the camera start sending us data */
353 if( dc1394_video_set_transmission( p_sys->camera,
354 DC1394_ON ) != DC1394_SUCCESS )
356 msg_Err( p_demux, "Unable to start camera iso transmission" );
357 dc1394_capture_stop( p_sys->camera );
358 Close( p_this );
359 return VLC_EGENERIC;
361 msg_Dbg( p_demux, "Set iso transmission" );
362 // TODO: reread camera
363 return VLC_SUCCESS;
366 /*****************************************************************************
367 * Close:
368 *****************************************************************************/
369 static void Close( vlc_object_t *p_this )
371 demux_t *p_demux = (demux_t*)p_this;
372 demux_sys_t *p_sys = p_demux->p_sys;
374 /* Stop data transmission */
375 if( dc1394_video_set_transmission( p_sys->camera,
376 DC1394_OFF ) != DC1394_SUCCESS )
377 msg_Err( p_demux, "Unable to stop camera iso transmission" );
379 /* Close camera */
380 dc1394_capture_stop( p_sys->camera );
382 dc1394_camera_free(p_sys->camera);
383 dc1394_free(p_sys->p_dccontext);
385 free( p_sys->video_device );
388 #if 0
389 static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
391 char u,v,y;
392 u_char *sc;
393 u_char *dc;
395 sc = (u_char *)src + (spos*2);
396 if( spos % 2 )
398 v = sc[0];
399 y = sc[1];
400 u = *(sc -2);
402 else
404 u = sc[0];
405 y = sc[1];
406 v = sc[2];
408 dc = (u_char *)dst+(dpos*2);
409 if( dpos % 2 )
411 dc[0] = v;
412 dc[1] = y;
414 else
416 dc[0] = u;
417 dc[1] = y;
420 #endif
422 /*****************************************************************************
423 * Demux:
424 *****************************************************************************/
425 static block_t *GrabVideo( demux_t *p_demux )
427 demux_sys_t *p_sys = p_demux->p_sys;
428 block_t *p_block = NULL;
430 if( dc1394_capture_dequeue( p_sys->camera,
431 DC1394_CAPTURE_POLICY_WAIT,
432 &p_sys->frame ) != DC1394_SUCCESS )
434 msg_Err( p_demux, "Unable to capture a frame" );
435 return NULL;
438 p_block = block_Alloc( p_sys->frame->size[0] * p_sys->frame->size[1] * 2 );
439 if( !p_block )
441 msg_Err( p_demux, "Can not get block" );
442 return NULL;
445 if( !p_sys->frame->image )
447 msg_Err (p_demux, "Capture buffer empty");
448 block_Release( p_block );
449 return NULL;
452 memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
453 p_sys->width * p_sys->height * 2 );
455 p_block->i_pts = p_block->i_dts = vlc_tick_now();
456 dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
457 return p_block;
460 static int Demux( demux_t *p_demux )
462 demux_sys_t *p_sys = p_demux->p_sys;
463 block_t *p_blockv = NULL;
465 /* Try grabbing video frame */
466 p_blockv = GrabVideo( p_demux );
468 if( !p_blockv )
470 /* Sleep so we do not consume all the cpu, 10ms seems
471 * like a good value (100fps)
473 vlc_tick_sleep( VLC_HARD_MIN_SLEEP );
474 return 1;
477 if( p_blockv )
479 es_out_SetPCR( p_demux->out, p_blockv->i_pts );
480 es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
482 return 1;
485 /*****************************************************************************
486 * Control:
487 *****************************************************************************/
488 static int Control( demux_t *p_demux, int i_query, va_list args )
490 VLC_UNUSED( p_demux );
491 switch( i_query )
493 /* Special for access_demux */
494 case DEMUX_CAN_PAUSE:
495 case DEMUX_CAN_SEEK:
496 case DEMUX_CAN_CONTROL_PACE:
497 *va_arg( args, bool * ) = false;
498 return VLC_SUCCESS;
500 case DEMUX_GET_PTS_DELAY:
501 *va_arg( args, vlc_tick_t * ) = DEFAULT_PTS_DELAY;
502 return VLC_SUCCESS;
504 case DEMUX_GET_TIME:
505 *va_arg( args, vlc_tick_t * ) = vlc_tick_now();
506 return VLC_SUCCESS;
508 /* TODO implement others */
509 default:
510 return VLC_EGENERIC;
512 return VLC_EGENERIC;
515 static int process_options( demux_t *p_demux )
517 demux_sys_t *p_sys = p_demux->p_sys;
518 char *psz_dup;
519 char *psz_parser;
520 char *token = NULL;
521 char *state = NULL;
522 const char *in_size = NULL;
523 const char *in_fmt = NULL;
524 float rate_f;
526 psz_dup = strdup( p_demux->psz_location );
527 psz_parser = psz_dup;
528 for( token = strtok_r( psz_parser,":",&state); token;
529 token = strtok_r( NULL, ":", &state ) )
531 if( strncmp( token, "size=", strlen("size=") ) == 0 )
533 token += strlen("size=");
534 if( strncmp( token, "160x120", 7 ) == 0 )
536 /* TODO - UYV444 chroma converter is needed ...
537 * video size of 160x120 is temporarily disabled
539 msg_Err( p_demux,
540 "video size of 160x120 is actually disabled for lack of"
541 "chroma support. It will be released ASAP, until then try "
542 "an higher size (320x240 and 640x480 are fully supported)" );
543 free(psz_dup);
544 return VLC_EGENERIC;
545 #if 0
546 in_size = "160x120";
547 p_sys->width = 160;
548 p_sys->height = 120;
549 #endif
551 else if( strncmp( token, "320x240", 7 ) == 0 )
553 in_size = "320x240";
554 p_sys->width = 320;
555 p_sys->height = 240;
557 else if( strncmp( token, "640x480", 7 ) == 0 )
559 in_size = "640x480";
560 p_sys->width = 640;
561 p_sys->height = 480;
563 else
565 msg_Err( p_demux,
566 "This program currently suppots frame sizes of"
567 " 160x120, 320x240, and 640x480. "
568 "Please specify one of them. You have specified %s.",
569 token );
570 free(psz_dup);
571 return VLC_EGENERIC;
573 msg_Dbg( p_demux, "Requested video size : %s",token );
575 if( strncmp( token, "format=", strlen("format=") ) == 0 )
577 token += strlen("format=");
578 if( strncmp( token, "YUV411", 6 ) == 0 )
580 in_fmt = "YUV411";
582 else if( strncmp( token, "YUV422", 6 ) == 0 )
584 in_fmt = "YUV422";
586 else if( strncmp( token, "YUV444", 6 ) == 0 )
588 in_fmt = "YUV444";
590 else if( strncmp( token, "RGB8", 4 ) == 0 )
592 in_fmt = "RGB8";
594 else if( strncmp( token, "MONO8", 5 ) == 0 )
596 in_fmt = "MONO8";
598 else if( strncmp( token, "MONO16", 6 ) == 0 )
600 in_fmt = "MONO16";
602 else
604 msg_Err( p_demux, "Invalid format %s.", token );
605 free(psz_dup);
606 return VLC_EGENERIC;
608 msg_Dbg( p_demux, "Requested video format : %s", token );
610 else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
612 token += strlen("fps=");
613 sscanf( token, "%g", &rate_f );
614 if( rate_f == 1.875 )
615 p_sys->frame_rate = DC1394_FRAMERATE_1_875;
616 else if( rate_f == 3.75 )
617 p_sys->frame_rate = DC1394_FRAMERATE_3_75;
618 else if( rate_f == 7.5 )
619 p_sys->frame_rate = DC1394_FRAMERATE_7_5;
620 else if( rate_f == 15 )
621 p_sys->frame_rate = DC1394_FRAMERATE_15;
622 else if( rate_f == 30 )
623 p_sys->frame_rate = DC1394_FRAMERATE_30;
624 else if( rate_f == 60 )
625 p_sys->frame_rate = DC1394_FRAMERATE_60;
626 else
628 msg_Err( p_demux ,
629 "This program supports framerates of"
630 " 1.875, 3.75, 7.5, 15, 30, 60. "
631 "Please specify one of them. You have specified %s.",
632 token);
633 free(psz_dup);
634 return VLC_EGENERIC;
636 msg_Dbg( p_demux, "Requested frame rate : %s",token );
638 else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
640 token += strlen("resetbus");
641 p_sys->reset_bus = 1;
643 else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
645 int nr = 0;
646 token += strlen("brightness=");
647 nr = sscanf( token, "%u", &p_sys->brightness);
648 if( nr != 1 )
650 msg_Err( p_demux, "Bad brightness value '%s', "
651 "must be an unsigned integer.",
652 token );
653 free(psz_dup);
654 return VLC_EGENERIC;
657 else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
659 int nr = 0;
660 int in_buf = 0;
661 token += strlen("buffers=");
662 nr = sscanf( token, "%d", &in_buf);
663 if( nr != 1 || in_buf < 1 )
665 msg_Err( p_demux, "DMA buffers must be 1 or greater." );
666 free(psz_dup);
667 return VLC_EGENERIC;
669 else p_sys->dma_buffers = in_buf;
671 #if 0
672 // NOTE: If controller support is added back, more logic will needed to be added
673 // after the cameras are scanned.
674 else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
676 int nr = 0;
677 token += strlen("controller=");
678 nr = sscanf( token, "%u", &p_sys->controller );
679 if( nr != 1)
681 msg_Err(p_demux, "Bad controller value '%s', "
682 "must be an unsigned integer.",
683 token );
684 return VLC_EGENERIC;
687 #endif
688 else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
690 int nr = 0;
691 token += strlen("camera=");
692 nr = sscanf(token,"%u",&p_sys->selected_camera);
693 if( nr != 1)
695 msg_Err( p_demux, "Bad camera number '%s', "
696 "must be an unsigned integer.",
697 token );
698 free(psz_dup);
699 return VLC_EGENERIC;
702 else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
704 token += strlen("vdev=");
705 p_sys->video_device = strdup(token);
706 msg_Dbg( p_demux, "Using video device '%s'.", token );
708 else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
710 int nr = 0;
711 token += strlen("focus=");
712 nr = sscanf( token, "%u", &p_sys->focus );
713 if( nr != 1 )
715 msg_Err( p_demux, "Bad focus value '%s', "
716 "must be an unsigned integer.",
717 token );
718 free(psz_dup);
719 return VLC_EGENERIC;
722 else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
724 token += strlen("uid=");
725 sscanf( token, "0x%"SCNx64, &p_sys->selected_uid );
729 // The mode is a combination of size and format and not every format
730 // is supported by every size.
731 if( in_size)
733 if( strcmp( in_size, "160x120") == 0)
735 if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
736 msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
737 p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
739 else if( strcmp( in_size, "320x240") == 0)
741 if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
742 msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
743 p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
746 else
747 { // 640x480 default
748 if( in_fmt )
750 if( strcmp( in_fmt, "RGB8") == 0)
751 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
752 else if( strcmp( in_fmt, "MONO8") == 0)
753 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
754 else if( strcmp( in_fmt, "MONO16") == 0)
755 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
756 else if( strcmp( in_fmt, "YUV411") == 0)
757 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
758 else // YUV422 default
759 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
761 else // YUV422 default
762 p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
765 free( psz_dup );
766 return VLC_SUCCESS;