mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-19 14:19:58 +01:00
Added auto deinterlacer for capture devices, Sample imports and exports capture device properties, Added fallback to RGB for webcam devices
git-svn-id: svn://code.dyne.org/veejay/trunk@579 eb8d1916-c9e9-0310-b8de-cf0c9472ead5
This commit is contained in:
@@ -186,6 +186,9 @@
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Set to 1 if you have unicap. */
|
||||
#undef HAVE_UNICAP
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
|
||||
@@ -1860,7 +1860,7 @@ static char *vevo_format_inline_property( vevo_port_t *port, int n_elem, int typ
|
||||
return res;
|
||||
}
|
||||
|
||||
static char *vevo_format_property( vevo_port_t *port, const char *key )
|
||||
char *vevo_format_property( vevo_port_t *port, const char *key )
|
||||
{
|
||||
char *res = NULL;
|
||||
char token[5];
|
||||
@@ -1892,6 +1892,9 @@ static char *vevo_format_property( vevo_port_t *port, const char *key )
|
||||
case VEVO_ATOM_TYPE_PORTPTR:
|
||||
token[0] = 'p';
|
||||
break;
|
||||
default:
|
||||
token[0] = 'g';
|
||||
break;
|
||||
}
|
||||
|
||||
if( token[0])
|
||||
@@ -1907,7 +1910,7 @@ static char *vevo_format_property( vevo_port_t *port, const char *key )
|
||||
|
||||
}
|
||||
|
||||
static const char *vevo_split_token_( const char *s, const char delim, char *buf, int buf_len )
|
||||
const char *vevo_split_token_( const char *s, const char delim, char *buf, int buf_len )
|
||||
{
|
||||
const char *c = s;
|
||||
int n = 0;
|
||||
@@ -1925,7 +1928,7 @@ static const char *vevo_split_token_( const char *s, const char delim, char *buf
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *vevo_scan_token_( const char *s )
|
||||
char *vevo_scan_token_( const char *s )
|
||||
{
|
||||
const char *c = s;
|
||||
int n = 0;
|
||||
@@ -1951,7 +1954,7 @@ static char *vevo_scan_token_( const char *s )
|
||||
return res;
|
||||
}
|
||||
|
||||
static const char *vevo_split_token_q( const char *s, const char delim, char *buf, int buf_len )
|
||||
const char *vevo_split_token_q( const char *s, const char delim, char *buf, int buf_len )
|
||||
{
|
||||
const char *c = s;
|
||||
int n = 0;
|
||||
@@ -2017,8 +2020,6 @@ int vevo_sscanf_property( vevo_port_t *port, const char *s)
|
||||
{
|
||||
int done = 0;
|
||||
char key[PROPERTY_KEY_SIZE];
|
||||
//@ what if series of key=value is passed?
|
||||
|
||||
bzero(key, PROPERTY_KEY_SIZE );
|
||||
const char *value = vevo_split_token_(s, '=', key, PROPERTY_KEY_SIZE );
|
||||
if(value==NULL)
|
||||
@@ -2029,6 +2030,10 @@ int vevo_sscanf_property( vevo_port_t *port, const char *s)
|
||||
|
||||
if( format == NULL )
|
||||
return done;
|
||||
if(atom==-1)
|
||||
atom = VEVO_ATOM_TYPE_DOUBLE;
|
||||
//@ if a property does not exist, DOUBLE is assumed
|
||||
//@ DOUBLE is valid for all sample's of type capture.
|
||||
|
||||
uint64_t i64_val[MAX_ELEMENTS];
|
||||
int32_t i32_val[MAX_ELEMENTS];
|
||||
@@ -2103,6 +2108,9 @@ int vevo_sscanf_property( vevo_port_t *port, const char *s)
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
|
||||
//veejay_msg(0, "Set: '%s' : %d, %g", key,n, dbl_val[0] );
|
||||
|
||||
if( n == 0 )
|
||||
error = vevo_property_set( port, key, atom, 0, NULL );
|
||||
else
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <unistd.h>
|
||||
#include <libyuv/yuvconv.h>
|
||||
#include <libvjmsg/vj-common.h>
|
||||
#include <ffmpeg/avcodec.h>
|
||||
/* this routine is the same as frame_YUV422_to_YUV420P , unpack
|
||||
* libdv's 4:2:2-packed into 4:2:0 planar
|
||||
* See http://mjpeg.sourceforge.net/ (MJPEG Tools) (lav-common.c)
|
||||
@@ -971,3 +972,21 @@ void yuv_blend_opacity( VJFrame *A, VJFrame *B, uint8_t alpha )
|
||||
yuv_1plane_blend_opacity( A->data[1], B->data[1], alpha, A->uv_len );
|
||||
yuv_1plane_blend_opacity( A->data[2], B->data[2], alpha, A->uv_len );
|
||||
}
|
||||
|
||||
void yuv_deinterlace( VJFrame *A, uint8_t *Y,uint8_t *U, uint8_t *V )
|
||||
{
|
||||
AVPicture p,q;
|
||||
p.data[0] = A->data[0];
|
||||
p.data[1] = A->data[1];
|
||||
p.data[2] = A->data[3];
|
||||
p.linesize[0] = A->width;
|
||||
p.linesize[1] = A->uv_width;
|
||||
p.linesize[2] = A->uv_width;
|
||||
q.data[0] = Y;
|
||||
q.data[1] = U;
|
||||
q.data[2] = V;
|
||||
q.linesize[0] = A->width;
|
||||
q.linesize[1] = A->uv_width;
|
||||
q.linesize[2] = A->uv_width;
|
||||
avpicture_deinterlace( &p,&q, A->pixfmt, A->width,A->height );
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ void yuv_convert_and_scale( void *sws, VJFrame *src, VJFrame *dst );
|
||||
|
||||
void yuv_convert_and_scale_rgb( void *sws, VJFrame *src, VJFrame *dst );
|
||||
|
||||
void yuv_deinterlace( VJFrame *A, uint8_t *Y,uint8_t *U, uint8_t *V );
|
||||
|
||||
int yuv_sws_get_cpu_flags(void);
|
||||
|
||||
|
||||
@@ -640,7 +640,6 @@ static void vj_event_parse_port( veejay_t *v, char *msg )
|
||||
if( port_str[len-1] == ';' )
|
||||
port_str[len-1] = '\0';
|
||||
|
||||
|
||||
if( strncasecmp(port_name, "sample#",5 ) == 0 )
|
||||
{
|
||||
sample_sscanf_port( v->current_sample, port_str );
|
||||
@@ -668,8 +667,6 @@ int vj_event_parse_msg( veejay_t * v, char *msg )
|
||||
veejay_chomp_str( msg, &msg_len );
|
||||
msg_len --;
|
||||
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "VIMS: Parse message '%s'", msg );
|
||||
|
||||
if( msg_len < MSG_MIN_LEN )
|
||||
{
|
||||
veejay_msg(VEEJAY_MSG_ERROR, "VIMS Message too small, dropped!");
|
||||
|
||||
@@ -589,6 +589,16 @@ void vj_init_vevo_events(void)
|
||||
"0=off,1=on",
|
||||
1,
|
||||
NULL );
|
||||
index_map_[VIMS_SET_PORT] = _new_event(
|
||||
"%s",
|
||||
VIMS_SET_PORT,
|
||||
"Set properties",
|
||||
vj_event_none,
|
||||
1,
|
||||
VIMS_REQUIRE_ALL_PARAMS,
|
||||
"formatted text",
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
index_map_[VIMS_SAMPLE_CHAIN_ENTRY_SET_FX] = _new_event(
|
||||
"%d %d %s",
|
||||
|
||||
@@ -220,25 +220,11 @@ static struct
|
||||
const char *name;
|
||||
int atom_type;
|
||||
} stream_property_list[] = {
|
||||
{ "width", VEVO_ATOM_TYPE_STRING },
|
||||
{ "height", VEVO_ATOM_TYPE_INT },
|
||||
{ "palette", VEVO_ATOM_TYPE_INT },
|
||||
{ "active", VEVO_ATOM_TYPE_INT },
|
||||
{ "format", VEVO_ATOM_TYPE_INT },
|
||||
{ "data", VEVO_ATOM_TYPE_VOIDPTR },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
int atom_type;
|
||||
} stream_capture_list[] = {
|
||||
{ "device", VEVO_ATOM_TYPE_STRING },
|
||||
{ "channel", VEVO_ATOM_TYPE_INT },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
@@ -804,13 +790,20 @@ void *sample_get_fx_port( int id, int fx_entry )
|
||||
void sample_set_property_ptr( void *ptr, const char *key, int atom_type, void *value )
|
||||
{
|
||||
sample_runtime_data *info = (sample_runtime_data*) ptr;
|
||||
if(info)
|
||||
if( info->type == VJ_TAG_TYPE_CAPTURE)
|
||||
{
|
||||
vj_unicap_select_value( info->data,key, atom_type,value );
|
||||
}
|
||||
vevo_property_set( info->info_port, key, atom_type,1, value );
|
||||
}
|
||||
|
||||
void sample_set_property( int id, const char *key, int atom_type, void *value )
|
||||
{
|
||||
sample_runtime_data *info = (sample_runtime_data*) find_sample( id );
|
||||
if( info->type == VJ_TAG_TYPE_CAPTURE)
|
||||
{
|
||||
vj_unicap_select_value( info->data,key, atom_type,value );
|
||||
}
|
||||
if(info)
|
||||
vevo_property_set( info->info_port, key, atom_type,1, value );
|
||||
}
|
||||
@@ -824,6 +817,9 @@ void sample_get_property( int id, const char *key, void *dst )
|
||||
void sample_get_property_ptr( void *ptr, const char *key, void *dst )
|
||||
{
|
||||
sample_runtime_data *info = (sample_runtime_data*) ptr;
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( info != NULL );
|
||||
#endif
|
||||
vevo_property_get( info->info_port, key, 0, dst );
|
||||
}
|
||||
|
||||
@@ -855,8 +851,6 @@ static int sample_new_stream(void *info, int type )
|
||||
vevo_property_set( info, stream_color_list[i].name, stream_color_list[i].atom_type, 1, &v );
|
||||
break;
|
||||
case VJ_TAG_TYPE_CAPTURE:
|
||||
for( i = 0 ; stream_capture_list[i].name != NULL; i ++ )
|
||||
vevo_property_set( info, stream_capture_list[i].name, stream_capture_list[i].atom_type, 0, NULL );
|
||||
break;
|
||||
case VJ_TAG_TYPE_YUV4MPEG:
|
||||
for( i = 0; stream_file_list[i].name != NULL; i ++ )
|
||||
@@ -1151,6 +1145,24 @@ void *sample_last(void)
|
||||
return found;
|
||||
}
|
||||
|
||||
static void sample_collect_unicap_properties( void *sample )
|
||||
{
|
||||
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||
char **props = vj_unicap_get_list( srd->data );
|
||||
int i;
|
||||
for( i = 0; props[i] != NULL ; i ++ )
|
||||
{
|
||||
double dvalue = 0.0;
|
||||
int n = vj_unicap_get_value( srd->data, props[i], VEVO_ATOM_TYPE_DOUBLE, &dvalue );
|
||||
|
||||
veejay_msg(0, "Add property '%s', default is %g", props[i], dvalue);
|
||||
|
||||
vevo_property_set( srd->info_port, props[i], VEVO_ATOM_TYPE_DOUBLE,1,&dvalue );
|
||||
|
||||
free( props[i] );
|
||||
}
|
||||
}
|
||||
|
||||
//@ what pixelformat are we supposed to play,
|
||||
/// what pixel format is file openened in ?
|
||||
int sample_open( void *sample, const char *token, int extra_token , sample_video_info_t *project_settings )
|
||||
@@ -1228,6 +1240,7 @@ int sample_open( void *sample, const char *token, int extra_token , sample_video
|
||||
res=1;
|
||||
sit->speed = 1;
|
||||
sample_set_property_ptr( sample, "speed", VEVO_ATOM_TYPE_INT,&(sit->speed));
|
||||
sample_collect_unicap_properties( sample );
|
||||
|
||||
break;
|
||||
case VJ_TAG_TYPE_NET:
|
||||
@@ -1921,14 +1934,6 @@ static int sample_identify_xml_token( int sample_type, const unsigned char *name
|
||||
if( strcasecmp( (const char*) name, stream_property_list[i].name ) == 0 )
|
||||
return stream_property_list[i].atom_type;
|
||||
}
|
||||
if( sample_type == VJ_TAG_TYPE_CAPTURE )
|
||||
{
|
||||
for( i = 0; stream_capture_list[i].name != NULL ; i ++ )
|
||||
{
|
||||
if( strcasecmp( (const char*) name, stream_capture_list[i].name ) == 0 )
|
||||
return stream_capture_list[i].atom_type;
|
||||
}
|
||||
}
|
||||
if( sample_type == VJ_TAG_TYPE_NET )
|
||||
{
|
||||
for( i = 0; stream_socket_list[i].name != NULL ; i ++ )
|
||||
@@ -2279,12 +2284,141 @@ int sample_fx_sscanf_port( void *sample, const char *s, const char *id )
|
||||
//@ fx_instance must be valid
|
||||
return 1;
|
||||
}
|
||||
#define PROPERTY_KEY_SIZE 64
|
||||
#define MAX_ELEMENTS 16
|
||||
static int sample_sscanf_property( sample_runtime_data *srd ,vevo_port_t *port, const char *s)
|
||||
{
|
||||
int done = 0;
|
||||
char key[PROPERTY_KEY_SIZE];
|
||||
bzero(key, PROPERTY_KEY_SIZE );
|
||||
const char *value = vevo_split_token_(s, '=', key, PROPERTY_KEY_SIZE );
|
||||
if(value==NULL)
|
||||
return 0;
|
||||
|
||||
char *format = vevo_format_property( port, key );
|
||||
int atom = vevo_property_atom_type( port, key );
|
||||
|
||||
if( format == NULL )
|
||||
return done;
|
||||
if(atom==-1)
|
||||
atom = VEVO_ATOM_TYPE_DOUBLE;
|
||||
//@ if a property does not exist, DOUBLE is assumed
|
||||
//@ DOUBLE is valid for all sample's of type capture.
|
||||
|
||||
uint64_t i64_val[MAX_ELEMENTS];
|
||||
int32_t i32_val[MAX_ELEMENTS];
|
||||
double dbl_val[MAX_ELEMENTS];
|
||||
char *str_val[MAX_ELEMENTS];
|
||||
|
||||
int cur_elem = 0;
|
||||
int n = 0;
|
||||
|
||||
const char *p = value;
|
||||
char *fmt = format;
|
||||
while( *fmt != '\0' )
|
||||
{
|
||||
char arg[256];
|
||||
bzero(arg,256);
|
||||
|
||||
if( *fmt == 's' )
|
||||
p = vevo_split_token_q( p, ':', arg, 1024 );
|
||||
else
|
||||
p = vevo_split_token_( p, ':', arg, 1024 );
|
||||
|
||||
if( p == NULL )
|
||||
return 0;
|
||||
|
||||
if( arg[0] != ':' )
|
||||
{
|
||||
switch(*fmt)
|
||||
{
|
||||
case 'd':
|
||||
n = sscanf( arg, "%d", &(i32_val[cur_elem]));
|
||||
break;
|
||||
case 'D':
|
||||
n = sscanf( arg, "%lld", &(i64_val[cur_elem]));
|
||||
break;
|
||||
case 'g':
|
||||
n = sscanf( arg, "%lf", &(dbl_val[cur_elem]));
|
||||
break;
|
||||
case 's':
|
||||
str_val[cur_elem] = strdup( arg );
|
||||
n = 1;
|
||||
break;
|
||||
default:
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
}
|
||||
|
||||
*fmt++;
|
||||
cur_elem ++;
|
||||
}
|
||||
|
||||
void *ptr = NULL;
|
||||
if( n > 0 )
|
||||
switch( *format )
|
||||
{
|
||||
case 'd':
|
||||
ptr = &(i32_val[0]);
|
||||
break;
|
||||
case 'D':
|
||||
ptr = &(i64_val[0]);
|
||||
break;
|
||||
case 'g':
|
||||
ptr = &(dbl_val[0]);
|
||||
break;
|
||||
case 's':
|
||||
ptr = &(str_val[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
|
||||
//veejay_msg(0, "Set: '%s' : %d, %g", key,n, dbl_val[0] );
|
||||
if( n == 0 )
|
||||
error = vevo_property_set( port, key, atom, 0, NULL );
|
||||
else
|
||||
{
|
||||
sample_set_property_ptr( srd, key, atom, ptr );
|
||||
error = VEVO_NO_ERROR;
|
||||
}
|
||||
if( error == VEVO_NO_ERROR )
|
||||
done = 1;
|
||||
return done;
|
||||
}
|
||||
|
||||
int sample_sscanf_port( void *sample, const char *s )
|
||||
{
|
||||
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||
return vevo_sscanf_port( srd->info_port, s );
|
||||
const char *ptr = s;
|
||||
int len = strlen(s);
|
||||
int i = 0;
|
||||
while( len > 0 )
|
||||
{
|
||||
char *token = vevo_scan_token_(ptr);
|
||||
int token_len;
|
||||
if( token )
|
||||
{
|
||||
token_len = strlen(token);
|
||||
if(sample_sscanf_property(srd,srd->info_port, token ))
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
token_len = len;
|
||||
if(sample_sscanf_property( srd,srd->info_port, ptr ))
|
||||
i++;
|
||||
}
|
||||
len -= token_len;
|
||||
ptr += token_len;
|
||||
}
|
||||
return 1;
|
||||
// return vevo_sscanf_port( srd->info_port, s );
|
||||
}
|
||||
|
||||
|
||||
@@ -2313,3 +2447,4 @@ char *sample_sprintf_port( void *sample )
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ typedef struct
|
||||
int deviceID;
|
||||
int sizes[3];
|
||||
int active;
|
||||
int deinterlace;
|
||||
int rgb;
|
||||
void *sampler;
|
||||
} vj_unicap_t;
|
||||
|
||||
@@ -60,58 +62,6 @@ typedef struct
|
||||
int num_devices;
|
||||
} unicap_driver_t;
|
||||
|
||||
static void *vj_unicap_convert_property( unicap_property_t *property, void *device_port)
|
||||
{
|
||||
/* void *port = vevo_port_new( VEVO_ANONYMOUS_PORT );
|
||||
int error = vevo_property_set( device_port, property->identifier,VEVO_ATOM_TYPE_PORTPTR,1,&port );
|
||||
#ifdef STRICT_CHECKING
|
||||
assert ( error == VEVO_NO_ERROR );
|
||||
#endif
|
||||
|
||||
if( property->type == UNICAP_PROPERTY_TYPE_RANGE )
|
||||
{
|
||||
double value = (double) property->range.min;
|
||||
error = vevo_property_set( port, "min", VEVO_ATOM_TYPE_DOUBLE,1,&value );
|
||||
#ifdef STRICT_CHECKING
|
||||
assert ( error == VEVO_NO_ERROR );
|
||||
#endif
|
||||
value = (double) property->range.max;
|
||||
error = vevo_property_set( port, "max", VEVO_ATOM_TYPE_DOUBLE,1,&value );
|
||||
#ifdef STRICT_CHECKING
|
||||
assert ( error == VEVO_NO_ERROR );
|
||||
#endif
|
||||
value = (double) property->range.value;
|
||||
error = vevo_property_set( port, "value", VEVO_ATOM_TYPE_DOUBLE,1,&value );
|
||||
}
|
||||
|
||||
if( property->type == UNICAP_PROPERTY_TYPE_MENU )
|
||||
{
|
||||
//used for source and norm
|
||||
int n = property->menu.menu_item_count ;
|
||||
int j;
|
||||
for( j = 0; j < n ; j ++ )
|
||||
{
|
||||
char key[64];
|
||||
sprintf(key, "%d",j);
|
||||
error = vevo_property_set( port, key, VEVO_ATOM_TYPE_STRING,1,&(property->menu.menu_items[j]));
|
||||
#ifdef STRICT_CHECKING
|
||||
assert ( error == VEVO_NO_ERROR );
|
||||
#endif
|
||||
if( !strcmp( property->menu.menu_items[i], property->menu_item ))
|
||||
{
|
||||
error = vevo_property_set( port, "selected", VEVO_ATOM_TYPE_INT,1,&j );
|
||||
#ifdef STRICT_CHECKING
|
||||
assert ( error == VEVO_NO_ERROR );
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return port;*/
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static int vj_unicap_scan_enumerate_devices(void *unicap)
|
||||
{
|
||||
int i;
|
||||
@@ -173,13 +123,6 @@ static int vj_unicap_scan_enumerate_devices(void *unicap)
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( error == VEVO_NO_ERROR );
|
||||
#endif
|
||||
|
||||
for( j = 0; SUCCESS( unicap_enumerate_properties( ud->handle, NULL, &property, j ) ); j++ )
|
||||
{
|
||||
unicap_get_property( ud->handle, &property );
|
||||
void *props = vj_unicap_convert_property( &property, device_port);
|
||||
}
|
||||
|
||||
unicap_close( ud->handle );
|
||||
}
|
||||
return i;
|
||||
@@ -203,7 +146,7 @@ void vj_unicap_deinit(void *dud )
|
||||
free(ud);
|
||||
dud = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
int vj_unicap_set_property( void *ud, char *key, int atom_type, void *val )
|
||||
{
|
||||
unicap_property_t property;
|
||||
@@ -219,6 +162,7 @@ int vj_unicap_set_property( void *ud, char *key, int atom_type, void *val )
|
||||
&property_spec, &property, i ) ); i ++ )
|
||||
{
|
||||
unicap_get_property( vut->handle, &property);
|
||||
|
||||
if( strcmp(property.identifier, key) == 0 )
|
||||
{
|
||||
if(atom_type == VEVO_ATOM_TYPE_STRING)
|
||||
@@ -240,15 +184,62 @@ int vj_unicap_set_property( void *ud, char *key, int atom_type, void *val )
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vj_unicap_get_property( void *ud, char *key,int atom_type, void *dst )
|
||||
*/
|
||||
int vj_unicap_select_value( void *ud, char *key, int atom_type, void *val )
|
||||
{
|
||||
unicap_property_t property;
|
||||
unicap_property_t property_spec;
|
||||
int i;
|
||||
if(atom_type != VEVO_ATOM_TYPE_STRING && atom_type != VEVO_ATOM_TYPE_DOUBLE )
|
||||
return 0;
|
||||
unicap_void_property( &property_spec );
|
||||
vj_unicap_t *vut = (vj_unicap_t*) ud;
|
||||
for( i = 0; SUCCESS( unicap_enumerate_properties( vut->handle,
|
||||
&property_spec, &property, i ) ); i ++ )
|
||||
{
|
||||
unicap_get_property( vut->handle, &property);
|
||||
if( strcmp( property.identifier, key ) == 0 )
|
||||
{
|
||||
|
||||
if( property.type == UNICAP_PROPERTY_TYPE_MENU )
|
||||
{
|
||||
int n = property.menu.menu_item_count;
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( atom_type == VEVO_ATOM_TYPE_DOUBLE );
|
||||
#endif
|
||||
int idx = (int) *( (double*) val );
|
||||
veejay_msg(0, "To menu item %d",idx);
|
||||
strcpy( property.menu_item, property.menu.menu_items[idx] );
|
||||
|
||||
unicap_set_property( vut->handle, &property );
|
||||
|
||||
|
||||
veejay_msg(0,"changed menu item %d to %s", n, property.menu_item );
|
||||
return 1;
|
||||
}
|
||||
if( property.type == UNICAP_PROPERTY_TYPE_RANGE )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( atom_type == VEVO_ATOM_TYPE_DOUBLE) ;
|
||||
#endif
|
||||
double fval = (double) *( (double*) val);
|
||||
if(fval < property.range.min)
|
||||
fval = property.range.min;
|
||||
else if(fval > property.range.max)
|
||||
fval = property.range.max;
|
||||
property.value = (double) *((double*) val);
|
||||
unicap_set_property( vut->handle, &property );
|
||||
veejay_msg(0, "Changed range value to %f", property.value );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_unicap_get_range( void *ud, char *key, double *min , double *max )
|
||||
{
|
||||
unicap_property_t property;
|
||||
unicap_property_t property_spec;
|
||||
int i;
|
||||
unicap_void_property( &property_spec );
|
||||
vj_unicap_t *vut = (vj_unicap_t*) ud;
|
||||
|
||||
@@ -256,27 +247,101 @@ int vj_unicap_get_property( void *ud, char *key,int atom_type, void *dst )
|
||||
&property_spec, &property, i ) ); i ++ )
|
||||
{
|
||||
unicap_get_property( vut->handle, &property);
|
||||
if( strcmp(property.identifier, key) == 0 )
|
||||
|
||||
if( strcmp( property.identifier, key ) == 0 )
|
||||
continue;
|
||||
|
||||
if( property.type == UNICAP_PROPERTY_TYPE_MENU )
|
||||
{
|
||||
if(atom_type == VEVO_ATOM_TYPE_STRING)
|
||||
{
|
||||
char *d = (char*) dst;
|
||||
d = strdup( (char*)property.menu_item );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(atom_type == VEVO_ATOM_TYPE_DOUBLE)
|
||||
{
|
||||
memcpy(dst, &property.value, sizeof(double));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*min = 0.0;
|
||||
*max = (double) property.menu.menu_item_count;
|
||||
return 1;
|
||||
}
|
||||
if( property.type == UNICAP_PROPERTY_TYPE_RANGE )
|
||||
{
|
||||
*min = property.range.min;
|
||||
*max = property.range.max;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **vj_unicap_get_list( void *ud )
|
||||
{
|
||||
unicap_property_t property;
|
||||
unicap_property_t property_spec;
|
||||
int i;
|
||||
unicap_void_property( &property_spec );
|
||||
vj_unicap_t *vut = (vj_unicap_t*) ud;
|
||||
|
||||
for( i = 0; SUCCESS( unicap_enumerate_properties( vut->handle,
|
||||
&property_spec, &property, i ) ); i ++ )
|
||||
{
|
||||
}
|
||||
|
||||
int n = i;
|
||||
|
||||
char **res = (char**) malloc(sizeof(char*) * (n+1) );
|
||||
memset(res, 0,sizeof(char*) * (n+1));
|
||||
|
||||
for( i = 0;i < n; i ++ )
|
||||
{
|
||||
if( SUCCESS( unicap_enumerate_properties(vut->handle,
|
||||
&property_spec,&property,i ) ) )
|
||||
{
|
||||
res[i] = strdup( property.identifier );
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int vj_unicap_get_value( void *ud, char *key, int atom_type, void *value )
|
||||
{
|
||||
unicap_property_t property;
|
||||
unicap_property_t property_spec;
|
||||
int i;
|
||||
unicap_void_property( &property_spec );
|
||||
vj_unicap_t *vut = (vj_unicap_t*) ud;
|
||||
|
||||
for( i = 0; SUCCESS( unicap_enumerate_properties( vut->handle,
|
||||
&property_spec, &property, i ) ); i ++ )
|
||||
{
|
||||
unicap_get_property( vut->handle, &property);
|
||||
|
||||
if( strcmp( property.identifier, key ) != 0 )
|
||||
continue;
|
||||
|
||||
if( property.type == UNICAP_PROPERTY_TYPE_MENU )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( atom_type == VEVO_ATOM_TYPE_DOUBLE );
|
||||
#endif
|
||||
int n = property.menu.menu_item_count;
|
||||
int j;
|
||||
for( j =0; j < n; j ++ )
|
||||
{
|
||||
if( strcmp( property.menu_item, property.menu.menu_items[j] ) == 0 )
|
||||
{
|
||||
double *dval = value;
|
||||
*dval = (double) j;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( property.type == UNICAP_PROPERTY_TYPE_RANGE )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( atom_type == VEVO_ATOM_TYPE_DOUBLE );
|
||||
#endif
|
||||
double *dval = value;
|
||||
*dval = property.value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_unicap_num_capture_devices( void *dud )
|
||||
{
|
||||
@@ -339,7 +404,7 @@ int vj_unicap_configure_device( void *ud, int pixel_format, int w, int h )
|
||||
switch(pixel_format)
|
||||
{
|
||||
case FMT_420:
|
||||
fourcc = get_fourcc( "420P" );
|
||||
fourcc = get_fourcc( "YU12" );
|
||||
vut->sizes[1] = (w*h)/4;
|
||||
vut->sizes[2] = vut->sizes[1];
|
||||
break;
|
||||
@@ -355,6 +420,11 @@ int vj_unicap_configure_device( void *ud, int pixel_format, int w, int h )
|
||||
vut->sizes[2] = vut->sizes[1];
|
||||
vut->sampler = subsample_init( w );
|
||||
break;
|
||||
#ifdef STRICT_CHECKING
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
int i;
|
||||
@@ -369,20 +439,37 @@ int vj_unicap_configure_device( void *ud, int pixel_format, int w, int h )
|
||||
|
||||
if( !SUCCESS( unicap_set_format( vut->handle, &(vut->format) ) ) )
|
||||
{
|
||||
veejay_msg(0,"Failed to set pixel format");
|
||||
unsigned int rgb_fourcc = get_fourcc( "RGB4" );
|
||||
unicap_format_t rgb_spec, rgb_format;
|
||||
for( i = 0;
|
||||
SUCCESS( unicap_enumerate_formats( vut->handle, &rgb_spec, &rgb_format, i ) ); i ++ )
|
||||
{
|
||||
if( rgb_fourcc == rgb_format.fourcc )
|
||||
{
|
||||
vut->rgb = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!vut->rgb)
|
||||
return 0;
|
||||
else
|
||||
if( !SUCCESS( unicap_set_format( vut->handle, &rgb_format ) ) )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vut->deinterlace = 1;
|
||||
}
|
||||
|
||||
veejay_msg(0, "Selected '%s'", vut->format.identifier );
|
||||
|
||||
/*
|
||||
char *comp = "Composite1";
|
||||
if(vj_unicap_set_property( vut, "video source", VEVO_ATOM_TYPE_STRING, &comp ) )
|
||||
{
|
||||
veejay_msg(2, "Changed channel to Composite1");
|
||||
}
|
||||
}*/
|
||||
|
||||
veejay_msg(0, "Capture video in %d x %d, format is %s", vut->format.size.width,
|
||||
vut->format.size.height,
|
||||
vut->format.identifier );
|
||||
// memset( &(vut->buffer), 0x0, sizeof( unicap_data_buffer_t ) );
|
||||
vut->buffer.data = vj_malloc( w * h * 8 );
|
||||
vut->buffer.buffer_size = (sizeof(unsigned char) * 4 * w * h );
|
||||
|
||||
@@ -424,13 +511,32 @@ int vj_unicap_grab_frame( void *vut, void *slot )
|
||||
veejay_msg(0,"Failed to wait for buffer on device: %s\n", v->device.identifier );
|
||||
return 0;
|
||||
}
|
||||
// veejay_memcpy( f->data[0], v->buffer.data, v->sizes[0] );
|
||||
// veejay_memcpy( f->data[1], v->buffer.data + v->sizes[0], v->sizes[1] );
|
||||
// veejay_memcpy( f->data[2], v->buffer.data + v->sizes[0] +v->sizes[1] , v->sizes[2]);
|
||||
|
||||
if( v->deinterlace )
|
||||
{
|
||||
yuv_deinterlace( f, v->buffer.data,v->buffer.data+v->sizes[0],v->buffer.data+v->sizes[0]+
|
||||
v->sizes[1] );
|
||||
if( v->sampler )
|
||||
chroma_supersample( SSM_422_444, v->sampler, f->data, f->width,f->height );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!v->rgb)
|
||||
{
|
||||
veejay_memcpy( f->data[0], v->buffer.data, v->sizes[0] );
|
||||
veejay_memcpy( f->data[1], v->buffer.data + v->sizes[0], v->sizes[1] );
|
||||
veejay_memcpy( f->data[2], v->buffer.data + v->sizes[0] +v->sizes[1] , v->sizes[2]);
|
||||
|
||||
if( v->sampler )
|
||||
{
|
||||
chroma_supersample( SSM_422_444, v->sampler, f->data, f->width,f->height );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
util_convertsrc( v->buffer, f->width,f->height,f->pixfmt, f->data );
|
||||
}
|
||||
}
|
||||
|
||||
// f->data[0] = v->buffer->data;
|
||||
|
||||
Reference in New Issue
Block a user