diff --git a/veejay-current/veejay-server/libstream/vj-net.c b/veejay-current/veejay-server/libstream/vj-net.c index 7cbc3135..1042a82f 100644 --- a/veejay-current/veejay-server/libstream/vj-net.c +++ b/veejay-current/veejay-server/libstream/vj-net.c @@ -147,13 +147,49 @@ void *reader_thread(void *data) if(!error && retrieve == 2) { - lock(t); - t->buf = vj_client_read_i( v, t->buf,&(t->bufsize), &ret ); + int ret = 0; + int strides[3] = { 0,0,0}; + int compr_len = 0; + + if( vj_client_read_frame_header( v, &(t->in_w), &(t->in_h), &(t->in_fmt), &compr_len, &strides[0],&strides[1],&strides[2]) == 0 ) { + error = 1; + } + + if(!error) { + int need_rlock = 0; + if( compr_len <= 0 ) + need_rlock = 1; + + if( need_rlock ) { + lock(t); + } + + if( t->bufsize < (t->in_w * t->in_h * 3) || t->buf == NULL ) { + t->bufsize = t->in_w * t->in_h * 3; + t->buf = (uint8_t*) realloc( t->buf, RUP8(t->bufsize)); + } + + ret = vj_client_read_frame_data( v, compr_len, strides[0], strides[1], strides[2], t->buf ); + if( ret == 2 ) { + if(!need_rlock) { + lock(t); + vj_client_decompress_frame_data( v, t->buf, t->in_fmt, t->in_w, t->in_h, compr_len, strides[0],strides[1],strides[2] ); + unlock(t); + } + } + + if( need_rlock ) { + unlock(t); + } + } + + // lock(t); + //t->buf = vj_client_read_i( v, t->buf,&(t->bufsize), &ret ); if(ret && t->buf) { t->have_frame = 1; - t->in_fmt = v->in_fmt; - t->in_w = v->in_width; - t->in_h = v->in_height; + t->in_fmt = v->in_fmt; + t->in_w = v->in_width; + t->in_h = v->in_height; retrieve = 0; } if( ret <= 0 || t->buf == NULL ) { @@ -163,7 +199,7 @@ void *reader_thread(void *data) error = 1; } } - unlock(t); + // unlock(t); } NETTHREADRETRY: @@ -259,43 +295,25 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] ) have_frame = t->have_frame; state = t->state; - if( state == 0 || have_frame == 0 || t->bufsize == 0 || t->buf == NULL ) { + if( state == 0 || t->bufsize == 0 || t->buf == NULL ) { unlock(t); return 1; // not active or no frame - } + } // just continue when t->have_frame == 0 //@ color space convert frame - int len = t->w * t->h; int b_len = t->in_w * t->in_h; int buvlen = b_len; - if( (b_len*3) > tag->socket_len ) { - tag->socket_frame = - (uint8_t*) realloc( tag->socket_frame, RUP8(b_len*3) ); - tag->socket_len = b_len*3; - } - - if( t->in_fmt == PIX_FMT_RGB24 || t->in_fmt == PIX_FMT_BGR24 || t->in_fmt == PIX_FMT_RGBA || t->in_fmt == PIX_FMT_RGB32_1 ) { - - if(t->a == NULL ) - t->a = yuv_rgb_template( tag->socket_frame, t->in_w, t->in_w, t->in_fmt ); + if( PIX_FMT_YUV420P == t->in_fmt || PIX_FMT_YUVJ420P == t->in_fmt ) + buvlen = b_len/4; + else + buvlen = b_len/2; - } else { + if( t->a == NULL ) + t->a = yuv_yuv_template( t->buf, t->buf + b_len, t->buf+ b_len+ buvlen,t->in_w,t->in_h, t->in_fmt); - if( t->b == NULL ) { - if( PIX_FMT_YUV420P == t->in_fmt || PIX_FMT_YUVJ420P == t->in_fmt ) - buvlen = b_len/4; - else - buvlen = b_len/2; - - t->a = yuv_yuv_template( t->buf, t->buf + b_len, t->buf+ b_len+ buvlen,t->in_w,t->in_h, t->in_fmt); - } - } - - if( t->b == NULL ) { + if( t->b == NULL ) t->b = yuv_yuv_template( buffer[0],buffer[1], buffer[2],t->w,t->h,t->f); - } - if( t->scaler == NULL ) { sws_template sws_templ; @@ -312,56 +330,6 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] ) return 1; } -int net_thread_get_frame_rgb( vj_tag *tag, uint8_t *buffer, int w, int h ) -{ - threaded_t *t = (threaded_t*) tag->priv; - - int have_frame = 0; - int state = 0; - - lock(t); - have_frame = t->have_frame; - state= t->state; - if( state == 0 || have_frame == 0 ) { - unlock(t); - return 1; - } - - int len = t->w * t->h; - int uv_len = len; - int b_len = t->in_w * t->in_h; - int buvlen = b_len; - - - if( PIX_FMT_YUV420P == t->f || PIX_FMT_YUVJ420P == t->f ) - uv_len = len/4; - else - uv_len = len/2; - - - if(t->have_frame ) - { - if( PIX_FMT_YUV420P == t->in_fmt || PIX_FMT_YUVJ420P == t->in_fmt ) - buvlen = b_len/4; - else - buvlen = b_len/2; - - if( t->a == NULL ) { - t->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); - } - if( t->b == NULL ) { - t->b = yuv_rgb_template( buffer,w,h,PIX_FMT_RGB24); - } - - yuv_convert_any_ac(t->a,t->b, t->a->format,t->b->format ); - } - - unlock(t); - - return 1; -} - - int net_thread_start(vj_tag *tag, int wid, int height, int pixelformat) { if(tag->source_type == VJ_TAG_TYPE_MCAST ) { diff --git a/veejay-current/veejay-server/libstream/vj-net.h b/veejay-current/veejay-server/libstream/vj-net.h index 5e17a14c..fe4c7831 100644 --- a/veejay-current/veejay-server/libstream/vj-net.h +++ b/veejay-current/veejay-server/libstream/vj-net.h @@ -25,7 +25,6 @@ void net_thread_stop(vj_tag *tag); int net_thread_start(vj_tag *tag, int w, int h, int f); void net_thread_remote(void *priv, void *p ); int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3]); -int net_thread_get_frame_rgb( vj_tag *tag, uint8_t *buffer, int w, int h); void net_thread_exit(vj_tag *tag); void *net_threader(VJFrame *frame); diff --git a/veejay-current/veejay-server/libvjnet/vj-client.c b/veejay-current/veejay-server/libvjnet/vj-client.c index d6c06b71..45e77bab 100644 --- a/veejay-current/veejay-server/libvjnet/vj-client.c +++ b/veejay-current/veejay-server/libvjnet/vj-client.c @@ -232,14 +232,6 @@ static long vj_client_decompress( vj_client *t,uint8_t *in, uint8_t *out, int da return total; } -static uint32_t getint(uint8_t *in, int len ) { - char *ptr, *word = strndup( in, len+1 ); - word[len] = '\0'; - long v = strtol( word, &ptr, 10 ); - free(word); - return (uint32_t) v; -} - /* packet negotation. * read a small portion (44 bytes for veejay, its veejay's full header size) * and try to identify which software is sending frames @@ -288,6 +280,111 @@ static int vj_client_packet_negotiate( vj_client *v, int *tokens ) return 1; } +int vj_client_read_frame_header( vj_client *v, int *w, int *h, int *fmt, int *compr_len, int *stride1,int *stride2, int *stride3 ) +{ + uint8_t line[128]; + uint32_t p[4] = {0, 0,0,0 }; + uint32_t strides[4] = { 0,0,0,0 }; + + int tokens[16]; + + memset( tokens,0,sizeof(tokens)); + + int result = vj_client_packet_negotiate( v, tokens ); + if( result == 0 ) { + return 0; + } + + if( tokens[0] <= 0 || tokens[1] <= 0 ) { + return 0; + } + + *w = tokens[0]; + *h = tokens[1]; + *fmt=tokens[2]; + *compr_len=tokens[3]; + *stride1=tokens[4]; + *stride2=tokens[5]; + *stride3=tokens[6]; + v->in_width = *w; + v->in_height = *h; + v->in_fmt = *fmt; + + return 1; +} + +int vj_client_read_frame_data( vj_client *v, int compr_len, int stride1,int stride2, int stride3, uint8_t *dst ) +{ + int datalen = (compr_len > 0 ? compr_len : stride1+stride2+stride3); + if( (compr_len > 0) && ( v->space == NULL || v->space_len < compr_len) ) { + if( v->space ) { + free(v->space); + v->space = NULL; + } + v->space_len = RUP8( compr_len ); + v->space = vj_calloc(sizeof(uint8_t) * v->space_len ); + if(!v->space) { + veejay_msg(0,"Could not allocate memory for network stream."); + return 0; + } + } + + if( compr_len > 0 ) { + int n = sock_t_recv( v->fd[0],v->space,datalen ); + if( n <= 0 ) { + if( n == -1 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Error '%s' while reading socket", strerror(errno)); + } else { + veejay_msg(VEEJAY_MSG_DEBUG,"Remote closed connection"); + } + return 0; + } + + if( n != compr_len && n > 0 ) + { + veejay_msg(VEEJAY_MSG_ERROR, "Broken video packet , got %d out of %d bytes",n, compr_len ); + return 0; + } + + return 2; + } + else { + int n = sock_t_recv( v->fd[0], dst, datalen ); + if( n != (stride1 + stride2 + stride3) ) + { + return 0; + } + + return 1; + } + return 0; +} + +void vj_client_decompress_frame_data( vj_client *v, uint8_t *dst, int fmt, int w, int h, int compr_len, int stride1, int stride2, int stride3 ) +{ + int y_len = w * h; + int uv_len = 0; + switch(fmt) //@ veejay is sending compressed YUV data, calculate UV size + { + case PIX_FMT_YUV422P: + case PIX_FMT_YUVJ422P: + uv_len = y_len / 2; + break; + case PIX_FMT_YUV420P: + case PIX_FMT_YUVJ420P: + uv_len = y_len / 4; + break; + default: + uv_len = y_len; + break; + } + + + //@ decompress YUV buffer + vj_client_decompress( v, v->space, dst, compr_len, y_len, uv_len ,0, stride1,stride2,stride3); +} + + uint8_t *vj_client_read_i( vj_client *v, uint8_t *dst, ssize_t *dstlen, int *ret ) { diff --git a/veejay-current/veejay-server/libvjnet/vj-client.h b/veejay-current/veejay-server/libvjnet/vj-client.h index 59d1ee21..fefa4be4 100644 --- a/veejay-current/veejay-server/libvjnet/vj-client.h +++ b/veejay-current/veejay-server/libvjnet/vj-client.h @@ -78,5 +78,12 @@ 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 ); + +void vj_client_decompress_frame_data( vj_client *v, uint8_t *dst, int fmt, int w, int h, int compr_len, int stride1, int stride2, int stride3 ); + +int vj_client_read_frame_data( vj_client *v, int compr_len, int stride1,int stride2, int stride3, uint8_t *dst ); + +int vj_client_read_frame_header( vj_client *v, int *w, int *h, int *fmt, int *compr_len, int *stride1,int *stride2, int *stride3 ); + #endif