Commit 577ce5a6 authored by Jean-Baptiste Kempf's avatar Jean-Baptiste Kempf

dc1394: update to v2 API

This patch needs more testing, I think.
parent 7c446cb7
...@@ -5,6 +5,7 @@ Access: ...@@ -5,6 +5,7 @@ Access:
* Port of the screen module from Xlib to XCB * Port of the screen module from Xlib to XCB
* Support for the sftp protocol * Support for the sftp protocol
* Support for CDDB servers for Audio-CD on Windows version * Support for CDDB servers for Audio-CD on Windows version
* Port of the dc1394 module from libdc1394 to libdc1394 v2.0
Decoders: Decoders:
* Support for Atrac1 * Support for Atrac1
......
...@@ -2041,7 +2041,7 @@ dnl ...@@ -2041,7 +2041,7 @@ dnl
dnl - special access module for dc1394 input dnl - special access module for dc1394 input
dnl - dv module: digital video module check for libraw1394 dnl - dv module: digital video module check for libraw1394
dnl dnl
PKG_ENABLE_MODULES_VLC([DC1394], [], [libraw1394 >= 2.0.1 libdc1394 >= 1.0.0], [dc1394 access module], [auto]) PKG_ENABLE_MODULES_VLC([DC1394], [], [libraw1394 >= 2.0.1 libdc1394-2 >= 2.1.0], [dc1394 access module], [auto])
PKG_ENABLE_MODULES_VLC([DV], [access_dv], [libraw1394 >= 2.0.1 libavc1394 >= 0.5.3], [DV input module], [auto]) PKG_ENABLE_MODULES_VLC([DV], [access_dv], [libraw1394 >= 2.0.1 libavc1394 >= 0.5.3], [DV input module], [auto])
dnl dnl
......
/***************************************************************************** /*****************************************************************************
* dc1394.c: firewire input module * dc1394.c: firewire input module
***************************************************************************** *****************************************************************************
* Copyright (C) 2006 the VideoLAN team * Copyright (C) 2006-2009 VideoLAN
* *
* Authors: Xant Majere <xant@xant.net> * Authors: Xant Majere <xant@xant.net>
* Rob Shortt <rob@tvcentric.com> - libdc1394 V2 API updates
* Frederic Benoist <fridorik@gmail.com> - updates from Rob's work
* *
***************************************************************************** *****************************************************************************
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
...@@ -35,6 +37,7 @@ ...@@ -35,6 +37,7 @@
#include <vlc_input.h> #include <vlc_input.h>
#include <vlc_demux.h> #include <vlc_demux.h>
#include <vlc_charset.h> #include <vlc_charset.h>
#include <vlc_picture.h>
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> # include <fcntl.h>
...@@ -49,7 +52,7 @@ ...@@ -49,7 +52,7 @@
#include <sys/soundcard.h> #include <sys/soundcard.h>
#include <libraw1394/raw1394.h> #include <libraw1394/raw1394.h>
#include <libdc1394/dc1394_control.h> #include <dc1394/dc1394.h>
#define MAX_IEEE1394_HOSTS 32 #define MAX_IEEE1394_HOSTS 32
#define MAX_CAMERA_NODES 32 #define MAX_CAMERA_NODES 32
...@@ -69,39 +72,31 @@ vlc_module_begin () ...@@ -69,39 +72,31 @@ vlc_module_begin ()
set_callbacks( Open, Close ) set_callbacks( Open, Close )
vlc_module_end () vlc_module_end ()
typedef struct __dc_camera struct demux_sys_t
{ {
int port; /* camera info */
nodeid_t node; dc1394_t *p_dccontext;
u_int64_t uid; uint32_t num_cameras;
} dc_camera; dc1394camera_t *camera;
typedef struct demux_sys_t
{
dc1394_cameracapture camera;
picture_t pic;
int dma_capture;
#define DMA_OFF 0
#define DMA_ON 1
int num_ports;
int num_cameras;
int selected_camera; int selected_camera;
u_int64_t selected_uid; uint64_t selected_uid;
picture_t pic;
dc_camera *camera_nodes; uint32_t dma_buffers;
dc1394_camerainfo camera_info; dc1394featureset_t features;
dc1394_miscinfo misc_info;
raw1394handle_t fd_video;
quadlet_t supported_framerates; quadlet_t supported_framerates;
bool reset_bus;
/* video info */
char *video_device;
dc1394video_mode_t video_mode;
int width; int width;
int height; int height;
int frame_size; int frame_size;
int frame_rate; int frame_rate;
unsigned int brightness; unsigned int brightness;
unsigned int focus; unsigned int focus;
char *dma_device;
es_out_id_t *p_es_video; es_out_id_t *p_es_video;
dc1394video_frame_t *frame;
/* audio stuff */ /* audio stuff */
int i_sample_rate; int i_sample_rate;
...@@ -113,7 +108,7 @@ typedef struct demux_sys_t ...@@ -113,7 +108,7 @@ typedef struct demux_sys_t
#define ROTATION_LEFT 1 #define ROTATION_LEFT 1
#define ROTATION_RIGHT 2 #define ROTATION_RIGHT 2
es_out_id_t *p_es_audio; es_out_id_t *p_es_audio;
} dc1394_sys; };
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -125,82 +120,84 @@ static block_t *GrabAudio( demux_t *p_demux ); ...@@ -125,82 +120,84 @@ static block_t *GrabAudio( demux_t *p_demux );
static int process_options( demux_t *p_demux); static int process_options( demux_t *p_demux);
/***************************************************************************** /*****************************************************************************
* ScanCameras * FindCameras
*****************************************************************************/ *****************************************************************************/
static void ScanCameras( dc1394_sys *sys, demux_t *p_demux ) static int FindCamera( demux_sys_t *sys, demux_t *p_demux )
{ {
struct raw1394_portinfo portinfo[MAX_IEEE1394_HOSTS]; dc1394camera_list_t *list;
raw1394handle_t tempFd;
dc1394_camerainfo info;
dc_camera *node_list = NULL;
nodeid_t *nodes = NULL;
int num_ports = 0;
int num_cameras = 0;
int nodecount;
int i, n;
memset( &portinfo, 0, sizeof(portinfo) );
msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." ); msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
tempFd = raw1394_new_handle(); if( dc1394_camera_enumerate (sys->p_dccontext, &list) != DC1394_SUCCESS )
if( !tempFd ) {
msg_Err(p_demux, "Can not ennumerate cameras");
dc1394_camera_free_list (list);
dc1394_free( sys->p_dccontext );
free( sys );
p_demux->p_sys = NULL;
return VLC_EGENERIC; return VLC_EGENERIC;
raw1394_get_port_info( tempFd, portinfo, MAX_IEEE1394_HOSTS); }
raw1394_destroy_handle( tempFd );
for( i=0; i < MAX_IEEE1394_HOSTS; i++ )
{
/* check if port exists and has at least one node*/
if( !portinfo[i].nodes )
continue;
nodes = NULL;
nodecount = 0;
tempFd = dc1394_create_handle( i );
/* skip this port if we can't obtain a valid handle */
if( !tempFd )
continue;
msg_Dbg( p_demux, "Found ieee1394 port %d (%s) ... "
"checking for camera nodes",
i, portinfo[i].name );
num_ports++;
nodes = dc1394_get_camera_nodes( tempFd, &nodecount, 0 );
if( nodecount )
{
msg_Dbg( p_demux, "Found %d dc1394 cameras on port %d (%s)",
nodecount, i, portinfo[i].name );
if( node_list ) if( list->num == 0 )
node_list = realloc( node_list, sizeof(dc_camera) * (num_cameras+nodecount) ); {
else msg_Err(p_demux, "Can not find cameras");
node_list = malloc( sizeof(dc_camera) * nodecount); dc1394_camera_free_list (list);
dc1394_free( sys->p_dccontext );
free( sys );
p_demux->p_sys = NULL;
return VLC_EGENERIC;
}
sys->num_cameras = list->num;
msg_Dbg( p_demux, "Found %d dc1394 cameras.", list->num);
for( n = 0; n < nodecount; n++ ) if( sys->selected_uid )
{
int found = 0;
for( unsigned i = 0; i < sys->num_cameras; i++ )
{
if( list->ids[i].guid == sys->selected_uid )
{ {
int result = 0; sys->camera = dc1394_camera_new(sys->p_dccontext,
list->ids[i].guid);
result = dc1394_get_camera_info( tempFd, nodes[n], &info ); found++;
if( result == DC1394_SUCCESS ) break;
{
node_list[num_cameras+n].uid = info.euid_64;
}
node_list[num_cameras+n].node = nodes[n];
node_list[num_cameras+n].port = i;
} }
num_cameras += nodecount;
} }
else if( !found )
msg_Dbg( p_demux, "no cameras found on port %d (%s)", {
i, portinfo[i].name ); msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
sys->selected_uid );
if( tempFd ) dc1394_camera_free_list (list);
dc1394_destroy_handle( tempFd ); dc1394_free( sys->p_dccontext );
free( sys );
p_demux->p_sys = NULL;
return VLC_EGENERIC;
}
}
else if( sys->selected_camera >= (int)list->num )
{
msg_Err( p_demux, "There are not this many cameras. (%d/%d)",
sys->selected_camera, sys->num_cameras );
dc1394_camera_free_list (list);
dc1394_free( sys->p_dccontext );
free( sys );
p_demux->p_sys = NULL;
return VLC_EGENERIC;
}
else if( sys->selected_camera >= 0 )
{
sys->camera = dc1394_camera_new(sys->p_dccontext,
list->ids[sys->selected_camera].guid);
}
else
{
sys->camera = dc1394_camera_new(sys->p_dccontext,
list->ids[0].guid);
} }
sys->num_ports = num_ports;
sys->num_cameras = num_cameras; dc1394_camera_free_list (list);
sys->camera_nodes = node_list; return VLC_SUCCESS;
} }
/***************************************************************************** /*****************************************************************************
...@@ -208,13 +205,12 @@ static void ScanCameras( dc1394_sys *sys, demux_t *p_demux ) ...@@ -208,13 +205,12 @@ static void ScanCameras( dc1394_sys *sys, demux_t *p_demux )
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t *p_this ) static int Open( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys; demux_sys_t *p_sys;
es_format_t fmt; es_format_t fmt;
int i; dc1394error_t res;
int i_width; int i_width;
int i_height; int i_height;
int result = 0;
if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 ) if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -229,22 +225,22 @@ static int Open( vlc_object_t *p_this ) ...@@ -229,22 +225,22 @@ static int Open( vlc_object_t *p_this )
p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) ); p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
if( !p_sys ) if( !p_sys )
return VLC_ENOMEM; return VLC_ENOMEM;
memset( &fmt, 0, sizeof( es_format_t ) ); memset( &fmt, 0, sizeof( es_format_t ) );
/* DEFAULTS */ /* DEFAULTS */
p_sys->frame_size = MODE_640x480_YUV422; p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
p_sys->width = 640; p_sys->width = 640;
p_sys->height = 480; p_sys->height = 480;
p_sys->frame_rate = FRAMERATE_30; p_sys->frame_rate = DC1394_FRAMERATE_15;
p_sys->brightness = 200; p_sys->brightness = 200;
p_sys->focus = 0; p_sys->focus = 0;
p_sys->dma_capture = DMA_ON; /* defaults to VIDEO1394 capture mode */ p_sys->fd_audio = -1;
p_sys->fd_audio = -1; p_sys->p_dccontext = NULL;
p_sys->fd_video = NULL; p_sys->camera = NULL;
p_sys->camera_nodes = NULL; p_sys->selected_camera = -1;
p_sys->selected_camera = 0; p_sys->dma_buffers = 1;
p_sys->dma_device = NULL; p_sys->reset_bus = 0;
p_sys->selected_uid = 0;
/* PROCESS INPUT OPTIONS */ /* PROCESS INPUT OPTIONS */
if( process_options(p_demux) != VLC_SUCCESS ) if( process_options(p_demux) != VLC_SUCCESS )
...@@ -257,223 +253,145 @@ static int Open( vlc_object_t *p_this ) ...@@ -257,223 +253,145 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Dbg( p_demux, "Selected camera %d", p_sys->selected_camera ); p_sys->p_dccontext = dc1394_new();
msg_Dbg( p_demux, "Selected uid 0x%llx", p_sys->selected_uid ); if( !p_sys->p_dccontext )
{
msg_Err( p_demux, "Failed to initialise libdc1394");
free(p_demux->p_sys);
p_demux->p_sys = NULL;
return VLC_EGENERIC;
}
if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
return VLC_EGENERIC;
ScanCameras( p_sys, p_demux ); if( !p_sys->camera )
if( !p_sys->camera_nodes )
{ {
msg_Err( p_demux, "No camera found !!" ); msg_Err( p_demux, "No camera found !!" );
dc1394_free( p_sys->p_dccontext );
free( p_sys ); free( p_sys );
p_demux->p_sys = NULL; p_demux->p_sys = NULL;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( p_sys->selected_uid ) if( p_sys->reset_bus )
{ {
int found = 0; if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
for( i=0; i < p_sys->num_cameras; i++ )
{ {
if( p_sys->camera_nodes[i].uid == p_sys->selected_uid ) msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
{
p_sys->selected_camera = i;
found++;
break;
}
}
if( !found )
{
msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
p_sys->selected_uid );
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
else if( p_sys->selected_camera >= p_sys->num_cameras )
{
msg_Err( p_demux, "there are not this many cameras. (%d/%d)",
p_sys->selected_camera, p_sys->num_cameras );
Close( p_this );
return VLC_EGENERIC;
} }
p_sys->fd_video = dc1394_create_handle( if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
p_sys->camera_nodes[p_sys->selected_camera].port );
if( (int)p_sys->fd_video < 0 )
{ {
msg_Err( p_demux, "Can't init dc1394 handle" ); msg_Err( p_demux, "Unable to reset camera");
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* get camera info */ if( dc1394_camera_print_info( p_sys->camera,
result = dc1394_get_camera_info( p_sys->fd_video, stderr ) != DC1394_SUCCESS )
p_sys->camera_nodes[p_sys->selected_camera].node,
&p_sys->camera_info );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux ,"unable to get camera info" ); msg_Err( p_demux, "Unable to print camera info");
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
dc1394_print_camera_info( &p_sys->camera_info ); if( dc1394_feature_get_all( p_sys->camera,
result = dc1394_get_camera_misc_info( p_sys->fd_video, &p_sys->features ) != DC1394_SUCCESS )
p_sys->camera_nodes[p_sys->selected_camera].node,
&p_sys->misc_info );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "unable to get camera misc info" ); msg_Err( p_demux, "Unable to get feature set");
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
// TODO: only print features if verbosity increased
dc1394_feature_print_all(&p_sys->features, stderr);
/* init camera and set some video options */ #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/
result = dc1394_init_camera( p_sys->camera_info.handle, if( p_sys->video_device )
p_sys->camera_info.id );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "unable to get init dc1394 camera" ); if( dc1394_capture_set_device_filename( p_sys->camera,
Close( p_this ); p_sys->video_device ) != DC1394_SUCCESS )
return VLC_EGENERIC; {
msg_Err( p_demux, "Unable to set video device");
Close( p_this );
return VLC_EGENERIC;
}
} }
#endif
if( p_sys->focus ) if( p_sys->focus )
{ {
result = dc1394_set_focus( p_sys->camera_info.handle, if( dc1394_feature_set_value( p_sys->camera,
p_sys->camera_nodes[p_sys->selected_camera].node, DC1394_FEATURE_FOCUS,
p_sys->focus ); p_sys->focus ) != DC1394_SUCCESS )
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "unable to set initial focus to %u", msg_Err( p_demux, "Unable to set initial focus to %u",
p_sys->focus ); p_sys->focus );
} }
msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus ); msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
} }
result = dc1394_set_brightness( p_sys->camera_info.handle, if( dc1394_feature_set_value( p_sys->camera,
p_sys->camera_nodes[p_sys->selected_camera].node, DC1394_FEATURE_FOCUS,
p_sys->brightness ); p_sys->brightness ) != DC1394_SUCCESS )
if( result != DC1394_SUCCESS )
{
msg_Err( p_demux, "unable to set init brightness to %d",
p_sys->brightness);
Close( p_this );
return VLC_EGENERIC;
}
result = dc1394_set_video_framerate( p_sys->camera_info.handle,
p_sys->camera_nodes[p_sys->selected_camera].node,
p_sys->frame_rate );
if( result != DC1394_SUCCESS )
{
msg_Err( p_demux, "unable to set framerate to %d",
p_sys->frame_rate );
Close( p_this );
return VLC_EGENERIC;
}
p_sys->misc_info.framerate = p_sys->frame_rate;
result = dc1394_set_video_format( p_sys->camera_info.handle,
p_sys->camera_nodes[p_sys->selected_camera].node,
FORMAT_VGA_NONCOMPRESSED );
if( result != DC1394_SUCCESS )
{
msg_Err( p_demux, "unable to set video format to VGA_NONCOMPRESSED" );
Close( p_this );
return VLC_EGENERIC;
}
p_sys->misc_info.format = FORMAT_VGA_NONCOMPRESSED;
result = dc1394_set_video_mode( p_sys->camera_info.handle,
p_sys->camera_nodes[p_sys->selected_camera].node,
p_sys->frame_size );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "unable to set video mode" ); msg_Err( p_demux, "Unable to set initial brightness to %u",
Close( p_this ); p_sys->brightness );
return VLC_EGENERIC;
} }
p_sys->misc_info.mode = p_sys->frame_size; msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
/* reprobe everything */ if( dc1394_video_set_framerate( p_sys->camera,
result = dc1394_get_camera_info( p_sys->camera_info.handle, p_sys->frame_rate ) != DC1394_SUCCESS )
p_sys->camera_info.id,
&p_sys->camera_info );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "Could not get camera basic information!" ); msg_Err( p_demux, "Unable to set framerate");
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
result = dc1394_get_camera_misc_info( p_sys->camera_info.handle, if( dc1394_video_set_mode( p_sys->camera,
p_sys->camera_info.id, p_sys->video_mode ) != DC1394_SUCCESS )
&p_sys->misc_info );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "Could not get camera misc information!" ); msg_Err( p_demux, "Unable to set video mode");
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* set iso_channel */ if( dc1394_video_set_iso_speed( p_sys->camera,
result = dc1394_set_iso_channel_and_speed( p_sys->camera_info.handle, DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
p_sys->camera_info.id,
p_sys->selected_camera,
SPEED_400 );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "Could not set iso channel!" ); msg_Err( p_demux, "Unable to set iso speed");
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Dbg( p_demux, "Using ISO channel %d", p_sys->misc_info.iso_channel );
p_sys->misc_info.iso_channel = p_sys->selected_camera;
/* and setup capture */ /* and setup capture */
if( p_sys->dma_capture ) res = dc1394_capture_setup( p_sys->camera,
{ p_sys->dma_buffers,
result = dc1394_dma_setup_capture( p_sys->camera_info.handle, DC1394_CAPTURE_FLAGS_DEFAULT);
p_sys->camera_info.id, if( res != DC1394_SUCCESS )
p_sys->misc_info.iso_channel, {
p_sys->misc_info.format, if( res == DC1394_NO_BANDWIDTH )
p_sys->misc_info.mode,
SPEED_400,
p_sys->misc_info.framerate,
10, 0,
p_sys->dma_device,
&p_sys->camera );
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux ,"unable to setup camera" ); msg_Err( p_demux ,"No bandwidth: try adding the "
Close( p_this ); "\"resetbus\" option" );
return VLC_EGENERIC;
} }
} else
else
{
result = dc1394_setup_capture( p_sys->camera_info.handle,
p_sys->camera_info.id,
p_sys->misc_info.iso_channel,
p_sys->misc_info.format,
p_sys->misc_info.mode,
SPEED_400,
p_sys->misc_info.framerate,
&p_sys->camera );
if( result != DC1394_SUCCESS)
{ {
msg_Err( p_demux ,"unable to setup camera" ); msg_Err( p_demux ,"Unable to setup capture" );
Close( p_this );
return VLC_EGENERIC;
} }
Close( p_this );
return VLC_EGENERIC;
} }
/* TODO - UYV444 chroma converter is missing, when it will be available /* TODO - UYV444 chroma converter is missing, when it will be available
* fourcc will become variable (and not just a fixed value for UYVY) * fourcc will become variable (and not just a fixed value for UYVY)
*/ */
i_width = p_sys->camera.frame_width; i_width = p_sys->width;
i_height = p_sys->camera.frame_height; i_height = p_sys->height;
if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY, if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
i_width, i_height, i_width, i_height,
...@@ -489,7 +407,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -489,7 +407,7 @@ static int Open( vlc_object_t *p_this )
fmt.video.i_width = i_width; fmt.video.i_width = i_width;
fmt.video.i_height = i_height; fmt.video.i_height = i_height;
msg_Dbg( p_demux, "added new video es %4.4s %dx%d", msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
(char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height ); (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
p_sys->p_es_video = es_out_Add( p_demux->out, &fmt ); p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
...@@ -510,7 +428,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -510,7 +428,7 @@ static int Open( vlc_object_t *p_this )
fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate * fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
fmt.audio.i_bitspersample; fmt.audio.i_bitspersample;
msg_Dbg( p_demux, "new audio es %d channels %dHz", msg_Dbg( p_demux, "New audio es %d channels %dHz",
fmt.audio.i_channels, fmt.audio.i_rate ); fmt.audio.i_channels, fmt.audio.i_rate );
p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt ); p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
...@@ -518,23 +436,16 @@ static int Open( vlc_object_t *p_this ) ...@@ -518,23 +436,16 @@ static int Open( vlc_object_t *p_this )
} }
/* have the camera start sending us data */ /* have the camera start sending us data */
result = dc1394_start_iso_transmission( p_sys->camera_info.handle, if( dc1394_video_set_transmission( p_sys->camera,
p_sys->camera_info.id ); DC1394_ON ) != DC1394_SUCCESS )
if( result != DC1394_SUCCESS )
{ {
msg_Err( p_demux, "unable to start camera iso transmission" ); msg_Err( p_demux, "Unable to start camera iso transmission" );
if( p_sys->dma_capture ) dc1394_capture_stop( p_sys->camera );
{
dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
}
else
{
dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
}
Close( p_this ); Close( p_this );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_sys->misc_info.is_iso_on = DC1394_TRUE; msg_Dbg( p_demux, "Set iso transmission" );
// TODO: reread camera
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -548,7 +459,7 @@ static void OpenAudioDev( demux_t *p_demux ) ...@@ -548,7 +459,7 @@ static void OpenAudioDev( demux_t *p_demux )
p_sys->fd_audio = utf8_open( psz_device, O_RDONLY | O_NONBLOCK ); p_sys->fd_audio = utf8_open( psz_device, O_RDONLY | O_NONBLOCK );
if( p_sys->fd_audio < 0 ) if( p_sys->fd_audio < 0 )
{ {
msg_Err( p_demux, "cannot open audio device (%s)", psz_device ); msg_Err( p_demux, "Cannot open audio device (%s)", psz_device );
CloseAudioDev( p_demux ); CloseAudioDev( p_demux );
} }
...@@ -558,7 +469,7 @@ static void OpenAudioDev( demux_t *p_demux ) ...@@ -558,7 +469,7 @@ static void OpenAudioDev( demux_t *p_demux )
result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format ); result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format );
if( (result < 0) || (i_format != AFMT_S16_LE) ) if( (result < 0) || (i_format != AFMT_S16_LE) )
{ {
msg_Err( p_demux, "cannot set audio format (16b little endian) " msg_Err( p_demux, "Cannot set audio format (16b little endian) "
"(%d)", i_format ); "(%d)", i_format );
CloseAudioDev( p_demux ); CloseAudioDev( p_demux );
} }
...@@ -566,7 +477,7 @@ static void OpenAudioDev( demux_t *p_demux ) ...@@ -566,7 +477,7 @@ static void OpenAudioDev( demux_t *p_demux )
result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels ); result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
if( result < 0 ) if( result < 0 )
{ {
msg_Err( p_demux, "cannot set audio channels count (%d)", msg_Err( p_demux, "Cannot set audio channels count (%d)",
p_sys->channels ); p_sys->channels );
CloseAudioDev( p_demux ); CloseAudioDev( p_demux );
} }
...@@ -574,11 +485,12 @@ static void OpenAudioDev( demux_t *p_demux ) ...@@ -574,11 +485,12 @@ static void OpenAudioDev( demux_t *p_demux )
result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate ); result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
if( result < 0 ) if( result < 0 )
{ {
msg_Err( p_demux, "cannot set audio sample rate (%s)", p_sys->i_sample_rate ); msg_Err( p_demux, "Cannot set audio sample rate (%d)",
p_sys->i_sample_rate );
CloseAudioDev( p_demux ); CloseAudioDev( p_demux );
} }
msg_Dbg( p_demux, "opened adev=`%s' %s %dHz", msg_Dbg( p_demux, "Opened adev=`%s' %s %dHz",
psz_device, psz_device,
(p_sys->channels > 1) ? "stereo" : "mono", (p_sys->channels > 1) ? "stereo" : "mono",
p_sys->i_sample_rate ); p_sys->i_sample_rate );
...@@ -605,37 +517,27 @@ static void Close( vlc_object_t *p_this ) ...@@ -605,37 +517,27 @@ static void Close( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int result = 0;
/* Stop data transmission */ /* Stop data transmission */
result = dc1394_stop_iso_transmission( p_sys->fd_video, if( dc1394_video_set_transmission( p_sys->camera,
p_sys->camera.node ); DC1394_OFF ) != DC1394_SUCCESS )
if( result != DC1394_SUCCESS ) msg_Err( p_demux, "Unable to stop camera iso transmission" );
{
msg_Err( p_demux, "couldn't stop the camera" );
}
/* Close camera */ /* Close camera */
if( p_sys->dma_capture ) dc1394_capture_stop( p_sys->camera );
{
dc1394_dma_unlisten( p_sys->fd_video, &p_sys->camera );
dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
}
else
{
dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
}
if( p_sys->fd_video )
dc1394_destroy_handle( p_sys->fd_video );
CloseAudioDev( p_demux ); CloseAudioDev( p_demux );
free( p_sys->camera_nodes ); dc1394_camera_free(p_sys->camera);
free( p_sys->audio_device ); dc1394_free(p_sys->p_dccontext);
if( p_sys->audio_device )
free( p_sys->audio_device );
free( p_sys ); free( p_sys );
} }
#if 0
static void MovePixelUYVY( void *src, int spos, void *dst, int dpos ) static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
{ {
char u,v,y; char u,v,y;
...@@ -667,6 +569,7 @@ static void MovePixelUYVY( void *src, int spos, void *dst, int dpos ) ...@@ -667,6 +569,7 @@ static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
dc[1] = y; dc[1] = y;
} }
} }
#endif
/***************************************************************************** /*****************************************************************************
* Demux: * Demux:
...@@ -675,49 +578,35 @@ static block_t *GrabVideo( demux_t *p_demux ) ...@@ -675,49 +578,35 @@ static block_t *GrabVideo( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block = NULL; block_t *p_block = NULL;
int result = 0;
if( p_sys->dma_capture ) if( dc1394_capture_dequeue( p_sys->camera,
{ DC1394_CAPTURE_POLICY_WAIT,
result = dc1394_dma_single_capture( &p_sys->camera ); &p_sys->frame ) != DC1394_SUCCESS )
if( result != DC1394_SUCCESS )
{
msg_Err( p_demux, "unable to capture a frame" );
return NULL;
}
}
else
{ {
result = dc1394_single_capture( p_sys->camera_info.handle, msg_Err( p_demux, "Unable to capture a frame" );
&p_sys->camera ); return NULL;
if( result != DC1394_SUCCESS )
{
msg_Err( p_demux, "unable to capture a frame" );
return NULL;
}
} }
p_block = block_New( p_demux, p_sys->camera.frame_width * p_block = block_New( p_demux, p_sys->frame->size[0] *
p_sys->camera.frame_height * 2 ); p_sys->frame->size[1] * 2 );
if( !p_block ) if( !p_block )
{ {
msg_Err( p_demux, "cannot get block" ); msg_Err( p_demux, "Can not get block" );
return NULL; return NULL;
} }
if( !p_sys->camera.capture_buffer ) if( !p_sys->frame->image )
{ {
msg_Err (p_demux, "caputer buffer empty"); msg_Err (p_demux, "Capture buffer empty");
block_Release( p_block ); block_Release( p_block );
return NULL; return NULL;
} }
memcpy( p_block->p_buffer, (const char *)p_sys->camera.capture_buffer, memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
p_sys->camera.frame_width * p_sys->camera.frame_height * 2 ); p_sys->width * p_sys->height * 2 );
p_block->i_pts = p_block->i_dts = mdate(); p_block->i_pts = p_block->i_dts = mdate();
if( p_sys->dma_capture ) dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
dc1394_dma_done_with_buffer( &p_sys->camera );
return p_block; return p_block;
} }
...@@ -733,7 +622,7 @@ static block_t *GrabAudio( demux_t *p_demux ) ...@@ -733,7 +622,7 @@ static block_t *GrabAudio( demux_t *p_demux )
p_block = block_New( p_demux, p_sys->i_audio_max_frame_size ); p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
if( !p_block ) if( !p_block )
{ {
msg_Warn( p_demux, "cannot get buffer" ); msg_Warn( p_demux, "Cannot get buffer" );
return NULL; return NULL;
} }
...@@ -768,8 +657,7 @@ static int Demux( demux_t *p_demux ) ...@@ -768,8 +657,7 @@ static int Demux( demux_t *p_demux )
p_blocka = GrabAudio( p_demux ); p_blocka = GrabAudio( p_demux );
/* Try grabbing video frame */ /* Try grabbing video frame */
if( (int)p_sys->fd_video > 0 ) p_blockv = GrabVideo( p_demux );
p_blockv = GrabVideo( p_demux );
if( !p_blocka && !p_blockv ) if( !p_blocka && !p_blockv )
{ {
...@@ -799,6 +687,7 @@ static int Demux( demux_t *p_demux ) ...@@ -799,6 +687,7 @@ static int Demux( demux_t *p_demux )
*****************************************************************************/ *****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args ) static int Control( demux_t *p_demux, int i_query, va_list args )
{ {
VLC_UNUSED( p_demux );
switch( i_query ) switch( i_query )
{ {
/* Special for access_demux */ /* Special for access_demux */
...@@ -831,8 +720,13 @@ static int process_options( demux_t *p_demux ) ...@@ -831,8 +720,13 @@ static int process_options( demux_t *p_demux )
char *psz_parser; char *psz_parser;
char *token = NULL; char *token = NULL;
char *state = NULL; char *state = NULL;
const char *in_size = NULL;
const char *in_fmt = NULL;
float rate_f; float rate_f;
if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
return VLC_EGENERIC;
psz_dup = strdup( p_demux->psz_path ); psz_dup = strdup( p_demux->psz_path );
psz_parser = psz_dup; psz_parser = psz_dup;
for( token = strtok_r( psz_parser,":",&state); token; for( token = strtok_r( psz_parser,":",&state); token;
...@@ -847,26 +741,26 @@ static int process_options( demux_t *p_demux ) ...@@ -847,26 +741,26 @@ static int process_options( demux_t *p_demux )
* video size of 160x120 is temporarily disabled * video size of 160x120 is temporarily disabled
*/ */
msg_Err( p_demux, msg_Err( p_demux,
"video size of 160x120 is actually disabled for lack of chroma " "video size of 160x120 is actually disabled for lack of"
"support. It will relased ASAP, until then try an higher size " "chroma support. It will relased ASAP, until then try "
"(320x240 and 640x480 are fully supported)" ); "an higher size (320x240 and 640x480 are fully supported)" );
free( psz_dup ); free(psz_dup);
return VLC_EGENERIC; return VLC_EGENERIC;
#if 0 #if 0
p_sys->frame_size = MODE_160x120_YUV444; in_size = "160x120";
p_sys->width = 160; p_sys->width = 160;
p_sys->height = 120; p_sys->height = 120;
#endif #endif
} }
else if( strncmp( token, "320x240", 7 ) == 0 ) else if( strncmp( token, "320x240", 7 ) == 0 )
{ {
p_sys->frame_size = MODE_320x240_YUV422; in_size = "320x240";
p_sys->width = 320; p_sys->width = 320;
p_sys->height = 240; p_sys->height = 240;
} }
else if( strncmp( token, "640x480", 7 ) == 0 ) else if( strncmp( token, "640x480", 7 ) == 0 )
{ {
p_sys->frame_size = MODE_640x480_YUV422; in_size = "640x480";
p_sys->width = 640; p_sys->width = 640;
p_sys->height = 480; p_sys->height = 480;
} }
...@@ -877,27 +771,62 @@ static int process_options( demux_t *p_demux ) ...@@ -877,27 +771,62 @@ static int process_options( demux_t *p_demux )
" 160x120, 320x240, and 640x480. " " 160x120, 320x240, and 640x480. "
"Please specify one of them. You have specified %s.", "Please specify one of them. You have specified %s.",
token ); token );
free( psz_dup ); free(psz_dup);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Dbg( p_demux, "Requested video size : %s",token ); msg_Dbg( p_demux, "Requested video size : %s",token );
} }
if( strncmp( token, "format=", strlen("format=") ) == 0 )
{
token += strlen("format=");
if( strncmp( token, "YUV411", 6 ) == 0 )
{
in_fmt = "YUV411";
}
else if( strncmp( token, "YUV422", 6 ) == 0 )
{
in_fmt = "YUV422";
}
else if( strncmp( token, "YUV444", 6 ) == 0 )
{
in_fmt = "YUV444";
}
else if( strncmp( token, "RGB8", 4 ) == 0 )
{
in_fmt = "RGB8";
}
else if( strncmp( token, "MONO8", 5 ) == 0 )
{
in_fmt = "MONO8";
}
else if( strncmp( token, "MONO16", 6 ) == 0 )
{
in_fmt = "MONO16";
}
else
{
msg_Err( p_demux, "Invalid format %s.", token );
free(psz_dup);
return VLC_EGENERIC;
}
msg_Dbg( p_demux, "Requested video format : %s", token );
}
else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 ) else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
{ {
token += strlen("fps="); token += strlen("fps=");
sscanf( token, "%g", &rate_f ); sscanf( token, "%g", &rate_f );
if( rate_f == 1.875 ) if( rate_f == 1.875 )
p_sys->frame_rate = FRAMERATE_1_875; p_sys->frame_rate = DC1394_FRAMERATE_1_875;
else if( rate_f == 3.75 ) else if( rate_f == 3.75 )
p_sys->frame_rate = FRAMERATE_3_75; p_sys->frame_rate = DC1394_FRAMERATE_3_75;
else if( rate_f == 7.5 ) else if( rate_f == 7.5 )
p_sys->frame_rate = FRAMERATE_7_5; p_sys->frame_rate = DC1394_FRAMERATE_7_5;
else if( rate_f == 15 ) else if( rate_f == 15 )
p_sys->frame_rate = FRAMERATE_15; p_sys->frame_rate = DC1394_FRAMERATE_15;
else if( rate_f == 30 ) else if( rate_f == 30 )
p_sys->frame_rate = FRAMERATE_30; p_sys->frame_rate = DC1394_FRAMERATE_30;
else if( rate_f == 60 ) else if( rate_f == 60 )
p_sys->frame_rate = FRAMERATE_60; p_sys->frame_rate = DC1394_FRAMERATE_60;
else else
{ {
msg_Err( p_demux , msg_Err( p_demux ,
...@@ -905,11 +834,16 @@ static int process_options( demux_t *p_demux ) ...@@ -905,11 +834,16 @@ static int process_options( demux_t *p_demux )
" 1.875, 3.75, 7.5, 15, 30, 60. " " 1.875, 3.75, 7.5, 15, 30, 60. "
"Please specify one of them. You have specified %s.", "Please specify one of them. You have specified %s.",
token); token);
free( psz_dup ); free(psz_dup);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
msg_Dbg( p_demux, "Requested frame rate : %s",token ); msg_Dbg( p_demux, "Requested frame rate : %s",token );
} }
else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
{
token += strlen("resetbus");
p_sys->reset_bus = 1;
}
else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 ) else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
{ {
int nr = 0; int nr = 0;
...@@ -920,11 +854,27 @@ static int process_options( demux_t *p_demux ) ...@@ -920,11 +854,27 @@ static int process_options( demux_t *p_demux )
msg_Err( p_demux, "Bad brightness value '%s', " msg_Err( p_demux, "Bad brightness value '%s', "
"must be an unsigned integer.", "must be an unsigned integer.",
token ); token );
free( psz_dup ); free(psz_dup);
return VLC_EGENERIC;
}
}
else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
{
int nr = 0;
int in_buf = 0;
token += strlen("buffers=");
nr = sscanf( token, "%d", &in_buf);
if( nr != 1 || in_buf < 1 )
{
msg_Err( p_demux, "DMA buffers must be 1 or greater." );
free(psz_dup);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
else p_sys->dma_buffers = in_buf;
} }
#if 0 #if 0
// NOTE: If controller support is added back, more logic will needed to be added
// after the cameras are scanned.
else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 ) else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
{ {
int nr = 0; int nr = 0;
...@@ -949,31 +899,15 @@ static int process_options( demux_t *p_demux ) ...@@ -949,31 +899,15 @@ static int process_options( demux_t *p_demux )
msg_Err( p_demux, "Bad camera number '%s', " msg_Err( p_demux, "Bad camera number '%s', "
"must be an unsigned integer.", "must be an unsigned integer.",
token ); token );
free( psz_dup ); free(psz_dup);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
else if( strncmp( token, "capture=", strlen( "capture=" ) ) == 0) else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
{ {
token += strlen("capture="); token += strlen("vdev=");
if( strncmp(token, "raw1394",7) == 0 ) p_sys->video_device = strdup(token);
{ msg_Dbg( p_demux, "Using video device '%s'.", token );
msg_Dbg( p_demux, "DMA capture disabled!" );
p_sys->dma_capture = DMA_OFF;
}
else if( strncmp(token,"video1394",9) == 0 )
{
msg_Dbg( p_demux, "DMA capture enabled!" );
p_sys->dma_capture = DMA_ON;
}
else
{
msg_Err(p_demux, "Bad capture method value '%s', "
"it can be 'raw1394' or 'video1394'.",
token );
free( psz_dup );
return VLC_EGENERIC;
}
} }
else if( strncmp( token, "adev=", strlen( "adev=" ) ) == 0 ) else if( strncmp( token, "adev=", strlen( "adev=" ) ) == 0 )
{ {
...@@ -993,8 +927,17 @@ static int process_options( demux_t *p_demux ) ...@@ -993,8 +927,17 @@ static int process_options( demux_t *p_demux )
} }
else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0) else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
{ {
int nr = 0;
token += strlen("focus="); token += strlen("focus=");
sscanf( token, "%u", &p_sys->focus ); nr = sscanf( token, "%u", &p_sys->focus );
if( nr != 1 )
{
msg_Err( p_demux, "Bad focus value '%s', "
"must be an unsigned integer.",
token );
free(psz_dup);
return VLC_EGENERIC;
}
} }
else if( strncmp( token, "uid=", strlen("uid=") ) == 0) else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
{ {
...@@ -1002,7 +945,41 @@ static int process_options( demux_t *p_demux ) ...@@ -1002,7 +945,41 @@ static int process_options( demux_t *p_demux )
sscanf( token, "0x%llx", &p_sys->selected_uid ); sscanf( token, "0x%llx", &p_sys->selected_uid );
} }
} }
free( psz_dup );
// The mode is a combination of size and format and not every format
// is supported by every size.
if( in_size)
{
if( strcmp( in_size, "160x120") == 0)
{
if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
}
else if( strcmp( in_size, "320x240") == 0)
{
if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
}
}
else
{ // 640x480 default
if( in_fmt )
{
if( strcmp( in_fmt, "RGB8") == 0)
p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
else if( strcmp( in_fmt, "MONO8") == 0)
p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
else if( strcmp( in_fmt, "MONO16") == 0)
p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
else if( strcmp( in_fmt, "YUV411") == 0)
p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
else // YUV422 default
p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
}
else // YUV422 default
p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment