From c02f419bedbaaf9c04ff377a331092c0954a18bc Mon Sep 17 00:00:00 2001 From: Niels Elburg Date: Sun, 5 Apr 2009 16:57:25 +0000 Subject: [PATCH] added support for multicasting video in grayscale, rewrote mcast receiver routine to propery deal with late packets (fix corrupted compressed stream) git-svn-id: svn://code.dyne.org/veejay/trunk@1326 eb8d1916-c9e9-0310-b8de-cf0c9472ead5 --- veejay-current/veejay-server/libel/vj-el.c | 2 +- veejay-current/veejay-server/liblzo/lzo.c | 63 +++-- veejay-current/veejay-server/liblzo/lzo.h | 2 +- .../veejay-server/libstream/vj-net.c | 8 +- .../veejay-server/libstream/vj-tag.c | 2 - .../veejay-server/libvjnet/mcastreceiver.c | 217 +++++++----------- .../veejay-server/libvjnet/mcastsender.c | 4 +- .../veejay-server/libvjnet/mcastsender.h | 2 +- .../veejay-server/libvjnet/packet.h | 3 +- .../veejay-server/libvjnet/vj-client.c | 13 +- .../veejay-server/libvjnet/vj-client.h | 1 - .../veejay-server/libvjnet/vj-server.c | 8 +- .../veejay-server/libvjnet/vj-server.h | 2 + .../veejay-server/veejay/vj-event.c | 13 +- .../veejay-server/veejay/vj-eventman.c | 6 +- veejay-current/veejay-server/veejay/vj-lib.h | 1 + .../veejay-server/veejay/vj-perform.c | 16 +- 17 files changed, 171 insertions(+), 192 deletions(-) diff --git a/veejay-current/veejay-server/libel/vj-el.c b/veejay-current/veejay-server/libel/vj-el.c index 0edce704..db41dfde 100644 --- a/veejay-current/veejay-server/libel/vj-el.c +++ b/veejay-current/veejay-server/libel/vj-el.c @@ -1210,7 +1210,7 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) inter = lzo_decompress420into422(d->lzo_decoder, data,res,dst, el->video_width,el->video_height ); } else { - inter = lzo_decompress( d->lzo_decoder, data,res, dst); + inter = lzo_decompress( d->lzo_decoder, data,res, dst,el->video_width*el->video_height); } return inter; diff --git a/veejay-current/veejay-server/liblzo/lzo.c b/veejay-current/veejay-server/liblzo/lzo.c index 488891b5..a9ac1d18 100644 --- a/veejay-current/veejay-server/liblzo/lzo.c +++ b/veejay-current/veejay-server/liblzo/lzo.c @@ -63,7 +63,7 @@ void *lzo_new( ) } l->wrkmem = (lzo_bytep) - vj_malloc( LZO1X_1_MEM_COMPRESS ); + vj_malloc( 2 * LZO1X_1_MEM_COMPRESS ); if(l->wrkmem == NULL ) { @@ -100,10 +100,11 @@ int lzo_compress( void *lzo, uint8_t *src, uint8_t *plane, unsigned int *size, return (*size); } -long lzo_decompress( void *lzo, uint8_t *linbuf, int linbuf_len, uint8_t *dst[3] ) +long lzo_decompress( void *lzo, uint8_t *linbuf, int linbuf_len, uint8_t *dst[3], int uv_len ) { int i; lzo_uint len[3] = { 0,0,0}; + int mode = 0; int sum = 0; lzot *l = (lzot*) lzo; lzo_uint result_len = 0; @@ -112,19 +113,29 @@ long lzo_decompress( void *lzo, uint8_t *linbuf, int linbuf_len, uint8_t *dst[3 len[0] = str2ulong( linbuf ); len[1] = str2ulong( linbuf+4 ); len[2] = str2ulong( linbuf+8 ); -#ifdef STRICT_CHECKING - assert( len[0] > 0 && len[1] > 0 && len[2] > 0 ); -#endif + mode = str2ulong( linbuf+12 ); + + if(len[1] ==0 && len[2] == 0 ) + mode = 1; for( i = 0; i <= 2; i ++ ) { - const lzo_bytep src = (lzo_bytep) (linbuf+12+offset); + if( len[i] <= 0 ) + continue; + + const lzo_bytep src = (lzo_bytep) (linbuf+16+offset); int r = lzo1x_decompress( src, len[i], dst[i], &result_len, l->wrkmem ); if( r != LZO_E_OK ) return 0; sum += result_len; offset += len[i]; } + + if(mode == 1) { + veejay_memset( dst[1],128, uv_len ); + veejay_memset( dst[2],128, uv_len ); + } + return (long)sum; } @@ -133,6 +144,7 @@ long lzo_decompress422into420( void *lzo, uint8_t *linbuf, int linbuf_len, uint int i; lzo_uint len[3] = { 0,0,0}; int sum = 0; + int mode = 0; lzot *l = (lzot*) lzo; lzo_uint result_len = 0; lzo_uint offset = 0; @@ -140,7 +152,7 @@ long lzo_decompress422into420( void *lzo, uint8_t *linbuf, int linbuf_len, uint len[0] = str2ulong( linbuf ); len[1] = str2ulong( linbuf+4 ); len[2] = str2ulong( linbuf+8 ); -veejay_msg(0,"%s",__FUNCTION__); + mode = str2ulong( linbuf+12 ); if( l->tmp[0] == NULL ) { l->tmp[0] = vj_malloc(sizeof(uint8_t) * w * h * 3); // will do @@ -148,13 +160,12 @@ veejay_msg(0,"%s",__FUNCTION__); l->tmp[2] = l->tmp[1] + ( (w>>1)*h); } -#ifdef STRICT_CHECKING - assert( len[0] > 0 && len[1] > 0 && len[2] > 0 ); -#endif - for( i = 0; i <= 2; i ++ ) { - const lzo_bytep src = (lzo_bytep) (linbuf+12+offset); + if(len[i] <= 0) + continue; + + const lzo_bytep src = (lzo_bytep) (linbuf+16+offset); int r = lzo1x_decompress( src, len[i], l->tmp[i], &result_len, l->wrkmem ); if( r != LZO_E_OK ) return 0; @@ -163,8 +174,12 @@ veejay_msg(0,"%s",__FUNCTION__); } veejay_memcpy( dst[0], l->tmp[0], w*h); - yuv422to420planar( l->tmp, dst, w, h ); - + if( mode == 1 ) { + veejay_memset(dst[1],128,( (w>>1)*h)); + veejay_memset(dst[2],128,( (w>>1)*h)); + } else { + yuv422to420planar( l->tmp, dst, w, h ); + } return (long)sum; } long lzo_decompress420into422( void *lzo, uint8_t *linbuf, int linbuf_len, uint8_t *dst[3], int w, int h ) @@ -172,14 +187,15 @@ long lzo_decompress420into422( void *lzo, uint8_t *linbuf, int linbuf_len, uint int i; lzo_uint len[3] = { 0,0,0}; int sum = 0; + int mode= 0; lzot *l = (lzot*) lzo; lzo_uint result_len = 0; lzo_uint offset = 0; - veejay_msg(0,"%s",__FUNCTION__); len[0] = str2ulong( linbuf ); len[1] = str2ulong( linbuf+4 ); len[2] = str2ulong( linbuf+8 ); + mode = str2ulong( linbuf+12 ); if( l->tmp[0] == NULL ) { l->tmp[0] = vj_malloc(sizeof(uint8_t) * w * h * 3); // will do @@ -187,13 +203,11 @@ long lzo_decompress420into422( void *lzo, uint8_t *linbuf, int linbuf_len, uint l->tmp[2] = l->tmp[1] + ( (w>>1) * (h>>1)); } -#ifdef STRICT_CHECKING - assert( len[0] > 0 && len[1] > 0 && len[2] > 0 ); -#endif - for( i = 0; i <= 2; i ++ ) { - const lzo_bytep src = (lzo_bytep) (linbuf+12+offset); + if( len[i] <= 0 ) + continue; + const lzo_bytep src = (lzo_bytep) (linbuf+16+offset); int r = lzo1x_decompress( src, len[i], l->tmp[i], &result_len, l->wrkmem ); if( r != LZO_E_OK ) return 0; @@ -201,8 +215,13 @@ long lzo_decompress420into422( void *lzo, uint8_t *linbuf, int linbuf_len, uint offset += len[i]; } veejay_memcpy( dst[0], l->tmp[0], w*h); - - yuv420to422planar( l->tmp, dst, w, h ); + if(mode == 1) { + veejay_memset(dst[1],128,( (w>>1)*h)); + veejay_memset(dst[2],128,( (w>>1)*h)); + } + else { + yuv420to422planar( l->tmp, dst, w, h ); + } return (long)sum; } diff --git a/veejay-current/veejay-server/liblzo/lzo.h b/veejay-current/veejay-server/liblzo/lzo.h index 3b3c5723..6c826434 100644 --- a/veejay-current/veejay-server/liblzo/lzo.h +++ b/veejay-current/veejay-server/liblzo/lzo.h @@ -32,6 +32,6 @@ long lzo_decompress420into422( void *lzo, uint8_t *linbuf, int linbuf_len, uint long lzo_decompress2( void *lzo, uint8_t *linbuf, int linbuf_len, uint8_t *dst ); -long lzo_decompress( void *lzo, uint8_t *linbuf, int linbuf_len,uint8_t *dst[3] ); +long lzo_decompress( void *lzo, uint8_t *linbuf, int linbuf_len,uint8_t *dst[3], int uv_len ); #endif diff --git a/veejay-current/veejay-server/libstream/vj-net.c b/veejay-current/veejay-server/libstream/vj-net.c index 692d63bd..e07f3ae9 100644 --- a/veejay-current/veejay-server/libstream/vj-net.c +++ b/veejay-current/veejay-server/libstream/vj-net.c @@ -162,7 +162,7 @@ void *reader_thread(void *data) if( wait_time ) { if ( wait_time > 40 ) - wait_time = 25; + wait_time = 15; net_delay( wait_time ); // usleep(wait_time); } @@ -241,9 +241,11 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] ) buvlen = b_len/2; break; } - + + int tmp_fmt = get_ffmpeg_pixfmt( v->in_fmt ); + VJFrame *a = yuv_yuv_template( tag->socket_frame, tag->socket_frame + b_len, tag->socket_frame+b_len+buvlen, - v->in_width,v->in_height, get_ffmpeg_pixfmt( v->in_fmt )); + v->in_width,v->in_height, tmp_fmt); VJFrame *b = yuv_yuv_template( buffer[0],buffer[1], buffer[2], v->cur_width,v->cur_height,get_ffmpeg_pixfmt(v->cur_fmt)); yuv_convert_any_ac(a,b, a->format,b->format ); diff --git a/veejay-current/veejay-server/libstream/vj-tag.c b/veejay-current/veejay-server/libstream/vj-tag.c index 31985e7b..f10e5565 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.c +++ b/veejay-current/veejay-server/libstream/vj-tag.c @@ -271,8 +271,6 @@ void vj_tag_record_init(int w, int h) { } - - int _vj_tag_new_net(vj_tag *tag, int stream_nr, int w, int h,int f, char *host, int port, int p, int type ) { vj_client *v; diff --git a/veejay-current/veejay-server/libvjnet/mcastreceiver.c b/veejay-current/veejay-server/libvjnet/mcastreceiver.c index adc10caf..99e31f54 100644 --- a/veejay-current/veejay-server/libvjnet/mcastreceiver.c +++ b/veejay-current/veejay-server/libvjnet/mcastreceiver.c @@ -82,7 +82,7 @@ static void mcast_packet_buffer_release( void *dat ) if(pb->packets) free(pb->packets); free(pb); } - pb = NULL; + dat = NULL; } static int mcast_packet_buffer_next( void *dat, packet_header_t *hdr ) @@ -278,168 +278,107 @@ if( res == -1)\ int mcast_recv_frame( mcast_receiver *v, uint8_t *linear_buf, int total_len, int cw, int ch, int cfmt, int *dw, int *dh, int *dfmt ) { - uint32_t sec,usec; - int i=0; - int tb=0; uint8_t chunk[PACKET_PAYLOAD_SIZE]; packet_header_t header; frame_info_t info; - - veejay_memset(&header,0,sizeof(packet_header_t)); - int res = 0; - int n_packet = 0; - int total_recv = 0; - int packet_len = CHUNK_SIZE; - int nos =0; + int queue = 0; + int work_done = 0; - if( mcast_poll_timeout( v, header.timeout ) == 0 ) + if( mcast_poll_timeout( v, 1000 ) == 0 ) { return 0; } packet_buffer_t *queued_packets = (packet_buffer_t*) v->next; - while( total_recv < packet_len ) - { - int put_data = 1; - res = recv(v->sock_fd, chunk, PACKET_PAYLOAD_SIZE, MSG_PEEK ); + if( queued_packets != NULL ) { + memcpy(&header, &(queued_packets->hdr), sizeof(packet_header_t)); + memcpy(&info, &(queued_packets->inf), sizeof(frame_info_t)); + queue = 1; + } + else { + res = recv(v->sock_fd, chunk, PACKET_PAYLOAD_SIZE, 0 ); if( res <= 0 ) { veejay_msg(VEEJAY_MSG_ERROR, "Error receiving multicast packet:%s", strerror(errno)); return 0; - } -#ifdef STRICT_CHECKING - assert( res == PACKET_PAYLOAD_SIZE ); -#endif - packet_header_t hdr = packet_get_header( chunk ); - frame_info_t inf; - - packet_get_info(&inf,chunk ); - *dw = info.width; - *dh = info.height; - *dfmt = info.fmt; - -// packet_dump_header( &hdr ); -// packet_dump_info( &inf ); - - if( n_packet == 0 ) // is this the first packet we get? - { - if( queued_packets ) // if there are queued (future) packets, - { - // empty next packet buffer - if( queued_packets->hdr.usec == hdr.usec ) - { - n_packet = mcast_packet_buffer_fill(v->next, &packet_len, linear_buf); - total_recv = n_packet * CHUNK_SIZE; - veejay_memcpy(&header, &(queued_packets->hdr), sizeof(packet_header_t)); - veejay_memcpy(&info, &(queued_packets->inf), sizeof(frame_info_t)); - // veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d dequeuing packet with timestamp %x in next buffer (ts=%x,length=%d,len=%d, packets=%d)", - // __FUNCTION__,__LINE__, hdr.usec, queued_packets->hdr.usec, queued_packets->hdr.length, queued_packets->inf.len, n_packet ); - } - else - { - //@ there are queued packets, but not the expected ones. - //@ destroy packet buffer - // veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d packet with timestamp %x arrived (queued=%x, reset. grab new)", - // __FUNCTION__,__LINE__, hdr.usec, queued_packets->hdr.usec ); - mcast_packet_buffer_release(v->next); - queued_packets = NULL; - v->next = NULL; - packet_len = info.len; - veejay_memcpy( &header,&hdr, sizeof(packet_header_t)); - veejay_memcpy( &info, &inf, sizeof(frame_info_t)); - total_recv = 0; - } - } - else - { - // veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d Queuing first packet %d/%d, data_len=%d", - // __FUNCTION__,__LINE__, n_packet, hdr.length, info.len ); - packet_len = inf.len; - veejay_memcpy(&header,&hdr,sizeof(packet_header_t)); - veejay_memcpy(&info, &inf, sizeof(frame_info_t)); - total_recv = 0; - } } - - - if( header.usec != hdr.usec ) - { - if( hdr.usec < header.usec ) - { - put_data = 0; - veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d dropped packet (too old timestamp %x)", __FUNCTION__,__LINE__,header.usec); - } - else - { - //@ its newer! - // - if(!v->next) // nothing stored yet - { - v->next = mcast_packet_buffer_new( &hdr, &inf, chunk ); + header = packet_get_header(chunk); + packet_get_info( &info, chunk ); + } - // veejay_msg(VEEJAY_MSG_DEBUG,"%s:%d Stored packet with timestamp %x (processing %x)", - // __FUNCTION__,__LINE__, hdr.usec, header.usec ); - - } - else - { - // store packet if next buffer has identical timestamp - if( mcast_packet_buffer_next( v->next, &hdr ) ) - { - // veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d packet buffer STORE future frame (ts=%x)", __FUNCTION__,__LINE__, hdr.usec ); - mcast_packet_buffer_store( v->next, &hdr,chunk ); - put_data = 0; - } - else - { - // release packet buffer and start queueing new frames only - // veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d packet buffer release, storing newest packets",__FUNCTION__,__LINE__ ); - if( mcast_packet_buffer_full( v->next )) - { - n_packet = mcast_packet_buffer_fill(v->next, &packet_len, linear_buf); - total_recv = n_packet * CHUNK_SIZE; - return packet_len; - } + int expected_len = PACKET_PAYLOAD_SIZE * header.length; + int compressed_data_len = 0; + int i; - mcast_packet_buffer_release(v->next); - v->next = NULL; - total_recv = 0; n_packet = 0; packet_len = inf.len; - veejay_memcpy(&header,&hdr,sizeof(packet_header_t)); - put_data = 1; - } - - } - } + if(queue) { + if( mcast_packet_buffer_full( v->next ) ) { + mcast_packet_buffer_fill( v->next, &compressed_data_len, linear_buf ); + mcast_packet_buffer_release(v->next); + return compressed_data_len; } - - dequeue_packet(); - - - if( put_data ) + mcast_packet_buffer_fill(v->next,&compressed_data_len, linear_buf ); + for( i = 0; i < queued_packets->hdr.length; i ++ ) { - uint8_t *dst; - dst = linear_buf + (CHUNK_SIZE * hdr.seq_num ); - packet_get_data( &hdr, chunk, dst ); - total_recv += CHUNK_SIZE; - n_packet ++; + if( queued_packets->packets[i] ) + work_done += PACKET_PAYLOAD_SIZE; } - - if( n_packet >= header.length ) - { - // veejay_msg(VEEJAY_MSG_DEBUG, "%s:%d Have full frame",__FUNCTION__,__LINE__); - break; - } - } -#ifdef STRICT_CHECKING - assert( total_recv >= packet_len ); -#endif - - return packet_len; + *dw = info.width; + *dh = info.height; + *dfmt = info.fmt; + + while( work_done < expected_len ) + { + + uint8_t *dst = NULL; + if(queue == 0 && work_done == 0) { + dst = linear_buf + (CHUNK_SIZE * header.seq_num ); + packet_get_data( &header, chunk, dst ); + work_done += PACKET_PAYLOAD_SIZE; + } + + res = recv(v->sock_fd, chunk, PACKET_PAYLOAD_SIZE, 0 ); + packet_header_t hdr = packet_get_header( chunk ); + frame_info_t inf; + packet_get_info(&inf,chunk ); + if( hdr.usec == header.usec ) { + dst = linear_buf + (CHUNK_SIZE * hdr.seq_num ); + packet_get_data( &hdr, chunk,dst ); + work_done += PACKET_PAYLOAD_SIZE; + compressed_data_len = info.len; + } + else { + if( hdr.usec > header.usec ) { //@ store newer packets for next cycle + if(queue==1) { + veejay_msg(VEEJAY_MSG_WARNING,"Out of pace, can't keep up with network ?! Processing delta is %2.2f sec", + (float) (hdr.usec - header.usec)/40000.0f); + if(v->next) + mcast_packet_buffer_release( v->next ); + return 0; + } else { + if(!v->next) { + v->next = mcast_packet_buffer_new( &hdr, &inf, chunk ); + } + if( mcast_packet_buffer_next( v->next,&hdr ) ) { + mcast_packet_buffer_store(v->next,&hdr,chunk ); + } + if( mcast_packet_buffer_full(v->next)) { + int num_packets_done = mcast_packet_buffer_fill(v->next,&compressed_data_len,linear_buf ); + mcast_packet_buffer_release(v->next); + v->next = NULL; + return compressed_data_len; + } + } + } + + } + } + + return compressed_data_len; } diff --git a/veejay-current/veejay-server/libvjnet/mcastsender.c b/veejay-current/veejay-server/libvjnet/mcastsender.c index ba6b0420..cb0a993b 100644 --- a/veejay-current/veejay-server/libvjnet/mcastsender.c +++ b/veejay-current/veejay-server/libvjnet/mcastsender.c @@ -163,7 +163,7 @@ static uint32_t stamp_make( mcast_sender *v ) } int mcast_send_frame( mcast_sender *v, const VJFrame *frame, - uint8_t *buf, int total_len, long ms,int port_num) + uint8_t *buf, int total_len, long ms,int port_num, int mode) { int n_chunks = total_len / CHUNK_SIZE; int i; @@ -174,7 +174,7 @@ int mcast_send_frame( mcast_sender *v, const VJFrame *frame, info.width = frame->width; info.height = frame->height; info.len = total_len; - + info.mode = mode; uint32_t frame_num = stamp_make(v); header.timeout = ms * 1000; diff --git a/veejay-current/veejay-server/libvjnet/mcastsender.h b/veejay-current/veejay-server/libvjnet/mcastsender.h index ef54000c..d04fbc45 100644 --- a/veejay-current/veejay-server/libvjnet/mcastsender.h +++ b/veejay-current/veejay-server/libvjnet/mcastsender.h @@ -45,7 +45,7 @@ void mcast_set_interface( mcast_sender *s, const char *interface ); int mcast_send( mcast_sender *s, const void *buf, int len, int port_num ); -int mcast_send_frame( mcast_sender *s, const VJFrame *frame , uint8_t *buf, int total_len,long ms, int port_num ); +int mcast_send_frame( mcast_sender *s, const VJFrame *frame , uint8_t *buf, int total_len,long ms, int port_num ,int mode); void mcast_close_sender(mcast_sender *s ); diff --git a/veejay-current/veejay-server/libvjnet/packet.h b/veejay-current/veejay-server/libvjnet/packet.h index 38e2f070..f7928a1e 100644 --- a/veejay-current/veejay-server/libvjnet/packet.h +++ b/veejay-current/veejay-server/libvjnet/packet.h @@ -49,12 +49,13 @@ typedef struct uint16_t height; uint8_t fmt; uint32_t len; + uint8_t mode; } frame_info_t; #define PACKET_HEADER_LENGTH ( sizeof(packet_header_t) ) #define PACKET_APP_HEADER_LENGTH ( sizeof(frame_info_t) ) -#define CHUNK_SIZE ( 1500 - 28 ) +#define CHUNK_SIZE ( 1500 - 32 ) #define PACKET_PAYLOAD_SIZE (CHUNK_SIZE + PACKET_HEADER_LENGTH + PACKET_APP_HEADER_LENGTH ) void packet_dump_header( packet_header_t *h); diff --git a/veejay-current/veejay-server/libvjnet/vj-client.c b/veejay-current/veejay-server/libvjnet/vj-client.c index b54ece37..fbc1c741 100644 --- a/veejay-current/veejay-server/libvjnet/vj-client.c +++ b/veejay-current/veejay-server/libvjnet/vj-client.c @@ -252,12 +252,7 @@ static void vj_client_decompress( vj_client *t, uint8_t *out, int data_len, int out, out + Y, out + Y + UV }; -#ifdef STRICT_CHECKING - assert( data_len > 0 ); - assert( Y > 0 ); - assert( UV > 0 ); -#endif - lzo_decompress( t->lzo, t->space, data_len, d ); + lzo_decompress( t->lzo, t->space, data_len, d, UV ); } static void hexstr(uint8_t *bytes, int len){ @@ -277,6 +272,7 @@ static int getint(uint8_t *in, int len ) { free(word); return (int) v; } + int vj_client_read_i( vj_client *v, uint8_t *dst, int len ) { uint8_t line[32]; @@ -286,7 +282,6 @@ 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 ) { plen = mcast_recv_frame( v->c[0]->r, v->space, 0, v->cur_width,v->cur_height,v->cur_fmt, @@ -311,9 +306,9 @@ int vj_client_read_i( vj_client *v, uint8_t *dst, int len ) default: uv_len = y_len/2;break; } - - vj_client_decompress( v, dst,p[3],y_len,uv_len ,0); + vj_client_decompress( v, dst,plen,y_len,uv_len ,16); + if( p[0] != v->cur_width || p[1] != v->cur_height || p[2] != v->cur_fmt ) return 2; return 1; diff --git a/veejay-current/veejay-server/libvjnet/vj-client.h b/veejay-current/veejay-server/libvjnet/vj-client.h index 833b9f8d..9eae5519 100644 --- a/veejay-current/veejay-server/libvjnet/vj-client.h +++ b/veejay-current/veejay-server/libvjnet/vj-client.h @@ -78,6 +78,5 @@ 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 ); - #endif diff --git a/veejay-current/veejay-server/libvjnet/vj-server.c b/veejay-current/veejay-server/libvjnet/vj-server.c index f033cfe4..0db2c7a4 100644 --- a/veejay-current/veejay-server/libvjnet/vj-server.c +++ b/veejay-current/veejay-server/libvjnet/vj-server.c @@ -93,6 +93,12 @@ void vj_server_geo_stats() geo_stat_ = 1; } +void vj_server_set_mcast_mode( vj_server *v , int mode ) +{ + v->mcast_gray = mode; + veejay_msg(VEEJAY_MSG_DEBUG, "Sending in %s", (mode==0 ? "Color" : "Grayscale" ) ); +} + static int _vj_server_multicast( vj_server *v, char *group_name, int port ) { vj_link **link; @@ -435,7 +441,7 @@ int vj_server_send_frame( vj_server *vje, int link_id, uint8_t *buf, int len, { vj_proto **proto = (vj_proto**) vje->protocol; if( vje->server_type == V_CMD ) - return mcast_send_frame( proto[0]->s, frame, buf,len,ms, vje->ports[0] ); + return mcast_send_frame( proto[0]->s, frame, buf,len,ms, vje->ports[0],vje->mcast_gray ); } return 0; } diff --git a/veejay-current/veejay-server/libvjnet/vj-server.h b/veejay-current/veejay-server/libvjnet/vj-server.h index 5ab93d56..87427ded 100644 --- a/veejay-current/veejay-server/libvjnet/vj-server.h +++ b/veejay-current/veejay-server/libvjnet/vj-server.h @@ -40,6 +40,7 @@ typedef struct vj_server_t { char *recv_buf; int send_size; int recv_size; + int mcast_gray; } vj_server; vj_server *vj_server_alloc(int port, char *mcast_group_name, int type); @@ -61,6 +62,7 @@ int vj_server_init(void); int _vj_server_del_client(vj_server * vje, int link_id); +void vj_server_set_mcast_mode( vj_server *vje, int mode ); void vj_server_close_connection( vj_server *vje, int link_id ); diff --git a/veejay-current/veejay-server/veejay/vj-event.c b/veejay-current/veejay-server/veejay/vj-event.c index aebd1ff8..891041d1 100644 --- a/veejay-current/veejay-server/veejay/vj-event.c +++ b/veejay-current/veejay-server/veejay/vj-event.c @@ -6690,13 +6690,12 @@ void vj_event_tag_new_mcast(void *ptr, const char format[], va_list ap) veejay_t *v = (veejay_t*)ptr; char str[255]; - int args[2]; + int args[3]; P_A(args,str,format,ap); - veejay_msg(VEEJAY_MSG_DEBUG, "%s, %d", str, args[0]); - int id = veejay_create_tag(v, VJ_TAG_TYPE_MCAST, str, v->nstreams, args[0],0); + vj_event_send_new_id( v, id ); if( id <= 0) @@ -8631,11 +8630,17 @@ void vj_event_send_frame ( void *ptr, const char format[], va_list ap ) void vj_event_mcast_start ( void *ptr, const char format[], va_list ap ) { veejay_t *v = (veejay_t*) ptr; + int args[2]; + char s[255]; + P_A( args, s , format, ap); + if(!v->settings->use_vims_mcast) - veejay_msg(VEEJAY_MSG_ERROR, "start veejay in multicast mode (see -V commandline option)"); + veejay_msg(VEEJAY_MSG_ERROR, "start veejay in multicast mode (see -T commandline option)"); else { v->settings->mcast_frame_sender = 1; + v->settings->mcast_mode = args[0]; + vj_server_set_mcast_mode( v->vjs[2],args[0] ); veejay_msg(VEEJAY_MSG_INFO, "Veejay started mcast frame sender"); } } diff --git a/veejay-current/veejay-server/veejay/vj-eventman.c b/veejay-current/veejay-server/veejay/vj-eventman.c index d1bcb77e..5e99b5b4 100644 --- a/veejay-current/veejay-server/veejay/vj-eventman.c +++ b/veejay-current/veejay-server/veejay/vj-eventman.c @@ -2285,12 +2285,14 @@ void vj_init_vevo_events(void) VIMS_ALLOW_ANY, NULL ); index_map_[VIMS_VIDEO_MCAST_START] = _new_event( - NULL, + "%d", VIMS_VIDEO_MCAST_START, "Start built-in UDP mcast server (YUV planar)", vj_event_mcast_start, - 0, + 1, VIMS_ALLOW_ANY, + "0=Color,1=Grayscale (default)", + 1, NULL ); index_map_[VIMS_VIDEO_MCAST_STOP] = _new_event( NULL, diff --git a/veejay-current/veejay-server/veejay/vj-lib.h b/veejay-current/veejay-server/veejay/vj-lib.h index bfa2c8a0..245c25aa 100644 --- a/veejay-current/veejay-server/veejay/vj-lib.h +++ b/veejay-current/veejay-server/veejay/vj-lib.h @@ -176,6 +176,7 @@ typedef struct { int unicast_link_id; int unicast_frame_sender; int is_dat; + int mcast_mode; int mcast_frame_sender; int use_mcast; char *group_name; diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c index ddd8eb8b..c9588d3d 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -1030,7 +1030,7 @@ static int vj_perform_compress_frame( veejay_t *info, uint8_t *dst) { const int len = info->effect_frame1->width * info->effect_frame1->height; const int uv_len = info->effect_frame1->uv_len; - uint8_t *dstI = dst + (12 * sizeof(uint8_t)); + uint8_t *dstI = dst + (16 * sizeof(uint8_t)); unsigned int size1=0,size2=0,size3=0; int i = lzo_compress( lzo_ , primary_buffer[info->out_buf]->Y, dstI, &size1, len ); if( i == 0 ) @@ -1043,6 +1043,16 @@ static int vj_perform_compress_frame( veejay_t *info, uint8_t *dst) } dstI += size1; + + if( info->settings->mcast_mode == 1 ) { + //@ only compress Y plane, set mode in header + long2str( dst,size1); + long2str( dst+4,0); + long2str( dst+8,0); + long2str( dst+12, info->settings->mcast_mode ); + return 16 + size1; + } + i = lzo_compress( lzo_, primary_buffer[info->out_buf]->Cb, dstI, &size2, uv_len ); if( i == 0 ) { @@ -1067,8 +1077,8 @@ static int vj_perform_compress_frame( veejay_t *info, uint8_t *dst) long2str( dst,size1); long2str( dst+4, size2 ); long2str( dst+8, size3 ); - - return (size1+size2+size3+12); + long2str( dst+12,info->settings->mcast_mode ); + return (size1+size2+size3+16); } int vj_perform_send_primary_frame_s2(veejay_t *info, int mcast, int to_link_id)