mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-20 06:40:01 +01:00
merge new vj-client
added threadsafe gethostbyname fix bug in reloaded set keyframes drop vj_client_send_buf* functions drop vj_client_setup_timeout keep thread local buffer to store incoming frame (unicast stream) recover gracefully when lock or unlock fails (unicast stream) adapt poll frequency to find acceptable delay times recover gracefully from network errors retry to create connection when it fails while playing destroy thread when locking functions fail simpler get_frame for tag dropped multicast stream for now fix veejay_strncpy, null terminate string drop use of bzero, use memset instead rewrite part of cmd, socket peer-to-peer rewrite VIMS verify message rewrite VIMS parsing message
This commit is contained in:
@@ -2104,9 +2104,12 @@ void on_curve_buttonstore_clicked(GtkWidget *widget, gpointer user_data )
|
||||
int len = end - start;
|
||||
float *data = (float*) vj_calloc(sizeof(float) * len );
|
||||
int *values = (int*) vj_calloc(sizeof(int) * len );
|
||||
unsigned char *kf = (unsigned char*) vj_calloc( (len*4)+25);
|
||||
|
||||
unsigned char *kkf = (unsigned char*) vj_calloc( (len*4)+64);
|
||||
int min=0,max=0;
|
||||
|
||||
unsigned char *kf = kkf + 9; //@ reserve space for header
|
||||
|
||||
_effect_get_minmax( id, &min,&max,j );
|
||||
|
||||
int k;
|
||||
@@ -2115,9 +2118,13 @@ void on_curve_buttonstore_clicked(GtkWidget *widget, gpointer user_data )
|
||||
for( k = 0 ; k < len ; k++ )
|
||||
values[k] = ( (int) ( data[k] * max ));
|
||||
|
||||
int total_len = 25 + (4 * len);
|
||||
int total_len = 9;
|
||||
int row_len = 3 + 2 + 2 + 8 + 8 + 2;
|
||||
sprintf( (char*)kf, "key%02d%02d%08d%08d%02d",i,j,start,end,type );
|
||||
unsigned char *ptr = kf + 25;
|
||||
unsigned char *ptr = kf + row_len;
|
||||
|
||||
total_len += row_len;
|
||||
|
||||
for( k = 0; k < len; k ++ )
|
||||
{
|
||||
unsigned char *p = ptr + (k*4);
|
||||
@@ -2125,13 +2132,22 @@ void on_curve_buttonstore_clicked(GtkWidget *widget, gpointer user_data )
|
||||
p[1] = (values[k] >> 8) & 0xff;
|
||||
p[2] = (values[k] >> 16) & 0xff;
|
||||
p[3] = (values[k] >> 24) & 0xff;
|
||||
|
||||
total_len += 4;
|
||||
}
|
||||
|
||||
free(values);
|
||||
free(data);
|
||||
|
||||
vj_client_send_bufX( info->client, V_CMD, kf,total_len );
|
||||
free(kf);
|
||||
char header[10];
|
||||
snprintf( header,10, "K%08d", total_len );
|
||||
for( k = 0; k < 9; k ++ )
|
||||
kkf[k] = header[k];
|
||||
|
||||
printf("[%s]: %d\n", kkf,total_len );
|
||||
|
||||
vj_client_send_buf( info->client, V_CMD, kkf,total_len );
|
||||
free(kkf);
|
||||
|
||||
vj_msg( VEEJAY_MSG_INFO, "Saved new animation for parameter %d on entry %d, start at frame %d and end at frame %d",j,i,start,end );
|
||||
|
||||
|
||||
@@ -1100,8 +1100,6 @@ static int gvr_veejay( veejay_preview_t *vp , veejay_track_t *v, int track_num
|
||||
}
|
||||
else
|
||||
{
|
||||
vj_client_setup_timeout( v->fd,V_CMD,1);
|
||||
|
||||
v->preview = is_button_toggled( "previewtoggle");
|
||||
v->active = 1;
|
||||
vj_msg(VEEJAY_MSG_WARNING, "VeejayGrabber: connected with %s:%d on Track %d %d x %d",
|
||||
|
||||
@@ -24,4 +24,4 @@ fi
|
||||
## slackware 13.1 and older
|
||||
#########################################
|
||||
|
||||
#autoreconf -v -fi
|
||||
autoreconf -v -fi
|
||||
|
||||
@@ -45,7 +45,6 @@ typedef struct
|
||||
int state;
|
||||
int have_frame;
|
||||
int error;
|
||||
int grab;
|
||||
int repeat;
|
||||
int w;
|
||||
int h;
|
||||
@@ -54,23 +53,22 @@ typedef struct
|
||||
int in_w;
|
||||
int in_h;
|
||||
int af;
|
||||
uint8_t *buf;
|
||||
} threaded_t;
|
||||
|
||||
static void lock_(threaded_t *t, const char *f, int line)
|
||||
#define STATE_INACTIVE 0
|
||||
#define STATE_RUNNING 1
|
||||
|
||||
static int lock(threaded_t *t)
|
||||
{
|
||||
// veejay_msg(0,"lock thread by %s, line %d",f,line);
|
||||
pthread_mutex_lock( &(t->mutex ));
|
||||
return pthread_mutex_lock( &(t->mutex ));
|
||||
}
|
||||
|
||||
static void unlock_(threaded_t *t, const char *f, int line)
|
||||
static int unlock(threaded_t *t)
|
||||
{
|
||||
// veejay_msg(0,"unlock thread by %s, line %d",f,line);
|
||||
pthread_mutex_unlock( &(t->mutex ));
|
||||
return pthread_mutex_unlock( &(t->mutex ));
|
||||
}
|
||||
|
||||
#define lock( t ) lock_( t, __FUNCTION__, __LINE__ )
|
||||
#define unlock( t ) unlock_( t, __FUNCTION__ , __LINE__ )
|
||||
|
||||
#define MS_TO_NANO(a) (a *= 1000000)
|
||||
static void net_delay(long nsec, long sec )
|
||||
{
|
||||
@@ -98,6 +96,9 @@ void *reader_thread(void *data)
|
||||
|
||||
success = vj_client_connect_dat( v, tag->source_name,tag->video_channel );
|
||||
|
||||
|
||||
t->buf = (uint8_t*) vj_calloc(sizeof(uint8_t) * 2048 * 1500 );
|
||||
|
||||
if( success > 0 ) {
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Connecton established with %s:%d",tag->source_name,
|
||||
tag->video_channel + 5);
|
||||
@@ -105,28 +106,32 @@ void *reader_thread(void *data)
|
||||
else if ( tag->source_type != VJ_TAG_TYPE_MCAST )
|
||||
{
|
||||
veejay_msg(0, "Unable to connect to %s: %d", tag->source_name, tag->video_channel+5);
|
||||
free(t->buf);
|
||||
pthread_exit(&(t->thread));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int optimistic = 1;
|
||||
unsigned int optimal = 8;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int error = 0;
|
||||
int pollres = 0;
|
||||
int res = 0;
|
||||
if( t->state == 0 )
|
||||
{
|
||||
vj_client_close(v);
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Closed connection with %s: %d",
|
||||
tag->source_name,tag->video_channel+5);
|
||||
vj_client_free(v);
|
||||
pthread_exit( &(t->thread));
|
||||
return NULL;
|
||||
/*
|
||||
if( t->have_frame == 1 ) {
|
||||
net_delay(2,0);
|
||||
int have_frame = 0;
|
||||
lock(v);
|
||||
have_frame = t->have_frame;
|
||||
unlock(v);
|
||||
if( have_frame == 1 )
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
lock(t);
|
||||
|
||||
if(!error && t->grab && tag->source_type == VJ_TAG_TYPE_NET && retrieve == 0 ) {
|
||||
if(!error && tag->source_type == VJ_TAG_TYPE_NET && retrieve == 0) {
|
||||
ret = vj_client_send( v, V_CMD, buf );
|
||||
if( ret <= 0 )
|
||||
{
|
||||
@@ -136,41 +141,53 @@ void *reader_thread(void *data)
|
||||
tag->video_channel );
|
||||
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->grab = 0;
|
||||
} else {
|
||||
optimistic = optimal;
|
||||
}
|
||||
}
|
||||
|
||||
if(!error && tag->source_type == VJ_TAG_TYPE_NET )
|
||||
{
|
||||
res = vj_client_poll(v, V_CMD );
|
||||
if( ret )
|
||||
if( res )
|
||||
{
|
||||
retrieve = 1;
|
||||
} else if ( ret < 0 ) {
|
||||
if(vj_client_link_can_read( v, V_CMD ) ) {
|
||||
retrieve = 2;
|
||||
if( optimistic < optimal && optimistic > 1 )
|
||||
optimal = (optimistic + optimal) / 2;
|
||||
}
|
||||
}
|
||||
else if ( res < 0 ) {
|
||||
veejay_msg(VEEJAY_MSG_DEBUG,
|
||||
"Error polling connection %s:%d",
|
||||
tag->source_name,
|
||||
tag->video_channel );
|
||||
error = 1;
|
||||
} else if ( res == 0 ) {
|
||||
retrieve = 1;
|
||||
net_delay( optimistic ,0); //@ decrease wait time after each try
|
||||
optimistic --;
|
||||
if( optimistic == 0 ) {
|
||||
optimal ++;
|
||||
if(optimal > 20 )
|
||||
optimal = 20; //@ upper bound
|
||||
optimistic = 1;
|
||||
}
|
||||
|
||||
} else if (tag->source_type == VJ_TAG_TYPE_MCAST )
|
||||
{
|
||||
error = 0;
|
||||
retrieve = 1;
|
||||
res = 1;
|
||||
continue; //@ keep waiting after SEND_FRAME until like ;; or error
|
||||
}
|
||||
}
|
||||
|
||||
long wait_time = 0;
|
||||
|
||||
if(!error && retrieve)
|
||||
if(!error && (retrieve == 2))
|
||||
{
|
||||
if( res )
|
||||
{
|
||||
ret = vj_client_read_i ( v, tag->socket_frame,tag->socket_len );
|
||||
if(lock(t) != 0 ) //@ lock memory region to write
|
||||
goto NETTHREADEXIT;
|
||||
|
||||
ret = vj_client_read_i ( v, t->buf,0 );
|
||||
if( ret <= 0 )
|
||||
{
|
||||
if( tag->source_type == VJ_TAG_TYPE_NET )
|
||||
@@ -181,48 +198,45 @@ void *reader_thread(void *data)
|
||||
tag->video_channel );
|
||||
error = 1;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// wait_time += 10;
|
||||
// }
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->in_fmt = v->in_fmt;
|
||||
t->in_w = v->in_width;
|
||||
t->in_h = v->in_height;
|
||||
t->have_frame = ret;
|
||||
t->grab = 1;
|
||||
t->have_frame = 1;
|
||||
retrieve = 0;
|
||||
}
|
||||
if(unlock(t) != 0 )
|
||||
goto NETTHREADEXIT;
|
||||
/*
|
||||
#ifdef STRICT_CHECKING
|
||||
if( vj_client_poll( v, V_CMD ) ) {
|
||||
char bogus[32];
|
||||
while( vj_client_link_can_read(v,V_CMD) )
|
||||
vj_client_read( v, bogus, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tag->source_type == VJ_TAG_TYPE_MCAST )
|
||||
wait_time = 15;
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
}
|
||||
unlock(t);
|
||||
|
||||
if( wait_time )
|
||||
{
|
||||
if ( wait_time > 15 )
|
||||
wait_time = 10;
|
||||
//net_delay( wait_time,0 );
|
||||
wait_time = 0;
|
||||
}
|
||||
|
||||
NETTHREADRETRY:
|
||||
if( error )
|
||||
{
|
||||
int success = 0;
|
||||
|
||||
vj_client_close( v );
|
||||
vj_client_free( v);
|
||||
v = vj_client_alloc( t->w, t->h, t->af );
|
||||
if(!v) {
|
||||
free(t->buf);
|
||||
pthread_exit( &(t->thread));
|
||||
return NULL;
|
||||
}
|
||||
net_delay( 0,3 );
|
||||
v->lzo = lzo_new();
|
||||
|
||||
veejay_msg(VEEJAY_MSG_INFO, " ZZzzzzz ... waiting for Link %s:%d to become ready", tag->source_name, tag->video_channel );
|
||||
net_delay( 0, 5 );
|
||||
|
||||
if(tag->source_type == VJ_TAG_TYPE_MCAST )
|
||||
success = vj_client_connect( v,NULL,tag->source_name,tag->video_channel );
|
||||
@@ -231,21 +245,45 @@ void *reader_thread(void *data)
|
||||
|
||||
if( success <= 0 )
|
||||
{
|
||||
wait_time = 4000;
|
||||
#ifdef STRICT_CHECKING
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "Tried to connect to %s:%d code=%d", tag->source_name,tag->video_channel,success);
|
||||
#endif
|
||||
goto NETTHREADRETRY;
|
||||
}
|
||||
else
|
||||
{
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Connecton re-established with %s:%d",tag->source_name,
|
||||
tag->video_channel + 5);
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Connecton re-established with %s:%d",tag->source_name,tag->video_channel + 5);
|
||||
}
|
||||
|
||||
t->grab = 0;
|
||||
retrieve = 0;
|
||||
}
|
||||
|
||||
|
||||
int cur_state = STATE_RUNNING;
|
||||
if(lock(t) != 0 )
|
||||
goto NETTHREADEXIT;
|
||||
cur_state = t->state;
|
||||
if(unlock(t) != 0 )
|
||||
goto NETTHREADEXIT;
|
||||
|
||||
if( cur_state == 0 )
|
||||
{
|
||||
vj_client_close(v);
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Network thread with %s: %d was told to exit",tag->source_name,tag->video_channel+5);
|
||||
vj_client_free(v);
|
||||
free(t->buf);
|
||||
pthread_exit( &(t->thread));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
NETTHREADEXIT:
|
||||
vj_client_close(v);
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Network thread with %s: %d was aborted",tag->source_name,tag->video_channel+5);
|
||||
vj_client_free(v);
|
||||
free(t->buf);
|
||||
pthread_exit( &(t->thread));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -262,14 +300,18 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] )
|
||||
threaded_t *t = (threaded_t*) tag->priv;
|
||||
const uint8_t *buf = tag->socket_frame;
|
||||
|
||||
lock(t);
|
||||
if( t->state == 0 || t->error )
|
||||
{
|
||||
if(t->repeat < 0)
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Connection closed with remote host");
|
||||
t->repeat++;
|
||||
unlock(t);
|
||||
int have_frame = 0;
|
||||
int state = 0;
|
||||
if(lock(t) != 0 )
|
||||
return 0;
|
||||
|
||||
have_frame = t->have_frame;
|
||||
state= t->state;
|
||||
if(unlock(t) != 0)
|
||||
return 0;
|
||||
|
||||
if( state == 0 || have_frame == 0 ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
//@ color space convert frame
|
||||
@@ -286,17 +328,6 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] )
|
||||
break;
|
||||
}
|
||||
|
||||
if(t->have_frame == 1 )
|
||||
{
|
||||
veejay_memcpy(buffer[0], tag->socket_frame, len );
|
||||
veejay_memcpy(buffer[1], tag->socket_frame+len, uv_len );
|
||||
veejay_memcpy(buffer[2], tag->socket_frame+len+uv_len, uv_len );
|
||||
t->grab = 1;
|
||||
unlock(t);
|
||||
return 1;
|
||||
}
|
||||
else if(t->have_frame == 2 )
|
||||
{
|
||||
VJFrame *a = NULL;
|
||||
VJFrame *b = NULL;
|
||||
|
||||
@@ -320,19 +351,21 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
a =yuv_yuv_template( tag->socket_frame, tag->socket_frame + b_len, tag->socket_frame+b_len+buvlen,
|
||||
t->in_w,t->in_h, t->in_fmt);
|
||||
a =yuv_yuv_template( t->buf, t->buf + b_len, t->buf+ b_len+ buvlen,t->in_w,t->in_h, t->in_fmt);
|
||||
}
|
||||
|
||||
b = yuv_yuv_template( buffer[0],buffer[1], buffer[2],t->w,t->h,t->f);
|
||||
|
||||
if(lock(t) != 0)
|
||||
return 0;
|
||||
yuv_convert_any_ac(a,b, a->format,b->format );
|
||||
t->have_frame = 0;
|
||||
if(unlock(t)!=0)
|
||||
return 0;
|
||||
|
||||
free(a);
|
||||
free(b);
|
||||
}
|
||||
t->grab = 1;
|
||||
|
||||
unlock(t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -341,16 +374,20 @@ int net_thread_get_frame_rgb( vj_tag *tag, uint8_t *buffer, int w, int h )
|
||||
threaded_t *t = (threaded_t*) tag->priv;
|
||||
const uint8_t *buf = tag->socket_frame;
|
||||
|
||||
lock(t);
|
||||
if( t->state == 0 || t->error )
|
||||
{
|
||||
if(t->repeat < 0)
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Connection closed with remote host");
|
||||
t->repeat++;
|
||||
unlock(t);
|
||||
int have_frame = 0;
|
||||
int state = 0;
|
||||
if(lock(t) != 0 )
|
||||
return 0;
|
||||
have_frame = t->have_frame;
|
||||
state= t->state;
|
||||
if(unlock(t) != 0 )
|
||||
return 0;
|
||||
|
||||
if( state == 0 || have_frame == 0 ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//@ color space convert frame
|
||||
int len = t->w * t->h;
|
||||
int uv_len = len;
|
||||
@@ -389,9 +426,7 @@ int net_thread_get_frame_rgb( vj_tag *tag, uint8_t *buffer, int w, int h )
|
||||
free(a);
|
||||
free(b);
|
||||
}
|
||||
t->grab = 1;
|
||||
|
||||
unlock(t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -403,31 +438,23 @@ int net_thread_start(vj_tag *tag, int wid, int height, int pixelformat)
|
||||
|
||||
if(tag->source_type == VJ_TAG_TYPE_MCAST ) {
|
||||
veejay_msg(0, "MCAST: fixme!");
|
||||
return 0;
|
||||
}
|
||||
//@
|
||||
// success = vj_client_connect( v,NULL,tag->source_name,tag->video_channel );
|
||||
/* else
|
||||
success = vj_client_connect_dat( v, tag->source_name,tag->video_channel );
|
||||
*/
|
||||
|
||||
threaded_t *t = (threaded_t*)tag->priv;
|
||||
|
||||
pthread_mutex_init( &(t->mutex), NULL );
|
||||
t->repeat = 0;
|
||||
t->w = wid;
|
||||
t->h = height;
|
||||
t->af = pixelformat;
|
||||
t->f = get_ffmpeg_pixfmt(pixelformat);
|
||||
t->have_frame = 0;
|
||||
t->error = 0;
|
||||
t->state = 1;
|
||||
t->grab = 1;
|
||||
t->state = STATE_RUNNING;
|
||||
|
||||
int p_err = pthread_create( &(t->thread), NULL, &reader_thread, (void*) tag );
|
||||
if( p_err ==0)
|
||||
|
||||
{
|
||||
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Created new %s threaded stream to veejay host %s port %d",
|
||||
tag->source_type == VJ_TAG_TYPE_MCAST ?
|
||||
"multicast" : "unicast", tag->source_name,tag->video_channel);
|
||||
@@ -482,11 +509,10 @@ void net_thread_stop(vj_tag *tag)
|
||||
threaded_t *t = (threaded_t*)tag->priv;
|
||||
int ret = 0;
|
||||
|
||||
lock(t);
|
||||
|
||||
if(lock(t) == 0 ) {
|
||||
t->state = 0;
|
||||
|
||||
unlock(t);
|
||||
}
|
||||
|
||||
pthread_mutex_destroy( &(t->mutex));
|
||||
|
||||
|
||||
@@ -209,7 +209,9 @@ static inline unsigned long long int rdtsc()
|
||||
#define small_memset(to,val,n) memset(to,val,n)
|
||||
char *veejay_strncpy( char *dest, const char *src, size_t n )
|
||||
{
|
||||
return strncpy( dest,src, n-1 );
|
||||
memcpy ( dest, src, n );
|
||||
dest[n] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
char *veejay_strncat( char *s1, char *s2, size_t n )
|
||||
|
||||
@@ -576,7 +576,7 @@ int veejay_get_file_ext( char *file, char *dst, int dlen)
|
||||
int len = strlen(file)-1;
|
||||
int i = 0;
|
||||
char tmp[dlen];
|
||||
bzero(tmp,dlen);
|
||||
memset( tmp, 0, dlen );
|
||||
while(len)
|
||||
{
|
||||
if(file[len] == '.')
|
||||
|
||||
@@ -27,9 +27,52 @@
|
||||
#include <libvjmsg/vj-msg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <pthread.h>
|
||||
#ifdef STRICT_CHECKING
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
|
||||
struct host_list {
|
||||
struct hostent hostent;
|
||||
char h_addr_space[1024];
|
||||
};
|
||||
|
||||
static int ref_count = 0;
|
||||
static pthread_key_t ghbn_key;
|
||||
static pthread_once_t ghbn_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void ghbn_cleanup(void *data) {
|
||||
struct host_list *current = (struct host_list *) data;
|
||||
ref_count--;
|
||||
free(current);
|
||||
}
|
||||
|
||||
static void create_ghbn_key() {
|
||||
pthread_key_create(&ghbn_key, ghbn_cleanup);
|
||||
}
|
||||
|
||||
struct hostent *sock_gethostbyname(const char *name) {
|
||||
struct hostent *result;
|
||||
int local_errno;
|
||||
|
||||
pthread_once(&ghbn_key_once, create_ghbn_key);
|
||||
|
||||
struct host_list *current = (struct host_list *) pthread_getspecific(ghbn_key);
|
||||
|
||||
if (!current) {
|
||||
current = (struct host_list *) calloc(1, sizeof(struct host_list));
|
||||
current->hostent.h_name = "busy";
|
||||
ref_count++;
|
||||
pthread_setspecific(ghbn_key, current);
|
||||
}
|
||||
|
||||
if (gethostbyname_r(name, &(current->hostent), current->h_addr_space,sizeof(current->h_addr_space),&result, &local_errno)) {
|
||||
h_errno = local_errno;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vj_sock_t *alloc_sock_t(void)
|
||||
{
|
||||
vj_sock_t *s = (vj_sock_t*) malloc(sizeof(vj_sock_t));
|
||||
@@ -47,7 +90,7 @@ void sock_t_free(vj_sock_t *s )
|
||||
|
||||
int sock_t_connect_and_send_http( vj_sock_t *s, char *host, int port, char *buf, int buf_len )
|
||||
{
|
||||
s->he = gethostbyname( host );
|
||||
s->he = sock_gethostbyname( host );
|
||||
if(s->he==NULL)
|
||||
return 0;
|
||||
s->sock_fd = socket( AF_INET, SOCK_STREAM , 0);
|
||||
@@ -97,9 +140,11 @@ int sock_t_connect_and_send_http( vj_sock_t *s, char *host, int port, char *bu
|
||||
|
||||
int sock_t_connect( vj_sock_t *s, char *host, int port )
|
||||
{
|
||||
s->he = gethostbyname( host );
|
||||
s->he = sock_gethostbyname( host );
|
||||
|
||||
if(s->he==NULL)
|
||||
return 0;
|
||||
|
||||
s->sock_fd = socket( AF_INET, SOCK_STREAM , 0);
|
||||
if(s->sock_fd < 0)
|
||||
{
|
||||
@@ -109,6 +154,7 @@ int sock_t_connect( vj_sock_t *s, char *host, int port )
|
||||
s->port_num = port;
|
||||
s->addr.sin_family = AF_INET;
|
||||
s->addr.sin_port = htons( port );
|
||||
|
||||
s->addr.sin_addr = *( (struct in_addr*) s->he->h_addr );
|
||||
|
||||
if( connect( s->sock_fd, (struct sockaddr*) &s->addr,
|
||||
|
||||
@@ -59,19 +59,15 @@ vj_client *vj_client_alloc( int w, int h, int f )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
v->orig_width = w;
|
||||
v->orig_height = h;
|
||||
v->cur_width = w;
|
||||
v->cur_height = h;
|
||||
v->cur_fmt = get_ffmpeg_pixfmt(f);
|
||||
v->space = NULL;
|
||||
v->c = (conn_type_t**) malloc(sizeof(conn_type_t*) * 2);
|
||||
v->c[0] = (conn_type_t*) malloc(sizeof(conn_type_t));
|
||||
v->c[1] = (conn_type_t*) malloc(sizeof(conn_type_t));
|
||||
v->blob = (unsigned char*) malloc(sizeof(unsigned char) * PACKET_LEN );
|
||||
if(!v->blob ) {
|
||||
veejay_msg(0, "Memory allocation error.");
|
||||
free(v->c[1]);
|
||||
free(v->c[0]);
|
||||
free(v->c);
|
||||
free(v);
|
||||
return NULL;
|
||||
}
|
||||
@@ -81,42 +77,22 @@ vj_client *vj_client_alloc( int w, int h, int f )
|
||||
v->space = (uint8_t*) malloc( sizeof(uint8_t) * w * h * 4 );
|
||||
memset(v->space,0,sizeof(uint8_t)*w*h*4);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef STRICT_CHECKING
|
||||
static void vj_client_check( vj_client *v, int sock_type )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
if( sock_type == V_STATUS ) {
|
||||
assert( v->c[1] != NULL );
|
||||
assert( v->c[1]->fd != NULL );
|
||||
}
|
||||
if( sock_type == V_CMD ) {
|
||||
assert( v->c[0] != NULL );
|
||||
assert( v->c[0]->fd != NULL );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void vj_client_free(vj_client *v)
|
||||
{
|
||||
if(v)
|
||||
{
|
||||
int i;
|
||||
if( v->c ) {
|
||||
for( i = 0; i < 2; i ++ ) {
|
||||
if(!v->c[i])
|
||||
continue;
|
||||
if( v->fd[0] ) {
|
||||
sock_t_free( v->fd[0] );
|
||||
}
|
||||
if( v->fd[1] ) {
|
||||
sock_t_free( v->fd[1] );
|
||||
}
|
||||
|
||||
free(v->c[i]);
|
||||
v->c[i] = NULL;
|
||||
}
|
||||
free(v->c);
|
||||
}
|
||||
v->fd[0] = NULL;
|
||||
v->fd[1] = NULL;
|
||||
|
||||
if(v->blob)
|
||||
free(v->blob);
|
||||
@@ -159,8 +135,7 @@ static int verify_integrity( char *buf, int len ) {
|
||||
int vj_client_window_sizes( int socket_fd, int *r, int *s )
|
||||
{
|
||||
int tmp = sizeof(int);
|
||||
if( getsockopt( socket_fd, SOL_SOCKET, SO_SNDBUF,(unsigned char*) s, &tmp) == -1 )
|
||||
{
|
||||
if( getsockopt( socket_fd, SOL_SOCKET, SO_SNDBUF,(unsigned char*) s, &tmp) == -1 ) {
|
||||
veejay_msg(0, "Cannot read socket buffer size: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
@@ -186,17 +161,17 @@ int vj_client_connect_dat(vj_client *v, char *host, int port_id )
|
||||
return 0;
|
||||
}
|
||||
|
||||
v->c[0]->type = VSOCK_C;
|
||||
v->c[0]->fd = alloc_sock_t();
|
||||
v->fd[0] = alloc_sock_t();
|
||||
|
||||
if( sock_t_connect( v->c[0]->fd, host, (port_id + 5) ) )
|
||||
if( sock_t_connect( v->fd[0], host, (port_id + 5) ) )
|
||||
{
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Connect to DAT port %d", port_id + 5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
v->c[1]->fd = alloc_sock_t();
|
||||
v->c[1]->type = 654321;
|
||||
v->fd[1] = NULL; // no status port
|
||||
v->ports[0] = port_id + 5;
|
||||
v->ports[1] = -1;
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -214,47 +189,57 @@ int vj_client_connect(vj_client *v, char *host, char *group_name, int port_id )
|
||||
{
|
||||
if(host == NULL)
|
||||
return error;
|
||||
#ifdef STRICT_CHECKING
|
||||
assert(v->fd[0] == NULL );
|
||||
assert(v->fd[1] == NULL );
|
||||
#endif
|
||||
|
||||
v->c[0]->type = VSOCK_C;
|
||||
v->c[0]->fd = alloc_sock_t();
|
||||
v->c[1]->type = VSOCK_S;
|
||||
v->c[1]->fd = alloc_sock_t();
|
||||
if(!v->c[0]->fd || !v->c[1]->fd )
|
||||
{
|
||||
veejay_msg(0, "Error opening socket");
|
||||
v->fd[0] = alloc_sock_t();
|
||||
v->fd[1] = alloc_sock_t();
|
||||
if(!v->fd[0]) {
|
||||
return error;
|
||||
}
|
||||
if(!v->fd[1] ) {
|
||||
free(v->fd[0]);
|
||||
return error;
|
||||
}
|
||||
|
||||
if( sock_t_connect( v->c[0]->fd, host, port_id + VJ_CMD_PORT ) )
|
||||
{
|
||||
if( sock_t_connect( v->c[1]->fd, host, port_id + VJ_STA_PORT ) )
|
||||
{
|
||||
if( sock_t_connect( v->fd[0], host, port_id + VJ_CMD_PORT ) ) {
|
||||
if( sock_t_connect( v->fd[1], host, port_id + VJ_STA_PORT ) ) {
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
veejay_msg(0, "Failed to connect to status port.");
|
||||
}
|
||||
} else {
|
||||
veejay_msg(0, "Failed to connect to command port.");
|
||||
}
|
||||
v->ports[0] = port_id + VJ_CMD_PORT;
|
||||
v->ports[1] = port_id + VJ_STA_PORT;
|
||||
#ifdef STRICT_CHECKING
|
||||
veejay_msg( VEEJAY_MSG_DEBUG, "connected CMD port %d (socket %p, type %d)",
|
||||
v->ports[0], v->fd[0], 0 );
|
||||
veejay_msg( VEEJAY_MSG_DEBUG, "connected STATUS port %d (socket %p, type %d)",
|
||||
V->ports[1], v->fd[1], 1 );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
v->c[0]->type = VMCAST_C;
|
||||
v->c[0]->r = mcast_new_receiver( group_name, port_id + VJ_CMD_MCAST );
|
||||
if(!v->c[0]->r ) {
|
||||
v->r = mcast_new_receiver( group_name, port_id + VJ_CMD_MCAST );
|
||||
if(!v->r ) {
|
||||
veejay_msg(0 ,"Unable to setup multicast receiver on group %s", group_name );
|
||||
return error;
|
||||
}
|
||||
|
||||
v->c[0]->s = mcast_new_sender( group_name );
|
||||
if(!v->c[0]->s ) {
|
||||
v->s = mcast_new_sender( group_name );
|
||||
if(!v->s ) {
|
||||
veejay_msg(0, "Unable to setup multicast sender on group %s", group_name );
|
||||
return error;
|
||||
}
|
||||
v->ports[0] = port_id + VJ_CMD_MCAST;
|
||||
v->ports[1] = port_id + VJ_CMD_MCAST_IN;
|
||||
|
||||
mcast_sender_set_peer( v->c[0]->s , group_name );
|
||||
mcast_sender_set_peer( v->s , group_name );
|
||||
v->mcast = 1;
|
||||
// mcast_receiver_set_peer( v->c[0]->r, group_name);
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "Client is interested in packets from group %s : %d, send to %d",
|
||||
@@ -267,48 +252,36 @@ int vj_client_connect(vj_client *v, char *host, char *group_name, int port_id )
|
||||
|
||||
int vj_client_link_can_write( vj_client *v, int sock_type ){
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
int n = sock_t_wds_isset( v->fd[sock_type] );
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "%s: type %d, socket %p : result=%d",
|
||||
__FUNCTION__, sock_type, v->fd[sock_type], n );
|
||||
return n;
|
||||
#else
|
||||
return sock_t_wds_isset( v->fd[sock_type]);
|
||||
#endif
|
||||
if(sock_type==VSOCK_S) {
|
||||
return sock_t_wds_isset( v->c[1]->fd );
|
||||
} else if (sock_type == VSOCK_C ) {
|
||||
return sock_t_rds_isset( v->c[0]->fd );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_link_can_read( vj_client *v, int sock_type ) {
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
int n = sock_t_rds_isset( v->fd[sock_type] );
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "%s: type %d, socket %p : result=%d",
|
||||
__FUNCTION__, sock_type, v->fd[sock_type], n );
|
||||
return n;
|
||||
#else
|
||||
return sock_t_rds_isset( v->fd[sock_type] );
|
||||
#endif
|
||||
|
||||
if( sock_type == VSOCK_S) {
|
||||
return sock_t_rds_isset(v->c[1]->fd);
|
||||
} else if (sock_type == VSOCK_C ) {
|
||||
return sock_t_rds_isset( v->c[0]->fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_poll( vj_client *v, int sock_type )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
int n = sock_t_poll( v->fd[sock_type] );
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "%s: type %d, socket %p : result=%d",
|
||||
__FUNCTION__, sock_type, v->fd[sock_type], n );
|
||||
return n;
|
||||
#else
|
||||
return sock_t_poll( v->fd[sock_type ]);
|
||||
#endif
|
||||
|
||||
if(sock_type == V_STATUS )
|
||||
{
|
||||
if(v->c[1]->type == VSOCK_S)
|
||||
return ( sock_t_poll(v->c[1]->fd ) );
|
||||
}
|
||||
if(sock_type == V_CMD )
|
||||
{
|
||||
if(v->c[0]->type == VSOCK_C)
|
||||
return ( sock_t_poll( v->c[0]->fd ));
|
||||
if(v->c[0]->type == VMCAST_C )
|
||||
return ( mcast_poll( v->c[0]->r ));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vj_client_decompress( vj_client *t,uint8_t *in, uint8_t *out, int data_len, int Y, int UV , int header_len,
|
||||
@@ -387,7 +360,7 @@ static int vj_client_packet_negotiate( vj_client *v, int *tokens )
|
||||
|
||||
//@ 1. read 44 bytes and see if its us
|
||||
veejay_memset( line,0, sizeof(line));
|
||||
int plen = sock_t_recv( v->c[0]->fd, line, 44 );
|
||||
int plen = sock_t_recv( v->fd[0], line, 44 );
|
||||
if( plen == 0 ) {
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "Remote closed connection.");
|
||||
return -1;
|
||||
@@ -440,9 +413,9 @@ int vj_client_read_i( vj_client *v, uint8_t *dst, int len )
|
||||
int conv = 1;
|
||||
int y_len = 0;
|
||||
int uv_len = 0;
|
||||
if( v->c[0]->type == VMCAST_C )
|
||||
if( v->mcast == 1)
|
||||
{
|
||||
uint8_t *in = mcast_recv_frame( v->c[0]->r, &p[0],&p[1], &p[2], &plen );
|
||||
uint8_t *in = mcast_recv_frame( v->r, &p[0],&p[1], &p[2], &plen );
|
||||
if( in == NULL )
|
||||
return 0;
|
||||
|
||||
@@ -478,7 +451,7 @@ int vj_client_read_i( vj_client *v, uint8_t *dst, int len )
|
||||
|
||||
return 1; //@ caller will memcpy it to destination buffer
|
||||
}
|
||||
else if ( v->c[0]->type == VSOCK_C )
|
||||
else
|
||||
{
|
||||
//@ result returns software package id
|
||||
int result = vj_client_packet_negotiate( v, tokens );
|
||||
@@ -538,6 +511,15 @@ int vj_client_read_i( vj_client *v, uint8_t *dst, int len )
|
||||
v->in_height = p[1];
|
||||
v->in_fmt = p[2];
|
||||
|
||||
if( v->in_width != v->orig_width || v->in_height != v->orig_height ) {
|
||||
free(v->space);
|
||||
v->space = vj_calloc(sizeof(uint8_t) * v->in_width * v->in_height * 4 );
|
||||
if(!v->space)
|
||||
return -1;
|
||||
v->orig_width = v->in_width;
|
||||
v->orig_height = v->in_height;
|
||||
}
|
||||
|
||||
uv_len = 0;
|
||||
y_len = p[0] * p[1];
|
||||
|
||||
@@ -555,7 +537,7 @@ int vj_client_read_i( vj_client *v, uint8_t *dst, int len )
|
||||
break;
|
||||
}
|
||||
|
||||
int n = sock_t_recv( v->c[0]->fd,v->space,p[3] );
|
||||
int n = sock_t_recv( v->fd[0],v->space,p[3] );
|
||||
if( n <= 0 ) {
|
||||
if( n == -1 ) {
|
||||
veejay_msg(VEEJAY_MSG_ERROR, "Error '%s' while reading socket", strerror(errno));
|
||||
@@ -584,198 +566,78 @@ int vj_client_read_i( vj_client *v, uint8_t *dst, int len )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_get_status_fd(vj_client *v, int sock_type )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
#endif
|
||||
|
||||
if(sock_type == V_STATUS)
|
||||
{
|
||||
vj_sock_t *c = v->c[1]->fd;
|
||||
return c->sock_fd;
|
||||
}
|
||||
if(sock_type == V_CMD )
|
||||
{
|
||||
if(!v->mcast)
|
||||
{
|
||||
vj_sock_t *c = v->c[0]->fd;
|
||||
return c->sock_fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
mcast_receiver *c = v->c[0]->r;
|
||||
return c->sock_fd;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_setup_timeout( vj_client *v, int sock_type, int timeout )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
#endif
|
||||
|
||||
if( sock_type == V_STATUS )
|
||||
{
|
||||
sock_t_set_timeout( v->c[1], timeout );
|
||||
}
|
||||
if( sock_type == V_CMD )
|
||||
{
|
||||
sock_t_set_timeout( v->c[0], timeout );
|
||||
}
|
||||
}
|
||||
|
||||
int vj_client_read_no_wait(vj_client *v, int sock_type, uint8_t *dst, int bytes )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
int n = sock_t_recv( v->fd[ sock_type ] ,dst, bytes );
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "%s: type %d, socket %p: %d bytes [%s]",
|
||||
__FUNCTION__, sock_type, v->fd[sock_type], bytes, dst );
|
||||
return n;
|
||||
#else
|
||||
return sock_t_recv( v->fd[ sock_type ], dst, bytes );
|
||||
#endif
|
||||
|
||||
if( sock_type == V_STATUS )
|
||||
{
|
||||
if(v->c[1] && v->c[1]->fd && v->c[1]->type == VSOCK_S)
|
||||
return( sock_t_recv( v->c[1]->fd, dst, bytes ) );
|
||||
}
|
||||
if( sock_type == V_CMD )
|
||||
{
|
||||
if(v->c[0] && v->c[0]->fd && v->c[0]->type == VSOCK_C)
|
||||
return ( sock_t_recv( v->c[0]->fd, dst, bytes ) );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_read(vj_client *v, int sock_type, uint8_t *dst, int bytes )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
#ifndef STRICT_CHECKING
|
||||
return sock_t_recv( v->fd[ sock_type ], dst, bytes );
|
||||
#else
|
||||
int n = sock_t_recv( v->fd[ sock_type ], dst, bytes );
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "type %d, read %d bytes '[%s]' from socket %p (port %d)",
|
||||
sock_type, bytes, dst, v->fd[sock_type], v->ports[ sock_type] );
|
||||
return n;
|
||||
#endif
|
||||
|
||||
if( sock_type == V_STATUS )
|
||||
{
|
||||
if(v->c[1] && v->c[1]->fd && v->c[1]->type == VSOCK_S) {
|
||||
return( sock_t_recv( v->c[1]->fd, dst, bytes ) );
|
||||
}
|
||||
}
|
||||
if( sock_type == V_CMD )
|
||||
{
|
||||
if(v->c[0] && v->c[0]->fd && v->c[0]->type == VSOCK_C) {
|
||||
return ( sock_t_recv( v->c[0]->fd, dst, bytes ) );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_send(vj_client *v, int sock_type,char *buf ) {
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
#endif
|
||||
int vj_client_send_buf(vj_client *v, int sock_type,unsigned char *buf, int len) {
|
||||
if( v->mcast ) {
|
||||
return mcast_send( v->s, (void*) buf, len , v->ports[sock_type ] );
|
||||
}
|
||||
return sock_t_send( v->fd[ sock_type ], buf, len );
|
||||
}
|
||||
|
||||
if( sock_type == V_CMD )
|
||||
{
|
||||
// format msg
|
||||
int vj_client_send(vj_client *v, int sock_type,unsigned char *buf) {
|
||||
int len = strlen(buf);
|
||||
sprintf(v->blob, "V%03dD%s", len, buf);
|
||||
#ifdef STRICT_CHECKING
|
||||
if(!verify_integrity(v->blob,strlen(v->blob)) ) {
|
||||
veejay_msg(0,"VIMS validation error in buf of %d bytes: '%s'", len,buf);
|
||||
}
|
||||
#endif
|
||||
if(v->c[0]->type == VSOCK_C)
|
||||
return ( sock_t_send( v->c[0]->fd, v->blob, len + 5 ));
|
||||
if(v->c[0]->type == VMCAST_C)
|
||||
return ( mcast_send( v->c[0]->s, (void*) v->blob, len + 5,
|
||||
v->ports[1] ));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vj_client_send_buf(vj_client *v, int sock_type,unsigned char *buf, int len )
|
||||
{
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
#endif
|
||||
|
||||
if( sock_type == V_CMD )
|
||||
{
|
||||
// format msg
|
||||
if( v->mcast ) {
|
||||
sprintf( v->blob, "V%03dD", len );
|
||||
veejay_memcpy( v->blob+5, buf, len );
|
||||
memcpy( v->blob + 5, buf, len );
|
||||
return mcast_send( v->s, (void*) v->blob, len + 5, v->ports[sock_type ] );
|
||||
}
|
||||
|
||||
sprintf( v->blob, "V%03dD", len );
|
||||
memcpy( v->blob + 5, buf, len );
|
||||
|
||||
return sock_t_send( v->fd[ sock_type ], v->blob, len + 5 );
|
||||
}
|
||||
|
||||
void vj_client_close( vj_client *v )
|
||||
{
|
||||
if( v->mcast == 1 ) {
|
||||
mcast_close_receiver( v->r );
|
||||
mcast_close_sender( v->s );
|
||||
v->s = NULL;
|
||||
v->r = NULL;
|
||||
} else {
|
||||
if( v->fd[0] ) {
|
||||
#ifdef STRICT_CHECKING
|
||||
if(!verify_integrity( v->blob, strlen(v->blob) ) ) {
|
||||
veejay_msg(0,"VIMS validation error in buf of %d bytes: '%s'", len+5,buf);
|
||||
}
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "close connection: socket %p", v->fd[0] );
|
||||
#endif
|
||||
|
||||
if(v->c[0]->type == VSOCK_C)
|
||||
return ( sock_t_send( v->c[0]->fd, v->blob, len + 5 ));
|
||||
|
||||
if(v->c[0]->type == VMCAST_C)
|
||||
return ( mcast_send( v->c[0]->s, (void*) v->blob, len + 5,
|
||||
v->ports[1] ));
|
||||
sock_t_close( v->fd[0] );
|
||||
sock_t_free( v->fd[0] );
|
||||
v->fd[0] = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vj_client_send_bufX(vj_client *v, int sock_type,unsigned char *buf, int len )
|
||||
{
|
||||
if( v->fd[1] ) {
|
||||
#ifdef STRICT_CHECKING
|
||||
vj_client_check( v,sock_type);
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "close connection: socket %p", v->fd[1] );
|
||||
#endif
|
||||
|
||||
if( sock_type == V_CMD )
|
||||
{
|
||||
// format msg
|
||||
sprintf(v->blob, "K%08d", len);
|
||||
veejay_memcpy( v->blob+9, buf, len );
|
||||
|
||||
if(v->c[0]->type == VSOCK_C)
|
||||
return ( sock_t_send( v->c[0]->fd, v->blob, len + 9 ));
|
||||
if(v->c[0]->type == VMCAST_C)
|
||||
return ( mcast_send( v->c[0]->s, (void*) v->blob, len + 9,
|
||||
v->ports[1] ));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vj_client_close( vj_client *v )
|
||||
{
|
||||
if(v)
|
||||
{
|
||||
if(v->c[0])
|
||||
{
|
||||
if(v->c[0]->type == VSOCK_C ) {
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( v->c[0]->fd != NULL );
|
||||
#endif
|
||||
sock_t_close(v->c[0]->fd );
|
||||
sock_t_free( v->c[0]->fd);
|
||||
v->c[0]->fd = NULL;
|
||||
}
|
||||
else if ( v->c[0]->type == VMCAST_C )
|
||||
{
|
||||
mcast_close_receiver( v->c[0]->r );
|
||||
mcast_close_sender( v->c[0]->s );
|
||||
sock_t_close( v->fd[1] );
|
||||
sock_t_free( v->fd[1] );
|
||||
v->fd[1] = NULL;
|
||||
}
|
||||
}
|
||||
if(v->c[1])
|
||||
{
|
||||
if(v->c[1]->type == VSOCK_S ) {
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( v->c[1]->fd != NULL );
|
||||
#endif
|
||||
#ifdef STRICT_CHECKING
|
||||
sock_t_close(v->c[1]->fd );
|
||||
sock_t_free(v->c[1]->fd);
|
||||
v->c[1]->fd = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_client_test(char *host, int port)
|
||||
|
||||
@@ -19,14 +19,6 @@
|
||||
#ifndef VJ_CLIENT_H
|
||||
#define VJ_CLIENT_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *r;
|
||||
void *s;
|
||||
void *fd;
|
||||
int type;
|
||||
} conn_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int planes[3];
|
||||
@@ -36,12 +28,20 @@ typedef struct
|
||||
int in_width;
|
||||
int in_height;
|
||||
int in_fmt;
|
||||
|
||||
int orig_width;
|
||||
int orig_height;
|
||||
|
||||
uint8_t *space;
|
||||
conn_type_t **c;
|
||||
int ports[3];
|
||||
int mcast;
|
||||
void *lzo;
|
||||
unsigned char *blob;
|
||||
|
||||
void *r;
|
||||
void *s;
|
||||
|
||||
void *fd[2];
|
||||
int ports[2];
|
||||
} vj_client;
|
||||
|
||||
int vj_client_link_can_write(vj_client *v, int s);
|
||||
@@ -50,8 +50,6 @@ int vj_client_link_can_read(vj_client *v,int s );
|
||||
|
||||
int vj_client_connect( vj_client *v, char *host, char *group_name, int port_id );
|
||||
|
||||
int vj_client_get_status_fd(vj_client *v, int sock_type );
|
||||
|
||||
void vj_client_flush( vj_client *v, int delay );
|
||||
|
||||
int vj_client_poll( vj_client *v, int sock_type );
|
||||
@@ -62,9 +60,11 @@ int vj_client_read( vj_client *v, int sock_type, uint8_t *dst, int bytes );
|
||||
|
||||
int vj_client_read_no_wait( vj_client *v, int sock_type, uint8_t *dst, int bytes );
|
||||
|
||||
int vj_client_close( vj_client *v );
|
||||
void vj_client_close( vj_client *v );
|
||||
|
||||
int vj_client_send( vj_client *v, int sock_type, char *buf);
|
||||
int vj_client_send( vj_client *v, int sock_type,unsigned char *buf);
|
||||
|
||||
int vj_client_send_buf( vj_client *v, int sock_type,unsigned char *buf, int len);
|
||||
|
||||
vj_client *vj_client_alloc(int w , int h, int f);
|
||||
|
||||
@@ -72,12 +72,9 @@ void vj_client_free(vj_client *v);
|
||||
|
||||
int vj_client_test(char *addr, int port );
|
||||
|
||||
int vj_client_send_bufX(vj_client *v, int sock_type,unsigned char *buf, int len );
|
||||
|
||||
int vj_client_window_sizes( int socket_fd, int *r, int *s );
|
||||
|
||||
int vj_client_connect_dat(vj_client *v, char *host, int port_id );
|
||||
|
||||
int vj_client_setup_timeout( vj_client *v, int sock_type, int timeout );
|
||||
#endif
|
||||
|
||||
|
||||
@@ -704,84 +704,58 @@ static int _vj_verify_msg(vj_server *vje,int link_id, char *buf, int buf_len )
|
||||
int i = 0;
|
||||
char *s = buf;
|
||||
int num_msg = 0;
|
||||
//vj_link **Link = (vj_link**) vje->link;
|
||||
|
||||
if( (i+4) > buf_len )
|
||||
if( buf_len < 5 )
|
||||
{
|
||||
_vj_malfunction("VIMS (v) Message too small", buf, buf_len, i );
|
||||
return 0;
|
||||
}
|
||||
|
||||
while( (i+4) < buf_len )
|
||||
while( i < buf_len )
|
||||
{
|
||||
if( !(s[i]=='V' && s[i+4] == 'D') )
|
||||
{
|
||||
if(s[i] != 'K')
|
||||
if( !(s[i]=='V' && s[i+4] == 'D') && !(s[i] == 'K') )
|
||||
{
|
||||
_vj_malfunction( "VIMS (v) Cannot identify message as VIMS message", buf, buf_len, i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( s[i] != 'K' )
|
||||
if( s[i] == 'V' )
|
||||
{
|
||||
char tmp_len[4];
|
||||
char net_id[4];
|
||||
int slen = 0;
|
||||
int netid = 0;
|
||||
|
||||
bzero(tmp_len,4);
|
||||
bzero(net_id,4 );
|
||||
|
||||
char *str_ptr = &s[i];
|
||||
str_ptr ++; // skip 'V'
|
||||
char *str_ptr = &s[(i+1)];
|
||||
|
||||
veejay_strncpy( tmp_len,str_ptr, 3 ); // header length
|
||||
|
||||
if( sscanf(tmp_len, "%03d", &slen) <= 0 )
|
||||
{
|
||||
_vj_malfunction( "VIMS (v) Cannot read header length", buf, buf_len, i + 1);
|
||||
return 0;
|
||||
}
|
||||
if( slen > buf_len )
|
||||
{
|
||||
char msg[256];
|
||||
veejay_memset(msg,0,256);
|
||||
snprintf(msg, 256,"VIMS (v) Remote %s is sending corrupted packets", (char*) (inet_ntoa( vje->remote.sin_addr ) ) );
|
||||
_vj_malfunction( NULL, buf, buf_len, i + 1 );
|
||||
vj_server_close_connection( vje, link_id );
|
||||
return 0;
|
||||
}
|
||||
if ( slen > 999 )
|
||||
{
|
||||
char msg[256];
|
||||
veejay_memset(msg,0,256);
|
||||
snprintf(msg, 256, "VIMS (v) Remote %s is acting very suspiciously", (char* )( inet_ntoa( vje->remote.sin_addr ) ));
|
||||
_vj_malfunction( msg, buf, buf_len, i + 1);
|
||||
vj_server_close_connection( vje, link_id );
|
||||
return 0;
|
||||
}
|
||||
int slen = atoi( tmp_len );
|
||||
|
||||
i += 4; // advance to message content
|
||||
str_ptr += 4;
|
||||
|
||||
veejay_strncpy( net_id, str_ptr, 3 );
|
||||
|
||||
int netid = 0;
|
||||
if( sscanf( net_id, "%03d", &netid ) <= 0 )
|
||||
{
|
||||
_vj_malfunction( "VIMS (v) Corrupt VIMS selector", buf, buf_len, i );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( netid < 0 && netid > 600 )
|
||||
{
|
||||
_vj_malfunction( "VIMS (v) selector out of range", buf,buf_len, i );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( vje->use_mcast )
|
||||
{
|
||||
if( netid >= 400 && netid < 500 )
|
||||
{
|
||||
_vj_malfunction( "VIMS (v) multicast doesnt allow querying of data",buf,buf_len,i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//FIXME: malformed endings
|
||||
int last_char = slen - 1;
|
||||
int failed = 1;
|
||||
if( last_char > 1 )
|
||||
@@ -791,20 +765,21 @@ static int _vj_verify_msg(vj_server *vje,int link_id, char *buf, int buf_len )
|
||||
failed = 0;
|
||||
else if(str_ptr[last_char] == ';' )
|
||||
failed = 0;
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
num_msg ++;
|
||||
i += slen + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(failed)
|
||||
{
|
||||
_vj_malfunction("VIMS (v) message does not end with ';'", buf, buf_len , i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else if( s[i] == 'K' ) {
|
||||
int len = 0;
|
||||
char *str_ptr = &s[i];
|
||||
|
||||
@@ -812,22 +787,24 @@ static int _vj_verify_msg(vj_server *vje,int link_id, char *buf, int buf_len )
|
||||
{
|
||||
i += len;
|
||||
num_msg ++;
|
||||
return num_msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
_vj_malfunction("VIMS (v) keyframe packet length not set", str_ptr, buf_len, i );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(num_msg > 0 )
|
||||
return num_msg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
veejay_msg(0, "parse error.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int _vj_parse_msg(vj_server *vje,int link_id, char *buf, int buf_len, int priority )
|
||||
return num_msg;
|
||||
}
|
||||
|
||||
|
||||
static int _vj_parse_msg(vj_server *vje,int link_id, char *buf, int buf_len )
|
||||
{
|
||||
int i = 0;
|
||||
char *s = buf;
|
||||
@@ -835,20 +812,19 @@ static int _vj_parse_msg(vj_server *vje,int link_id, char *buf, int buf_len, in
|
||||
vj_link **Link = (vj_link**) vje->link;
|
||||
vj_message **v = Link[link_id]->m_queue;
|
||||
|
||||
while( (i+4) < buf_len )
|
||||
{
|
||||
while( i < buf_len ) {
|
||||
|
||||
char tmp_len[8];
|
||||
char net_id[4];
|
||||
int slen = 0;
|
||||
int netid = 0;
|
||||
bzero(tmp_len,8);
|
||||
bzero(net_id,4 );
|
||||
|
||||
char *str_ptr = &s[i];
|
||||
|
||||
if(s[i] == 'V')
|
||||
{
|
||||
str_ptr ++;
|
||||
str_ptr ++; //@ [V][ ]
|
||||
//@ ^
|
||||
|
||||
veejay_strncpy( tmp_len,str_ptr, 3 ); // header length
|
||||
if( sscanf(tmp_len, "%03d", &slen) <= 0 )
|
||||
@@ -856,46 +832,22 @@ static int _vj_parse_msg(vj_server *vje,int link_id, char *buf, int buf_len, in
|
||||
veejay_msg(0, "Error parsing header in '%s' (%d bytes)", buf, buf_len );
|
||||
return 0;
|
||||
}
|
||||
i += 4; // advance to message content
|
||||
str_ptr += 4;
|
||||
veejay_strncpy( net_id, str_ptr, 3 );
|
||||
|
||||
if( sscanf( net_id, "%03d", &netid ) <= 0 )
|
||||
str_ptr += 4; //@ [V][0][0][5][D][ ]
|
||||
//@ ^
|
||||
|
||||
veejay_strncpy( net_id, str_ptr, 3 ); //@ [V][0][0][5][D][6][0][0][:][;]
|
||||
//@ ^ ^ ^
|
||||
|
||||
if( sscanf( net_id, "%03d", &netid ) )
|
||||
{
|
||||
if( strncasecmp(net_id, "key",3) != 0 )
|
||||
{
|
||||
veejay_msg(0, "Error parsing VIMS ID in '%s' (%d bytes)",buf,buf_len);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[num_msg]->msg = (char*) vj_malloc( slen );
|
||||
veejay_memcpy( v[num_msg]->msg, str_ptr, slen );
|
||||
v[num_msg]->len = slen;
|
||||
v[num_msg]->msg = strndup( str_ptr, slen ); //@ '600:;'
|
||||
v[num_msg]->len = slen; //@ 5
|
||||
#ifdef STRICT_CHECKING
|
||||
assert( slen == strlen( v[num_msg]->msg ) );
|
||||
#endif
|
||||
num_msg++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(! priority )
|
||||
{
|
||||
// store message anyway
|
||||
int n_len = slen;
|
||||
v[num_msg]->msg = (char*)strndup( str_ptr , slen );
|
||||
veejay_chomp_str( v[num_msg]->msg , &n_len );
|
||||
v[num_msg]->len = n_len;
|
||||
num_msg++;
|
||||
}
|
||||
if(priority && netid > 255 )
|
||||
{
|
||||
// store high priority only (reduce load) -
|
||||
int n_len = slen;
|
||||
v[num_msg]->msg = (char*)strndup( str_ptr , slen );
|
||||
veejay_chomp_str( v[num_msg]->msg, &n_len );
|
||||
v[num_msg]->len = n_len;
|
||||
num_msg++;
|
||||
}
|
||||
}
|
||||
|
||||
if(num_msg >= (VJ_MAX_PENDING_MSG-1) )
|
||||
{
|
||||
@@ -903,37 +855,41 @@ static int _vj_parse_msg(vj_server *vje,int link_id, char *buf, int buf_len, in
|
||||
num_msg,VJ_MAX_PENDING_MSG );
|
||||
return VJ_MAX_PENDING_MSG-1; // cant take more
|
||||
}
|
||||
// i += slen;
|
||||
i += (slen+1); // try next message
|
||||
|
||||
i += ( 5 + slen);
|
||||
|
||||
}
|
||||
else if (s[i] == 'K' )
|
||||
{
|
||||
str_ptr ++;
|
||||
veejay_memcpy( tmp_len,str_ptr, 8 );
|
||||
str_ptr ++; //@ '[K][ ]
|
||||
//@ ^
|
||||
|
||||
veejay_strncpy( tmp_len, str_ptr, 8 );
|
||||
|
||||
if( sscanf(tmp_len, "%08d", &slen) <= 0 )
|
||||
{
|
||||
veejay_msg(0, "Error parsing KF header in '%s' (%d bytes)", buf, buf_len );
|
||||
return 0;
|
||||
}
|
||||
|
||||
i += 8; // advance to message content
|
||||
str_ptr += 8;
|
||||
str_ptr += 8; // '[K][0][0][0][0][0][0][2][5][ ]'
|
||||
//@ ^
|
||||
|
||||
v[num_msg]->msg = (char*) vj_calloc( slen );
|
||||
veejay_memcpy( v[num_msg]->msg, str_ptr, slen );
|
||||
v[num_msg]->msg = strndup( str_ptr, slen );
|
||||
v[num_msg]->len = slen;
|
||||
num_msg++;
|
||||
|
||||
i += slen;
|
||||
i += ( 8 + slen + 1);
|
||||
} else {
|
||||
veejay_msg(0, "VIMS: blob '%s' not recognized. First token must be either 'V' or 'K' followed by packet length.",
|
||||
str_ptr );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( ! priority )
|
||||
{
|
||||
Link[link_id]->n_queued = num_msg;
|
||||
Link[link_id]->n_retrieved = 0;
|
||||
}
|
||||
|
||||
return num_msg;
|
||||
}
|
||||
|
||||
@@ -1056,7 +1012,7 @@ int vj_server_update( vj_server *vje, int id )
|
||||
|
||||
if( n_msg < VJ_MAX_PENDING_MSG )
|
||||
{
|
||||
int nn = _vj_parse_msg( vje, id, msg_buf, bytes_left,0 );
|
||||
int nn = _vj_parse_msg( vje, id, msg_buf, bytes_left );
|
||||
if(nn != n_msg)
|
||||
{
|
||||
veejay_msg(VEEJAY_MSG_ERROR, "Veejay's message queue corrupted (end session!)");
|
||||
|
||||
@@ -308,12 +308,8 @@ enum {
|
||||
|
||||
#define MAX_EDIT_LIST_FILES 4096
|
||||
|
||||
#define VSOCK_S 0
|
||||
#define VSOCK_C 1
|
||||
#define V_STATUS 0
|
||||
#define V_CMD 1
|
||||
#define VMCAST_S 4
|
||||
#define VMCAST_C 5
|
||||
#define V_STATUS 1
|
||||
#define V_CMD 0
|
||||
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -2731,8 +2731,7 @@ void vj_event_quit(void *ptr, const char format[], va_list ap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
veejay_change_state(v, LAVPLAY_STATE_STOP);
|
||||
veejay_quit(v);
|
||||
}
|
||||
|
||||
void vj_event_sample_mode(void *ptr, const char format[], va_list ap)
|
||||
|
||||
Reference in New Issue
Block a user