diff --git a/veejay-current/configure.ac b/veejay-current/configure.ac index c68adb40..51ead360 100644 --- a/veejay-current/configure.ac +++ b/veejay-current/configure.ac @@ -1,12 +1,12 @@ dnl Process this file with autoconf to produce a configure script. dnl AC_INIT -AC_INIT([veejay],[0.9.23],[veejay-users@lists.sourceforge.net]) +AC_INIT([veejay],[0.9.24],[veejay-users@lists.sourceforge.net]) AC_PREREQ(2.57) AC_CONFIG_SRCDIR([veejay/veejay.c]) VEEJAY_MAJOR_VERSION=0 VEEJAY_MINOR_VERSION=9 -VEEJAY_MICRO_VERSION=23 +VEEJAY_MICRO_VERSION=24 VEEJAY_VERSION=$VEEJAY_MAJOR_VERSION.$VEEJAY_MINOR_VERSION.$VEEJAY_MICRO_VERSION VEEJAY_CODENAME="Veejay Classic - build $VEEJAY_MINOR_VERSION $VEEJAY_MICRO_VERSION" AC_CONFIG_HEADERS([config.h]) @@ -234,6 +234,15 @@ dnl fi ;; esac + +dnl ====== check for PKG_CONFIG_PATH +if test x"$PKG_CONFIG_PATH" = x ; then + AC_MSG_NOTICE([The PKG_CONFIG_PATH variable was not set]) + AC_MSG_NOTICE([You should set it to the directories that contain the .pc files]) + AC_MSG_ERROR([Abort]) +fi + + AC_SUBST(LIBM_LIBS) if test x$with_v4l != xno ; then diff --git a/veejay-current/gveejay-reloaded/sequence.c b/veejay-current/gveejay-reloaded/sequence.c index 20217e43..3f991145 100644 --- a/veejay-current/gveejay-reloaded/sequence.c +++ b/veejay-current/gveejay-reloaded/sequence.c @@ -34,6 +34,7 @@ typedef struct int port_num; vj_client *fd; uint8_t *data_buffer; + uint8_t *tmp_buffer; uint8_t *compr_buffer; //shared uint8_t *status_buffer; int track_list[16]; @@ -41,6 +42,7 @@ typedef struct int status_tokens[32]; //shared int active; int have_frame; + int grey_scale; int preview; int width; int height; @@ -109,6 +111,8 @@ static void gvr_close_connection( veejay_track_t *v ) if(v->status_buffer) free(v->status_buffer); if(v->compr_buffer) free(v->compr_buffer); if(v->data_buffer) free(v->data_buffer); + if(v->tmp_buffer) free(v->tmp_buffer); + free(v); v= NULL; } @@ -146,7 +150,6 @@ static int recvvims( veejay_track_t *v, gint header_len, gint *payload, guchar * gint tmp_len = header_len + 1; unsigned char *tmp = vj_calloc( tmp_len ); gint len = 0; - gint n = vj_client_read( v->fd, V_CMD, tmp, header_len ); if( n<= 0 ) @@ -156,7 +159,7 @@ static int recvvims( veejay_track_t *v, gint header_len, gint *payload, guchar * return 0; } - if( sscanf( (char*)tmp, "%6d", &len )<=0) + if( sscanf( (char*)tmp, "%6d%1d", &len,&(v->grey_scale) )<=0) { free(tmp); veejay_msg(0, "Error reading header contents"); @@ -318,7 +321,7 @@ static int veejay_get_image_data(veejay_preview_t *vp, veejay_track_t *v ) } gint bw = 0; - res = recvvims( v, 6, &bw, v->compr_buffer ); + res = recvvims( v, 7, &bw, v->compr_buffer ); if( res <= 0 ) { veejay_msg(0, "Error receiving compressed RGB image"); @@ -460,7 +463,7 @@ int gvr_track_connect( void *preview, const char *hostname, int port_num, int * vt->status_buffer = (uint8_t*) vj_calloc(sizeof(uint8_t) * 256); vt->compr_buffer = (uint8_t*) vj_calloc(sizeof(uint8_t) * 512 * 512 * 3 ); vt->data_buffer = (uint8_t*) vj_calloc(sizeof(uint8_t) * 512 * 512 * 3 ); - + vt->tmp_buffer = (uint8_t*) vj_calloc(sizeof(uint8_t) * 512 * 512 * 3 ); veejay_msg(2, "Track %d connected to Veejay %s : %d", track_num,hostname,port_num); g_mutex_lock( vp->mutex ); @@ -659,6 +662,7 @@ int gvr_track_toggle_preview( void *preview, int track_num, int status ) vp->tracks[ track_num ]->hostname, vp->tracks[ track_num ]->port_num, (status ? "Active" : "Disabled") ); + return status; } @@ -676,8 +680,24 @@ static GdkPixbuf **gvr_grab_images(void *preview) if( vp->tracks[i] && vp->tracks[i]->have_frame ) { veejay_track_t *v = vp->tracks[i]; - list[i] = gdk_pixbuf_new_from_data( v->data_buffer, GDK_COLORSPACE_RGB, FALSE, + if(v->grey_scale) + { + uint8_t *rgb = v->tmp_buffer; + unsigned int j = 0; + for( j = 0; j < (v->width*v->height); j+=3 ) + { + rgb[j+0] = v->data_buffer[j]; + rgb[j+1] = v->data_buffer[j]; + rgb[j+2] = v->data_buffer[j]; + } + list[i] = gdk_pixbuf_new_from_data(v->tmp_buffer, GDK_COLORSPACE_RGB, FALSE, + 8, v->width,v->height,v->width * 3, NULL,NULL ); + } + else + { + list[i] = gdk_pixbuf_new_from_data( v->data_buffer, GDK_COLORSPACE_RGB, FALSE, 8, v->width,v->height,v->width * 3,NULL,NULL ); + } vp->tracks[i]->have_frame = 0; } } diff --git a/veejay-current/libel/avilib.c b/veejay-current/libel/avilib.c index dc410543..c5c23fab 100644 --- a/veejay-current/libel/avilib.c +++ b/veejay-current/libel/avilib.c @@ -2059,13 +2059,12 @@ avi_t *AVI_open_input_file(char *filename, int getIndex, int mmap_size) /* Create avi_t structure */ - AVI = (avi_t *) vj_malloc(sizeof(avi_t)); + AVI = (avi_t *) vj_calloc(sizeof(avi_t)); if(AVI==NULL) { AVI_errno = AVI_ERR_NO_MEM; return 0; } - veejay_memset((void *)AVI,0,sizeof(avi_t)); AVI->mode = AVI_MODE_READ; /* open for reading */ diff --git a/veejay-current/libel/elcache.c b/veejay-current/libel/elcache.c index 97e78ed4..b27610eb 100644 --- a/veejay-current/libel/elcache.c +++ b/veejay-current/libel/elcache.c @@ -117,6 +117,11 @@ void *init_cache( unsigned int n_slots ) cache_t *v = (cache_t*) vj_malloc(sizeof(cache_t)); v->len = n_slots; v->cache = (cache_slot_t**) vj_malloc(sizeof(cache_slot_t*) * v->len ); + if(!v->cache) + { + free(v); + return NULL; + } veejay_memset( v->cache, 0, sizeof(cache_slot_t*) * v->len ); v->index = (long*) malloc(sizeof(long) * v->len ); diff --git a/veejay-current/libel/lav_io.c b/veejay-current/libel/lav_io.c index 6ecc7274..7bcf3810 100644 --- a/veejay-current/libel/lav_io.c +++ b/veejay-current/libel/lav_io.c @@ -42,6 +42,7 @@ #include #include #endif +#include #include #include #define QUICKTIME_MJPG_TAG 0x6d6a7067 @@ -74,7 +75,7 @@ uint16_t reorder_16(uint16_t todo, int big_endian); static int output_scale_width = 0; static int output_scale_height = 0; static float output_fps = 25.0; -static int output_yuv = 0; // 422 +static int output_yuv = 1; // 422 void lav_set_project(int w, int h, float f, int fmt) { @@ -709,7 +710,7 @@ int lav_video_width(lav_file_t *lav_file) #endif #ifdef USE_GDK_PIXBUF case 'x': - return (output_scale_width == 0 ? vj_picture_get_width( lav_file->picture ) : output_scale_width); + return output_scale_width; #endif #ifdef HAVE_LIBQUICKTIME case 'q': @@ -738,7 +739,7 @@ int lav_video_height(lav_file_t *lav_file) #endif #ifdef USE_GDK_PIXBUF case 'x': - return (output_scale_height == 0 ? vj_picture_get_height( lav_file->picture ) : output_scale_height); + return output_scale_height; #endif #ifdef HAVE_LIBQUICKTIME case 'q': @@ -753,9 +754,6 @@ double lav_frame_rate(lav_file_t *lav_file) video_format = lav_file->format; internal_error = 0; /* for error messages */ switch(lav_file->format) { -// case 'a': -// case 'A': -// return AVI_frame_rate(lav_file->avi_fd); #ifdef SUPPORT_READ_DV2 case 'b': return rawdv_fps(lav_file->dv_fd); @@ -765,12 +763,12 @@ double lav_frame_rate(lav_file_t *lav_file) return output_fps; #endif #ifdef HAVE_LIBQUICKTIME - case 'q': - return quicktime_frame_rate(lav_file->qt_fd,0); + case 'q': + return quicktime_frame_rate(lav_file->qt_fd,0); #endif - default: - return AVI_frame_rate( lav_file->avi_fd); - } + default: + return AVI_frame_rate( lav_file->avi_fd ); + } return -1; } @@ -1402,7 +1400,20 @@ lav_file_t *lav_open_input_file(char *filename, int mmap_size) #ifdef USE_GDK_PIXBUF if(strncasecmp(video_comp, "PICT",4) == 0 ) { - lav_fd->MJPG_chroma = (output_yuv == 1 ? CHROMA420: CHROMA422 ); + switch(output_yuv) + { + case FMT_420: + case FMT_420F: + lav_fd->MJPG_chroma = CHROMA420; + break; + case FMT_422: + case FMT_422F: + lav_fd->MJPG_chroma = CHROMA422; + break; + default: + lav_fd->MJPG_chroma = CHROMAUNKNOWN; + break; + } lav_fd->format = 'x'; lav_fd->interlacing = LAV_NOT_INTERLACED; return lav_fd; diff --git a/veejay-current/libel/pixbuf.c b/veejay-current/libel/pixbuf.c index 9ed73262..45e8aaff 100644 --- a/veejay-current/libel/pixbuf.c +++ b/veejay-current/libel/pixbuf.c @@ -139,12 +139,18 @@ int vj_picture_get_width( void *pic ) void *vj_picture_open( const char *filename, int v_outw, int v_outh, int v_outf ) { vj_pixbuf_t *pic = NULL; - - if(filename == NULL || v_outw <= 0 || v_outh <= 0 ) + if(filename == NULL ) { - veejay_msg(0, "No filename given or invalid image dimensions"); + veejay_msg(0, "No image filename given"); return NULL; } + + if(v_outw <= 0 || v_outh <= 0 ) + { + veejay_msg(0, "No image dimensions setup"); + return NULL; + } + pic = (vj_pixbuf_t*) vj_calloc(sizeof(vj_pixbuf_t)); if(!pic) { @@ -156,10 +162,34 @@ void *vj_picture_open( const char *filename, int v_outw, int v_outh, int v_outf pic->display_h = v_outh; pic->fmt = v_outf; + int len = v_outw * v_outh; + int ulen = len; + switch( v_outf ) + { + case PIX_FMT_YUV420P: + case PIX_FMT_YUVJ420P: + ulen = len / 4; + break; + case PIX_FMT_YUV422P: + case PIX_FMT_YUVJ422P: + ulen = len / 2; + break; + default: +#ifdef STRICT_CHECKING + assert(0); +#endif + break; + } - pic->space = (uint8_t*) vj_malloc( sizeof(uint8_t) * v_outw * v_outh * 3 ); - - pic->img = open_pixbuf( filename, v_outw, v_outh, v_outf, pic->space, pic->space + (v_outw*v_outh) , pic->space + (2*v_outw*v_outh) ); + pic->space = (uint8_t*) vj_malloc( sizeof(uint8_t) * (len + 2*ulen) ); + pic->img = open_pixbuf( + filename, + v_outw, + v_outh, + v_outf, + pic->space, + pic->space + len, + pic->space + len + ulen ); return (void*) pic; } @@ -382,22 +412,15 @@ veejay_image_t *vj_fastbw_picture_save_to_mem( VJFrame *frame, int out_w, int o veejay_memset(&src,0,sizeof(VJFrame)); veejay_memset(&dst,0,sizeof(VJFrame)); - vj_get_yuv_template( &src,frame->width,frame->height,fmt ); + vj_get_yuv_template( &src,frame->width,frame->height,fmt); src.data[0] = frame->data[0]; src.data[1] = frame->data[1]; src.data[2] = frame->data[2]; vj_get_yuv_template( &dst,out_w,out_h,fmt ); + dst.data[0] = (uint8_t*) gdk_pixbuf_get_pixels( image->image ); + dst.data[1] = dst.data[0] + (out_w * out_h ); + dst.data[2] = dst.data[1] + (out_w * out_h ); - uint8_t *data[3]; - data[0] = vj_malloc( sizeof(uint8_t) * out_w * out_h * 3 ); - data[1] = data[0] + (out_w * out_h); - data[2] = data[1] + (out_w * out_h); - - dst.data[0] = data[0]; - dst.data[1] = data[1]; - dst.data[2] = data[2]; - -veejay_msg(1, "%s: not grayscale yet"); if( !bwscaler || scale_dim_bw[0] != out_w || scale_dim_bw[1] != out_h ) { if(bwscaler ) diff --git a/veejay-current/libel/vj-el.c b/veejay-current/libel/vj-el.c index 0c165c59..cf967d55 100644 --- a/veejay-current/libel/vj-el.c +++ b/veejay-current/libel/vj-el.c @@ -262,7 +262,10 @@ static void _el_free_decoder( vj_decoder *d ) } if(d->frame) free(d->frame); - + + if(d->img) + free(d->img); + free(d); } d = NULL; @@ -340,15 +343,14 @@ void vj_el_setup_cache( editlist *el ) if(!el->cache) { int n_slots = mem_chunk_ / el->max_frame_size; - if( n_slots < (el->video_frames - 1) ) { veejay_msg(VEEJAY_MSG_DEBUG, "Not caching this EDL to memory (Cachesize too small)"); veejay_msg(VEEJAY_MSG_DEBUG, "try increasing cache size with -m commandline parameter"); } - else + else if( el->max_frame_size > 1024 ) { - veejay_msg(VEEJAY_MSG_DEBUG, "EditList caches at most %d slots", n_slots ); + veejay_msg(VEEJAY_MSG_DEBUG, "EditList caches at most %d slots (chunk=%d, framesize=%d)", n_slots, mem_chunk_, el->max_frame_size ); el->cache = init_cache( n_slots ); } } @@ -456,10 +458,9 @@ vj_decoder *_el_new_decoder( int id , int width, int height, float fps, int pixe void vj_el_set_image_output_size(editlist *el) { lav_set_project( - el->video_width, el->video_height, el->video_fps , - el->pixel_format == FMT_420 ? 1 :0); -} + el->video_width, el->video_height, el->video_fps , el_pixel_format_ ); +} static int _el_probe_for_pixel_fmt( lav_file_t *fd ) { @@ -988,9 +989,47 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) } } + int len = el->video_width * el->video_height; + int uv_len=len; + switch(out_pix_fmt) + { + case FMT_420: + case FMT_420F: + uv_len = len/4; + break; + case FMT_422: + case FMT_422F: + uv_len = len/2; + break; + default: + break; + } + + + int uv_w = el->video_width / 2; + + + if( decoder_id == 0xffff ) + { + VJFrame *srci = lav_get_frame_ptr( el->lav_fd[ N_EL_FILE(n) ] ); + if( srci == NULL ) + { + veejay_msg(VEEJAY_MSG_ERROR, "Error decoding Image %ld", + N_EL_FRAME(n)); + return -1; + } +#ifdef STRICT_CHECKING + assert( dst[0] != NULL && dst[1] != NULL && dst[2] != NULL ); +#endif + veejay_memcpy( dst[0], srci->data[0], len ); + veejay_memcpy( dst[1], srci->data[1], uv_len ); + veejay_memcpy( dst[2], srci->data[2], uv_len ); + return 1; + } + c_i = _el_get_codec( decoder_id , in_pix_fmt); - if(c_i >= 0 && c_i < MAX_CODECS && el_codecs[c_i] != NULL) - d = el_codecs[c_i]; + if(c_i >= 0 && c_i < MAX_CODECS && el_codecs[c_i] != NULL) + d = el_codecs[c_i]; else { veejay_msg(VEEJAY_MSG_ERROR, "Choked on decoder %x (%d), slot %d",decoder_id,decoder_id, c_i ); @@ -1012,25 +1051,6 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) } } - int len = el->video_width * el->video_height; - int uv_len = (el->video_width >> 1) * (el->video_height >> ((out_pix_fmt == FMT_420 || out_pix_fmt == FMT_420F) ? 1:0)); - int uv_w = el->video_width / 2; - if( decoder_id == 0xffff ) - { - VJFrame *srci = lav_get_frame_ptr( el->lav_fd[ N_EL_FILE(n) ] ); - if( srci == NULL ) - { - veejay_msg(VEEJAY_MSG_ERROR, "Error decoding frame %ld", - N_EL_FRAME(n)); - return -1; - } - - veejay_memcpy( dst[0], srci->data[0], len ); - veejay_memcpy( dst[1], srci->data[1], uv_len ); - veejay_memcpy( dst[2], srci->data[2], uv_len ); - return 1; - } - uint8_t *data = ( in_cache == NULL ? d->tmp_buffer: in_cache ); int inter = 0; int got_picture = 0; @@ -1221,8 +1241,14 @@ int test_video_frame( lav_file_t *lav,int out_pix_fmt) return -1; } - int decoder_id = lav_video_compressor_type( lav ); + int decoder_id = lav_video_compressor_type( lav ); + if(lav_filetype( lav ) == 'x') + { + veejay_msg(VEEJAY_MSG_INFO,"\tFile is an image"); + return out_pix_fmt; + } + vj_decoder *d = _el_new_decoder( decoder_id, lav_video_width( lav), @@ -1237,12 +1263,6 @@ int test_video_frame( lav_file_t *lav,int out_pix_fmt) return -1; } - if(lav_filetype( lav ) == 'x') - { - _el_free_decoder( d ); - veejay_msg(VEEJAY_MSG_INFO,"\tFile is an image"); - return out_pix_fmt; - } res = lav_read_frame( lav, d->tmp_buffer); if( res <= 0 ) @@ -1395,6 +1415,7 @@ int vj_el_init_420_frame(editlist *el, VJFrame *frame) frame->ssm = 0; frame->stride[0] = el->video_width; frame->stride[1] = frame->stride[2] = frame->stride[0]/2; + frame->format = el_pixel_format_; return 1; } @@ -1416,6 +1437,7 @@ int vj_el_init_422_frame(editlist *el, VJFrame *frame) frame->ssm = 0; frame->stride[0] = el->video_width; frame->stride[1] = frame->stride[2] = frame->stride[0]/2; + frame->format = el_pixel_format_; return 1; } @@ -1548,6 +1570,7 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de /* Check if a norm parameter is present */ if(!filename[0] || filename == NULL) { + veejay_msg(VEEJAY_MSG_ERROR,"\tInvalid filename given"); vj_el_free(el); return NULL; } @@ -1717,8 +1740,14 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de } if( el->num_video_files == 0 || - el->video_width == 0 || el->video_height == 0 || el->video_frames <= 2) + el->video_width == 0 || el->video_height == 0 || el->video_frames < 2) { + if( el->video_frames < 2 ) + veejay_msg(VEEJAY_MSG_ERROR, "\tFile has only %d frame(s)", el->video_frames ); + if( el->num_video_files == 0 ) + veejay_msg(VEEJAY_MSG_ERROR, "\tNo videofiles in EDL"); + if( el->video_height == 0 || el->video_width == 0 ) + veejay_msg(VEEJAY_MSG_ERROR, "\tImage dimensions unknown"); vj_el_free(el); return NULL; } @@ -1732,6 +1761,7 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de n = el->frame_list[i]; if(!el->lav_fd[N_EL_FILE(n)] ) { + veejay_msg(VEEJAY_MSG_ERROR, "\tUnable to read file"); vj_el_free(el); return NULL; } diff --git a/veejay-current/libstream/vj-net.c b/veejay-current/libstream/vj-net.c index 782fdaee..dc4c46ca 100644 --- a/veejay-current/libstream/vj-net.c +++ b/veejay-current/libstream/vj-net.c @@ -27,14 +27,12 @@ #include #include #include -#include typedef struct { pthread_mutex_t mutex; pthread_t thread; vj_client *remote; - void *lzo; int state; int have_frame; int error; @@ -68,13 +66,11 @@ void *reader_thread(void *data) for( ;; ) { - int retrieve = 0; int error = 0; if( t->state == 0 ) { error = 1; - t->grab = 0; } if( tag->source_type == VJ_TAG_TYPE_NET ) @@ -88,30 +84,54 @@ void *reader_thread(void *data) lock(t); - if( t->grab ) + if( t->grab && tag->source_type == VJ_TAG_TYPE_NET) { ret = vj_client_send( v, V_CMD, buf ); if( ret <= 0 ) error = 1; else - retrieve = 1; - t->grab = 0; - } - - if(!error && retrieve) + t->grab = 0; + } + + if (tag->source_type == VJ_TAG_TYPE_MCAST ) { - ret = vj_client_read_i ( v, tag->socket_frame ); + error = 0; + } + + int wait_time = 0; + + if(!error) + { + if( vj_client_poll(v, V_CMD ) ) + { + ret = vj_client_read_i ( v, tag->socket_frame,tag->socket_len ); if( ret <= 0 ) - error = 1; - t->have_frame = ret; + { + if( tag->source_type == VJ_TAG_TYPE_NET ) + error = 1; + else + { + wait_time = 1000; + } + ret = 0; + } + else + { + t->have_frame = ret; + } + } } unlock(t); + if( wait_time ) + usleep(wait_time); + if( error ) { veejay_msg(VEEJAY_MSG_ERROR, "Closing connection with remote veejay,"); t->state = 0; + t->grab = 0; pthread_exit( &(t->thread)); return NULL; } @@ -140,21 +160,53 @@ int net_thread_get_frame( vj_tag *tag, uint8_t *buffer[3] ) unlock(t); return 0; } - if(t->have_frame) + + //@ color space convert frame + int len = v->cur_width * v->cur_height; + int uv_len = len; + switch(v->cur_fmt) { - lzo_decompress( t->lzo, buf, 0, buffer ); + case FMT_420: + case FMT_420F: + uv_len=len/4; + break; + default: + uv_len=len/2; + break; } - else + + if(t->have_frame == 1 ) { - veejay_memset( buffer[0], 16, v->planes[0]); - veejay_memset( buffer[1], 128,v->planes[1]); - veejay_memset( buffer[2], 128,v->planes[2]); + 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; } - /* - veejay_memcpy( buffer[0], buf, v->planes[0] ); - veejay_memcpy( buffer[1], buf+ v->planes[0], v->planes[1] ); - veejay_memcpy( buffer[2], buf+ v->planes[0] + v->planes[1] , v->planes[2] ); - */ + else if(t->have_frame == 2 ) + { + int b_len = v->in_width * v->in_height; + int buvlen = b_len; + switch(v->in_fmt) + { + case FMT_420: + case FMT_420F: + buvlen = b_len/4; + break; + default: + buvlen = b_len/2; + break; + } + + 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 )); + 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(a,b, a->format,b->format ); + free(a); + free(b); + } t->grab = 1; unlock(t); @@ -183,7 +235,7 @@ int net_thread_start(vj_client *v, vj_tag *tag) threaded_t *t = (threaded_t*)tag->priv; pthread_mutex_init( &(t->mutex), NULL ); - t->lzo = lzo_new(); + v->lzo = lzo_new(); t->have_frame = 0; t->error = 0; t->state = 1; @@ -203,15 +255,18 @@ int net_thread_start(vj_client *v, vj_tag *tag) veejay_msg(VEEJAY_MSG_ERROR, "Unable to send to %s port %d", tag->source_name, tag->video_channel ); return 0; - } + } + else + veejay_msg(VEEJAY_MSG_INFO, "Requested mcast stream from Veejay group %s port %d", + tag->source_name, tag->video_channel ); } 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", + veejay_msg(VEEJAY_MSG_INFO, "Created new %s threaded stream with Veejay host %s port %d", tag->source_type == VJ_TAG_TYPE_MCAST ? - "multicast" : "unicast"); + "multicast" : "unicast", tag->source_name,tag->video_channel); return 1; } @@ -229,21 +284,25 @@ void net_thread_stop(vj_tag *tag) { sprintf(mcast_stop, "%03d:;", VIMS_VIDEO_MCAST_STOP ); ret = vj_client_send( t->remote , V_CMD, mcast_stop); + if(ret) + veejay_msg(VEEJAY_MSG_INFO, "Stopped multicast stream"); } if(tag->source_type == VJ_TAG_TYPE_NET) { sprintf(mcast_stop, "%03d:;", VIMS_CLOSE ); ret = vj_client_send( t->remote, V_CMD, mcast_stop); + if(ret) + veejay_msg(VEEJAY_MSG_INFO, "Stopped unicast stream"); } t->state = 0; - lzo_free(t->lzo); unlock(t); pthread_mutex_destroy( &(t->mutex)); - veejay_msg(VEEJAY_MSG_INFO, "Disconnected from %s", tag->source_name); + veejay_msg(VEEJAY_MSG_INFO, "Disconnected from Veejay host %s:%d", tag->source_name, + tag->video_channel); } int net_already_opened(const char *filename, int n, int channel) diff --git a/veejay-current/libstream/vj-tag.c b/veejay-current/libstream/vj-tag.c index 62999b3f..45c45780 100644 --- a/veejay-current/libstream/vj-tag.c +++ b/veejay-current/libstream/vj-tag.c @@ -268,14 +268,28 @@ 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; - if( !host ) return 0; - if( port <= 0 ) return 0; - if(stream_nr < 0 || stream_nr > VJ_TAG_MAX_STREAM_IN) return 0; + if( !host ) { + veejay_msg(0, "No hostname given"); + return 0; + } + if( port <= 0 ) { + veejay_msg(0, "Port number %d invalid", port ); + return 0; + } + if(stream_nr < 0 || stream_nr > VJ_TAG_MAX_STREAM_IN) + { + veejay_msg(0, "Unable to create more network streams (%d reached)", + VJ_TAG_MAX_STREAM_IN ); + return 0; + } vj_tag_input->net[stream_nr] = vj_client_alloc(w,h,f); v = vj_tag_input->net[stream_nr]; - if(!v) return 0; - + if(!v) + { + veejay_msg(0, "Memory allocation error while creating network stream"); + return 0; + } char tmp[255]; bzero(tmp,255); snprintf(tmp,sizeof(tmp)-1, "%s %d", host, port ); @@ -295,7 +309,8 @@ int _vj_tag_new_net(vj_tag *tag, int stream_nr, int w, int h,int f, char *host, } if( tag->socket_ready == 0 ) { - tag->socket_frame = (uint8_t*) vj_calloc(sizeof(uint8_t) * v->planes[0] * 4); + tag->socket_frame = (uint8_t*) vj_calloc(sizeof(uint8_t) * SOCKETFRAMELEN); + tag->socket_len = SOCKETFRAMELEN; if(!tag->socket_frame) { veejay_msg(VEEJAY_MSG_ERROR, "Insufficient error to allocate memory for Network Stream"); @@ -476,7 +491,10 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, char sourcename[255]; vj_tag *tag; - + + veejay_msg(VEEJAY_MSG_DEBUG, "type=%d, file=%s, stream_nr=%d, pix=%d, chan=%d, extra=%d", + type, filename, stream_nr, pix_fmt, channel, extra ); + if( this_tag_id == 0) { this_tag_id = 1; // first tag @@ -561,6 +579,7 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, tag->effect_toggle = 1; /* same as for samples */ tag->socket_ready = 0; tag->socket_frame = NULL; + tag->socket_len = 0; tag->color_r = 0; tag->color_g = 0; tag->color_b = 0; @@ -623,18 +642,6 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, } tag->active = 1; break; - case VJ_TAG_TYPE_SHM: - sprintf(tag->source_name, "%s", "SHM"); - veejay_msg(VEEJAY_MSG_INFO, "Opened SHM as Stream"); - break; -/* - case VJ_TAG_TYPE_WHITE: - case VJ_TAG_TYPE_BLACK: - case VJ_TAG_TYPE_RED: - case VJ_TAG_TYPE_GREEN: - case VJ_TAG_TYPE_YELLOW: - case VJ_TAG_TYPE_BLUE: -*/ case VJ_TAG_TYPE_COLOR: sprintf(tag->source_name, "[%d,%d,%d]", tag->color_r,tag->color_g,tag->color_b ); @@ -642,6 +649,7 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, break; default: + veejay_msg(0, "Stream type %d invalid", type ); return -1; } @@ -778,9 +786,6 @@ int vj_tag_del(int id) vj_tag_input->picture[tag->index] = NULL; break; #endif - case VJ_TAG_TYPE_SHM: - veejay_msg(VEEJAY_MSG_INFO, "huh ?"); - break; case VJ_TAG_TYPE_MCAST: case VJ_TAG_TYPE_NET: net_thread_stop(tag); @@ -2032,9 +2037,6 @@ void vj_tag_get_by_type(int type, char *description ) case VJ_TAG_TYPE_YUV4MPEG: sprintf(description, "%s", "YUV4MPEG"); break; - case VJ_TAG_TYPE_SHM: - sprintf(description, "%s","SHM"); - break; } } diff --git a/veejay-current/libstream/vj-tag.h b/veejay-current/libstream/vj-tag.h index ea08107f..7a9c055c 100644 --- a/veejay-current/libstream/vj-tag.h +++ b/veejay-current/libstream/vj-tag.h @@ -103,6 +103,7 @@ typedef struct { int selected_entry; int effect_toggle; int socket_ready; + int socket_len; uint8_t *socket_frame; int n_frames; void *priv; diff --git a/veejay-current/libstream/vj-unicap.c b/veejay-current/libstream/vj-unicap.c index 0bb0dd75..4321954d 100644 --- a/veejay-current/libstream/vj-unicap.c +++ b/veejay-current/libstream/vj-unicap.c @@ -101,7 +101,6 @@ static int vj_unicap_scan_enumerate_devices(void *unicap) int i; unicap_driver_t *ud = (unicap_driver_t*) unicap; char key[64]; - unicap_void_device(&(ud->device)); for( i = 0; SUCCESS( unicap_enumerate_devices( NULL, &(ud->device), i ) ); i++ ) @@ -113,10 +112,9 @@ static int vj_unicap_scan_enumerate_devices(void *unicap) if( !SUCCESS( unicap_open( &(ud->handle), &(ud->device) ) ) ) { - veejay_msg(0, "Failed to open: %s\n", &(ud->device.identifier) ); + veejay_msg(0, "Failed to open: %s\n", ud->device.identifier ); continue; } - unicap_lock_properties( ud->handle ); unicap_void_property(&property); unicap_void_format( &format ); @@ -160,9 +158,9 @@ static int vj_unicap_scan_enumerate_devices(void *unicap) #ifdef STRICT_CHECKING assert( error == VEVO_NO_ERROR ); #endif - unicap_unlock_properties( ud->handle ); - unicap_close( ud->handle ); + + veejay_memset( &(ud->handle), 0 , sizeof( unicap_handle_t)); } return i; } diff --git a/veejay-current/libvje/effects/colorhis.c b/veejay-current/libvje/effects/colorhis.c index b07da39f..b483aee5 100644 --- a/veejay-current/libvje/effects/colorhis.c +++ b/veejay-current/libvje/effects/colorhis.c @@ -47,7 +47,7 @@ vj_effect *colorhis_init(int w, int h) ve->defaults[3] = 132; // strength ve->description = "Color Histogram"; - ve->sub_format = 1; + ve->sub_format = 0; ve->extra_frame = 0; ve->has_user = 0; return ve; @@ -85,8 +85,8 @@ void colorhis_free() void colorhis_apply( VJFrame *frame, int width, int height,int mode, int val, int intensity, int strength) { - - yuv_convert_any( frame, rgb_frame_, PIX_FMT_YUV444P, PIX_FMT_RGB24 ); + int src_fmt = (frame->uv_height == height ? PIX_FMT_YUV422P : PIX_FMT_YUV420P); + yuv_convert_any( frame, rgb_frame_, src_fmt, PIX_FMT_RGB24 ); if( val == 0 ) { @@ -98,7 +98,7 @@ void colorhis_apply( VJFrame *frame, int width, int height,int mode, int val, in veejay_histogram_equalize_rgb( histogram_, frame, rgb_, intensity, strength, mode ); - yuv_convert_any( rgb_frame_, frame, PIX_FMT_RGB24, PIX_FMT_YUV444P ); + yuv_convert_any( rgb_frame_, frame, PIX_FMT_RGB24, src_fmt ); } } diff --git a/veejay-current/libvje/effects/diff.c b/veejay-current/libvje/effects/diff.c index ae08aad0..3868cc7c 100644 --- a/veejay-current/libvje/effects/diff.c +++ b/veejay-current/libvje/effects/diff.c @@ -22,36 +22,35 @@ #include #include #include +#include +#include +#include +static uint8_t *static_bg = NULL; typedef struct { - int has_bg; - uint8_t *static_bg[3]; - double *sqrt_table[256]; uint8_t *data; + uint8_t *current; } diff_data; vj_effect *diff_init(int width, int height) { //int i,j; vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect)); - ve->num_params = 4; + ve->num_params = 3; ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */ ve->limits[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */ ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */ ve->limits[0][0] = 0; - ve->limits[1][0] = 9; - ve->limits[0][1] = 0; /* threshold min */ - ve->limits[1][1] = 25500; - ve->limits[0][2] = 0; /* threshold difference min */ - ve->limits[1][2] = 25500; - ve->limits[0][3] = 0; - ve->limits[1][3] = 1; - ve->defaults[0] = 4; - ve->defaults[1] = 3000; - ve->defaults[2] = 3000; - ve->defaults[3] = 1; - ve->description = "Difference Overlay"; + ve->limits[1][0] = 255; + ve->limits[0][1] = 0; /* reverse */ + ve->limits[1][1] = 1; + ve->limits[0][2] = 0; /* show mask */ + ve->limits[1][2] = 1; + ve->defaults[0] = 20; + ve->defaults[1] = 0; + ve->defaults[2] = 1; + ve->description = "Map B to A (substract background mask)"; ve->extra_frame = 1; ve->sub_format = 1; ve->has_user = 1; @@ -59,7 +58,15 @@ vj_effect *diff_init(int width, int height) return ve; } +void diff_destroy(void) +{ + if(static_bg) + free(static_bg); + static_bg = NULL; + +} +#define ru8(num)(((num)+8)&~8) int diff_malloc(void **d, int width, int height) { @@ -67,12 +74,11 @@ int diff_malloc(void **d, int width, int height) diff_data *my; *d = (void*) vj_calloc(sizeof(diff_data)); my = (diff_data*) *d; - my->static_bg[0] = (uint8_t*) vj_calloc(sizeof(uint8_t)* width * height); - my->data = (uint8_t*) vj_calloc(sizeof(uint8_t) * width * height ); - for(i=0; i < 256; i ++) - my->sqrt_table[i] = (double*)vj_calloc(sizeof(double)* 256); - - my->has_bg = 0; + my->data = (uint8_t*) vj_calloc( ru8(sizeof(uint8_t) * 2 * width * height) ); + my->current = my->data + (width*height); + + if(static_bg == NULL) + static_bg = (uint8_t*) vj_calloc( ru8(width * height * sizeof(uint8_t)) ); return 1; } @@ -82,10 +88,7 @@ void diff_free(void *d) { int i; diff_data *my = (diff_data*) d; - if(my->static_bg[0]) free( my->static_bg[0] ); if(my->data) free(my->data); - for(i = 0; i < 256 ; i ++) - if( my->sqrt_table[i]) free( my->sqrt_table[i]); free(d); } d = NULL; @@ -94,70 +97,57 @@ void diff_free(void *d) void diff_prepare(void *user, uint8_t *map[3], int width, int height) { diff_data *my = (diff_data*) user; - int d,e,x,y,len=width*height; - uint8_t *luma_map = map[0]; - // map[0] contains luma information of the frame -// int g_width = 7; - my->static_bg[0][0] = luma_map[0]; - // first row, 3x1 average - for(y=1; y < width; y++) + if(!static_bg ) { - my->static_bg[0][y] = ( luma_map[y-1] + luma_map[y] + luma_map[y+1] ) / 3; + veejay_msg(0,"FX \"Map B to A (substract background mask)\" not initialized"); + return; } - // 3x3 window average - for(y=width; y < len-width; y+= width) + + veejay_memcpy( static_bg, map[0], (width*height)); + + VJFrame tmp; + veejay_memset( &tmp, 0, sizeof(VJFrame)); + tmp.data[0] = static_bg; + tmp.width = width; + tmp.height = height; + softblur_apply( &tmp, width,height,0); +} + +static void binarify( uint8_t *dst, uint8_t *bg, uint8_t *src,int threshold,int reverse, const int len ) +{ + int i; + + if(!reverse) { - // first pixel on row - my->static_bg[0][y] = luma_map[y]; - for(x=1; x < width-1; x++) + for( i = 0; i < len; i ++ ) { - my->static_bg[0][y+x] = ( - - luma_map[x+y-width-1] + - luma_map[x+y-width] + - luma_map[x+y-width+1] + - - luma_map[x+y+width-1] + - luma_map[x+y+width+1] + - luma_map[x+y+width] + - - luma_map[x+y-1 ] + - luma_map[x+y+1 ] + - luma_map[x+y] - ) / 9; + if ( abs(bg[i] - src[i]) <= threshold ) + dst[i] = 0; + else + dst[i] = 0xff; } - // last pixel on row - my->static_bg[0][y+x+1] = luma_map[y+x+1]; + } - // last row, 3x3 average - for(y=len-width; y < len; y++) + else { - my->static_bg[0][y] = (luma_map[y-1] + luma_map[y+1] + luma_map[y] ) /3; - } - // calculate distance vector - for(d=0; d < 256; d ++) - { - for(e=0; e < 256;e++ ) + for( i = 0; i < len; i ++ ) { - my->sqrt_table[d][e] = sqrt( (d-e) * (d-e) ); + if ( abs(bg[i] - src[i]) >= threshold ) + dst[i] = 0; + else + dst[i] = 0xff; + } } - my->has_bg = 1; } void diff_apply(void *ed, VJFrame *frame, VJFrame *frame2, int width, int height, - int K_level, int noise_level,int noise_level2, int mode) + int threshold, int reverse,int mode) { unsigned int i; - double d; - int x,y; - int K = 0; - uint8_t *dst; - double level1 = (double)noise_level / 100.0; - double level2 = (double)noise_level2 / 100.0; const int len = frame->len; uint8_t *Y = frame->data[0]; uint8_t *Cb = frame->data[1]; @@ -166,98 +156,43 @@ void diff_apply(void *ed, VJFrame *frame, uint8_t *Cb2 = frame2->data[1]; uint8_t *Cr2 = frame2->data[2]; diff_data *ud = (diff_data*) ed; - uint8_t *map = (uint8_t*) ud->static_bg[0]; - double **tab = (double**) ud->sqrt_table; - - dst = ud->data; - // calculate if pixel is much different (has greater distance) - // accepted pixels are 0xff - if(!ud->has_bg) + if(static_bg==NULL) { - printf("No static bg in has_bg\n"); + veejay_msg(0, "There is background mask!"); return; } - for(i = 0 ; i < len ; i ++ ) + VJFrame *tmp = yuv_yuv_template( ud->current, NULL,NULL, width,height, + PIX_FMT_YUV444P ); + veejay_memcpy( ud->current, frame->data[0], len ); + softblur_apply(tmp,width,height,0); + free(tmp); + + + binarify( ud->data, static_bg, ud->current, threshold, reverse,len ); + + if(mode) { - d = tab[ ( map[i]) ][ (Y[i]) ]; - if(d > level1) + veejay_memcpy( Y, ud->data, len ); + veejay_memset( Cb, 128, len ); + veejay_memset( Cr, 128, len ); + return; + } + + uint8_t *bin = ud->data; + for( i = 0; i < len ;i ++ ) + { + if(bin[i]) { - dst[i] = 0xff; + Y[i] = Y2[i]; + Cb[i] = Cb2[i]; + Cr[i] = Cr2[i]; } else { - dst[i] = 0x0; - } - d = tab[ map[i]][ (Y2[i]) ]; - if(d > level2) - { - dst[i] = 0xf0; - } - - } - // anti alias frame to remove isolated white pixels - - - for(y=width; y < len-width; y+= width) - { - for(x=1; x < width-1; x ++) - { - if( dst[x+y] >= 0xf0) - { // have a bad influence on branch prediction - // simple 3x3 window where the value of K - // indicates whether to accept or discard an isolated pixel - - K = 1; - if( dst[x+y-width] >= 0xf0 ) K++; - if( dst[x+y+width] >= 0xf0 ) K++; - if( dst[x+y-width+1] >= 0xf0 ) K++; - if( dst[x+y+width+1] >= 0xf0 ) K++; - if( dst[x+y+width-1] >= 0xf0 ) K++; - if( dst[x+y-width-1] >= 0xf0 ) K++; - if( dst[x+y-1] >= 0xf0) K++; - if( dst[x+y+1] >= 0xf0) K++; - if( K <= K_level ) dst[x+y] = 0x0; - - } - } - } - if(mode == 0) - { - - // apply difference frame - for( i = 0; i < len ; i++) - { - if(dst[i] == 0xf0) - { - Y[i] = Y2[i]; - Cb[i] = Cb2[i]; - Cr[i] = Cr2[i]; - } - } - } - else - { - // show different pixels in white - for( i = 0; i < len ; i++) - { - if(dst[i] == 0xf0) - { - Y[i] = 200; - } - else - { - if(dst[i] != 0xff) - { - Y[i] = pixel_Y_lo_; - } - else - { - Y[i] = pixel_Y_hi_; - } - } - Cr[i] = 128; + Y[i] = 0; + Cb[i] = 128; Cr[i] = 128; } } diff --git a/veejay-current/libvje/effects/diff.h b/veejay-current/libvje/effects/diff.h index 9eaf58e2..ecdfb9bf 100644 --- a/veejay-current/libvje/effects/diff.h +++ b/veejay-current/libvje/effects/diff.h @@ -30,6 +30,6 @@ int diff_malloc(void **c, int w, int h); void diff_prepare(void *d, uint8_t *map[3], int w, int h); void diff_apply(void *d , VJFrame *frame, VJFrame *frame2, int width, int height, - int mode, int th, int noise, int n2); - + int th, int reverse, int show); +void diff_destroy(); #endif diff --git a/veejay-current/libvje/effects/diffmap.c b/veejay-current/libvje/effects/diffmap.c index cfdec682..da50d09e 100644 --- a/veejay-current/libvje/effects/diffmap.c +++ b/veejay-current/libvje/effects/diffmap.c @@ -52,14 +52,15 @@ vj_effect *differencemap_init(int w, int h) static uint8_t *binary_img = NULL; static uint8_t *previous_img = NULL; static int nframe = 0; +#define RUP8(num)(((num)+8)&~8) int differencemap_malloc(int w, int h ) { if(binary_img || previous_img) differencemap_free(); - binary_img = (uint8_t*) vj_malloc(sizeof(uint8_t) * w * h ); - previous_img = (uint8_t*) vj_malloc(sizeof(uint8_t) * w *h ); + binary_img = (uint8_t*) vj_malloc(sizeof(uint8_t) * RUP8(w*h*2) ); + previous_img = binary_img + RUP8(w*h); nframe = 0; if(!binary_img) return 0; return 1; @@ -69,8 +70,6 @@ void differencemap_free(void) { if(binary_img) free(binary_img); - if(previous_img) - free(previous_img); binary_img = NULL; previous_img = NULL; } diff --git a/veejay-current/libvje/effects/lumamask.c b/veejay-current/libvje/effects/lumamask.c index 8ec75b0d..890b9756 100644 --- a/veejay-current/libvje/effects/lumamask.c +++ b/veejay-current/libvje/effects/lumamask.c @@ -104,7 +104,7 @@ void lumamask_apply( VJFrame *frame, VJFrame *frame2, int width, ny = y + dy; - if( nx < 0 || ny < 0 || nx > width || ny >= height ) + if( nx < 0 || ny < 0 || nx >= width || ny >= height ) { Y[y*width+x] = 16; Cb[y*width+x] = 128; diff --git a/veejay-current/libvje/effects/neighbours4.c b/veejay-current/libvje/effects/neighbours4.c index 7c7f0455..ea71332a 100644 --- a/veejay-current/libvje/effects/neighbours4.c +++ b/veejay-current/libvje/effects/neighbours4.c @@ -154,7 +154,7 @@ static inline pixel_t evaluate_pixel_bc( { dx = points[i].x + x; dy = points[i].y + y; - if(dx < 0) dx = 0; else if (dx > w) dx = w; + if(dx < 0) dx = 0; else if (dx >= w) dx = w-1; if(dy < 0) dy = 0; else if (dy >= h) dy = h-1; brightness = premul[ dy * w + dx]; diff --git a/veejay-current/libvje/effects/softblur.c b/veejay-current/libvje/effects/softblur.c index 7b96cc42..d00d206b 100644 --- a/veejay-current/libvje/effects/softblur.c +++ b/veejay-current/libvje/effects/softblur.c @@ -120,7 +120,7 @@ void softblur3_apply(VJFrame *frame, int width, int height ) { * Authors: Dennis Smit */ -static void mmx_blur(uint8_t *buf, int width, int height) +static void mmx_blur(uint8_t *buffer, int width, int height) { __asm __volatile ("\n\t pxor %%mm6, %%mm6" @@ -129,7 +129,7 @@ static void mmx_blur(uint8_t *buf, int width, int height) int scrsh = height / 2; int i; int len = width * height; - + uint8_t *buf = buffer; /* Prepare substraction register */ for (i = 0; i < scrsh; i += 4) { __asm __volatile @@ -155,7 +155,7 @@ static void mmx_blur(uint8_t *buf, int width, int height) // : "mm0", "mm1", "mm2", "mm3", "mm6"); } - for (i = len - 1; i > scrsh; i -= 4) { + for (i = len - 4; i > scrsh; i -= 4) { __asm __volatile ("\n\t movd %[buf], %%mm0" "\n\t movd %[add1], %%mm1" diff --git a/veejay-current/libvje/effects/threshold.c b/veejay-current/libvje/effects/threshold.c index b4b4a5f6..c712b5f3 100644 --- a/veejay-current/libvje/effects/threshold.c +++ b/veejay-current/libvje/effects/threshold.c @@ -48,10 +48,11 @@ vj_effect *threshold_init(int w, int h) static uint8_t *binary_img; +#define RUP8(num)(((num)+8)&~8) int threshold_malloc(int w, int h ) { - binary_img = (uint8_t*) vj_malloc(sizeof(uint8_t) * w * h ); + binary_img = (uint8_t*) vj_malloc(sizeof(uint8_t) * RUP8(w * h) ); if(!binary_img) return 0; return 1; } diff --git a/veejay-current/libvje/internal.h b/veejay-current/libvje/internal.h index 95aec9c7..a5d344cd 100644 --- a/veejay-current/libvje/internal.h +++ b/veejay-current/libvje/internal.h @@ -362,7 +362,7 @@ extern void whiteframe_apply(VJFrame *frame, VJFrame *frame2, extern void diff_apply(void *dd, VJFrame *frame, VJFrame *frame2, int width, int height, - int mode, int threshold, int c, int d); + int mode, int threshold, int c ); extern void chromamagick_apply(VJFrame *frame, VJFrame *frame2, int width, int height, int type, int op0); @@ -546,4 +546,6 @@ extern void autoeq_apply( VJFrame *frame, int width, int height, int val, int i, extern void colorhis_apply( VJFrame *frame, int w, int h, int v, int m, int i, int s ); +extern void diff_destroy(); + #endif diff --git a/veejay-current/libvje/plugload.c b/veejay-current/libvje/plugload.c index 3f8bb4c1..6b455127 100644 --- a/veejay-current/libvje/plugload.c +++ b/veejay-current/libvje/plugload.c @@ -384,7 +384,9 @@ static void* deal_with_ff( void *handle, char *name ) for( p= 0; p < n_params; p ++ ) { void *parameter = vpn( VEVO_FF_PARAM_PORT ); - +#ifdef STRICT_CHECKING + assert( parameter != NULL ); +#endif int type = q( FF_GETPARAMETERTYPE, (LPVOID) p, 0 ).ivalue; // name, kind, flags, description, min,max,default,transition vevo_property_set( parameter, "type", VEVO_ATOM_TYPE_INT, 1, &type); @@ -504,6 +506,34 @@ static void deinstantiate_plugin( void *plugin ) } } +static int is_so( const char *file ) +{ + if( strstr(file, ".so" ) || strstr( file, ".SO" ) ) + return 1; + return 0; +} + +static int is_valid_plugin( const char *file ) +{ + if(!file) + return 0; + struct stat l; + veejay_memset( &l, 0, sizeof( struct stat)); + if ( lstat( file, &l ) < 0 ) + return 0; + + if( S_ISDIR( l.st_mode )) + return 0; + + if( S_ISREG( l.st_mode )) + { + if( is_so(file) ) + return 1; + } + return 0; + +} + static void add_to_plugin_list( const char *path ) { if(!path) @@ -557,6 +587,12 @@ static void add_to_plugin_list( const char *path ) sprintf(fullname, "%s/%s", path,name ); + //@ check if name is regular file + if( is_valid_plugin( fullname ) == 0 ) + { + continue; + } + void *handle = dlopen(fullname, RTLD_NOW ); if(handle) @@ -655,19 +691,21 @@ static void scan_plugins() char *home = getenv( "HOME" ); char path[PATH_MAX]; char data[CONFIG_FILE_LEN]; - if(!home) return; - - sprintf( path , "%s/.veejay/plugins" , home ); + if(!home) + { + veejay_msg(VEEJAY_MSG_ERROR, "Environment variable HOME not set!"); + return; + } + sprintf( path , "%s/.veejay/plugins.cfg" , home ); int fd = open( path, O_RDONLY ); if( fd < 0 ) { - veejay_msg(VEEJAY_MSG_ERROR, "Cant open '~/.veejay/plugins. No plugins loaded"); + veejay_msg(VEEJAY_MSG_ERROR, "Cant open %s", path); return; } - veejay_msg(VEEJAY_MSG_INFO, "Parsing %s", path ); - bzero( data, CONFIG_FILE_LEN ); + veejay_memset( data, 0, CONFIG_FILE_LEN ); if( read( fd, data, CONFIG_FILE_LEN ) > 0 ) { @@ -676,13 +714,13 @@ static void scan_plugins() int k = 0; char value[PATH_MAX]; - bzero( value, PATH_MAX ); + veejay_memset( value,0, PATH_MAX ); for( j=0; j < len; j ++ ) { if(data[j] == '\0' ) break; if( data[j] == '\n' ) - { add_to_plugin_list( value ); bzero(value,PATH_MAX); k =0;} + { add_to_plugin_list( value ); veejay_memset(value,0,PATH_MAX); k =0;} if( isascii( data[j] ) && data[j] != '\n') { value[k] = data[j]; if( k < PATH_MAX) k ++; } diff --git a/veejay-current/libvje/vj-effect.c b/veejay-current/libvje/vj-effect.c index ea11a74c..66d46b48 100644 --- a/veejay-current/libvje/vj-effect.c +++ b/veejay-current/libvje/vj-effect.c @@ -603,10 +603,13 @@ void vj_effect_shutdown() { if(vj_effects[i]) { if( i >= MAX_EFFECTS ) if(vj_effects[i]->description) free(vj_effects[i]->description); - vj_effect_free(vj_effects[i]); + vj_effect_free(vj_effects[i]); } } + + diff_destroy(); + } void vj_effect_dump() { diff --git a/veejay-current/libvje/vj-effman.c b/veejay-current/libvje/vj-effman.c index 37e209f8..35ba180f 100644 --- a/veejay-current/libvje/vj-effman.c +++ b/veejay-current/libvje/vj-effman.c @@ -441,7 +441,7 @@ void vj_effman_apply_video_effect( VJFrame **frames, VJFrameInfo *frameinfo ,vjp break; case VJ_VIDEO_EFFECT_DIFF: diff_apply( vj_effects[entry]->user_data, frames[0], frames[1], - frameinfo->width, frameinfo->height, arg[0], arg[1],arg[2],arg[3]); + frameinfo->width, frameinfo->height, arg[0], arg[1],arg[2]); break; case VJ_VIDEO_EFFECT_WHITEFRAME: @@ -563,22 +563,28 @@ void vj_effman_apply_video_effect( VJFrame **frames, VJFrameInfo *frameinfo ,vjp } -int vj_effect_prepare( VJFrame *frame, VJFrameInfo *frameinfo, int selector) +int vj_effect_prepare( VJFrame *frame, int selector) { + veejay_msg(VEEJAY_MSG_DEBUG, "Found FX %d", selector); if(selector == VJ_VIDEO_EFFECT_DIFF && vj_effect_has_cb(selector)) { int i = vj_effect_real_to_sequence( selector ); + veejay_msg(VEEJAY_MSG_DEBUG,"internal id = %d", i ); if( vj_effects[i]->user_data != NULL) { diff_prepare( (void*) vj_effects[i]->user_data, frame->data, - frameinfo->width, - frameinfo->height ); + frame->width, + frame->height ); return 1; } } + else + { + veejay_msg(VEEJAY_MSG_ERROR,"There is currently no FX that needs a background image"); + } return 0; } diff --git a/veejay-current/libvje/vje.h b/veejay-current/libvje/vje.h index 7b05032a..db44d023 100644 --- a/veejay-current/libvje/vje.h +++ b/veejay-current/libvje/vje.h @@ -135,7 +135,7 @@ extern int vj_effect_get_max_v(); extern int vj_effect_get_by_name(char *name); extern int vj_effect_apply( VJFrame **frames, VJFrameInfo *frameinfo, vjp_kf *kf, int selector, int *arguments ); -extern int vj_effect_prepare( VJFrame *frame, VJFrameInfo *frameinfo, int selector); +extern int vj_effect_prepare( VJFrame *frame, int selector); extern void vj_effect_dump(void); diff --git a/veejay-current/libvjnet/Makefile.am b/veejay-current/libvjnet/Makefile.am index bf47dfc1..063c9fa7 100644 --- a/veejay-current/libvjnet/Makefile.am +++ b/veejay-current/libvjnet/Makefile.am @@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in AM_CFLAGS=$(OP_CFLAGS) -INCLUDES = -I$(top_srcdir) -I$(includedir) -I$(top_srcdir)/vjmem -I$(top_srcdir)/vjmsg +INCLUDES = -I$(top_srcdir) -I$(includedir) -I$(top_srcdir)/libyuv -I$(top_srcdir)/liblzo -I$(top_srcdir)/vjmem -I$(top_srcdir)/vjmsg VJNET_LIB_FILE = libvjnet.la noinst_LTLIBRARIES = $(VJNET_LIB_FILE) libvjnet_la_SOURCES = packet.c mcastsender.c mcastreceiver.c cmd.c vj-server.c vj-client.c diff --git a/veejay-current/libvjnet/cmd.c b/veejay-current/libvjnet/cmd.c index b7707adb..d2ce4ad1 100644 --- a/veejay-current/libvjnet/cmd.c +++ b/veejay-current/libvjnet/cmd.c @@ -61,31 +61,25 @@ int sock_t_connect( vj_sock_t *s, char *host, int port ) return 1; } -int sock_t_poll_w( vj_sock_t *s ) +int sock_t_poll_w(vj_sock_t *s ) { - int status; - fd_set fds; - struct timeval no_wait; - memset( &no_wait, 0, sizeof(no_wait) ); + int status; + fd_set fds; + struct timeval no_wait; + memset( &no_wait, 0, sizeof(no_wait) ); - FD_ZERO( &fds ); - FD_SET( s->sock_fd, &fds ); + FD_ZERO( &fds ); + FD_SET( s->sock_fd, &fds ); - status = select( s->sock_fd + 1, 0,&fds, 0, &no_wait ); - if( status < 0 ) - { - veejay_msg(VEEJAY_MSG_ERROR, "%s", strerror(errno)); - return 0; - } - - if( FD_ISSET( s->sock_fd, &fds ) ) - { - return 1; - } - return 0; + status = select( s->sock_fd + 1,NULL, &fds, NULL, &no_wait ); + if( status < 0 ) + { + veejay_msg(VEEJAY_MSG_ERROR, "%s", strerror(errno)); + return 0; + } + return status; } - - + int sock_t_poll( vj_sock_t *s ) { diff --git a/veejay-current/libvjnet/mcastreceiver.c b/veejay-current/libvjnet/mcastreceiver.c index cd777f83..a7fba295 100644 --- a/veejay-current/libvjnet/mcastreceiver.c +++ b/veejay-current/libvjnet/mcastreceiver.c @@ -1,6 +1,6 @@ /* vjnet - low level network I/O for VeeJay * - * (C) 2005 Niels Elburg + * (C) 2005-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include @@ -33,6 +34,22 @@ #include #include "packet.h" #include "common.h" +#include +#include +#ifdef STRICT_CHECKING +#include +#endif + +typedef struct +{ + uint8_t *packet; + uint32_t *len; + packet_header_t hdr; + frame_info_t inf; + uint32_t packets; + uint32_t length; +} frame_next_t; + static void print_error(char *msg) { veejay_msg(VEEJAY_MSG_ERROR,"%s: %s\n", msg,strerror(errno)); @@ -40,13 +57,13 @@ static void print_error(char *msg) mcast_receiver *mcast_new_receiver( const char *group_name, int port ) { - mcast_receiver *v = (mcast_receiver*) malloc(sizeof(mcast_receiver)); + mcast_receiver *v = (mcast_receiver*) vj_calloc(sizeof(mcast_receiver)); if(!v) return NULL; int on = 1; struct ip_mreq mcast_req; - memset( &mcast_req, 0, sizeof(mcast_req )); - memset( &(v->addr), 0, sizeof(struct sockaddr_in) ); + veejay_memset( &mcast_req, 0, sizeof(mcast_req )); + veejay_memset( &(v->addr), 0, sizeof(struct sockaddr_in) ); v->group = (char*) strdup( group_name ); v->port = port; @@ -143,7 +160,7 @@ static int mcast_poll_timeout( mcast_receiver *v, long timeout ) struct timeval tv; int n = 0; tv.tv_sec = 0; - tv.tv_usec = 80000 + timeout; // 0.05 seconds + tv.tv_usec = timeout; // 0.05 seconds FD_ZERO( &fds ); FD_SET( v->sock_fd, &fds ); @@ -168,97 +185,226 @@ int mcast_recv( mcast_receiver *v, void *buf, int len ) return n; } +int mcast_store_next_packet( mcast_receiver *v , packet_header_t *h, frame_info_t *i, uint8_t *payload) +{ + uint8_t *chunk = payload + (sizeof(packet_header_t) + sizeof(frame_info_t)); + if(v->next == NULL ) + v->next = (void*) vj_calloc(sizeof(frame_next_t)); + frame_next_t *n = (frame_next_t*) v->next; + int res = 1; + if(n->packet == NULL) + { + n->packet = vj_malloc( CHUNK_SIZE + ( h->length * CHUNK_SIZE) ); + n->length = h->length; + veejay_memcpy( &(n->hdr), h, sizeof(packet_header_t)); + veejay_memcpy( &(n->inf), i, sizeof(frame_info_t)); + } + else + { + //@ must have same timestamp + if( h->usec != n->hdr.usec ) + { + veejay_msg(0,"Cannot keep pace with sending veejay? Next frame:[tdiff=%d], In frame: [tdiff=%d], have %d/%d", + n->hdr.usec, h->usec, n->packets,h->length ); + return 0; + } -int mcast_recv_frame( mcast_receiver *v, uint8_t *linear_buf, int total_len ) + } + + + //@ store compressed data + veejay_memcpy( n->packet + (CHUNK_SIZE * h->seq_num), chunk, CHUNK_SIZE); + n->packets ++; + + if( n->packets >= n->length ) + res = 2; + + return res; +} + + +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 n_packets = ( total_len / CHUNK_SIZE); int i=0; int tb=0; uint8_t chunk[PACKET_PAYLOAD_SIZE]; packet_header_t header; frame_info_t info; - header.timeout = 20000; // first time timeout + veejay_memset(&header,0,sizeof(packet_header_t)); - while( i <= n_packets ) + int res = 0; + int n_packet = 0; + int total_recv = 0; + int packet_len = CHUNK_SIZE; + int nos =0; + + if( mcast_poll_timeout( v, header.timeout ) == 0 ) { - uint8_t *dst = linear_buf; - int n; + return 0; + } - retry: + //@ there is a packet, get it. - /* there may not be any data (packet never arrived) */ - /* Bah... we must take note that some packets will never arrive */ - if( mcast_poll_timeout(v, header.timeout) == 0 ) +/* if(v->next) + { + frame_next_t *pn = (frame_next_t*) v->next; + packet_len = pn->inf.len; + total_recv = (pn->packets * CHUNK_SIZE); + veejay_memcpy( &header, &(pn->hdr), sizeof(packet_header_t)); + n_packet = pn->packets; + nos = 1; + } +*/ + + while( total_recv < packet_len ) + { + int put_data = 1; + res = recv(v->sock_fd, chunk, PACKET_PAYLOAD_SIZE, 0 ); + if( res <= 0 ) { + veejay_msg(VEEJAY_MSG_DEBUG, "Nothing there to read!"); return 0; - } - /* peek , dont remove data from queue */ - n = recv( v->sock_fd, chunk, PACKET_PAYLOAD_SIZE, MSG_PEEK ); - if( n <= 0) - { - veejay_msg(VEEJAY_MSG_ERROR, "cannot read more data, only got %d bytes (%d)", tb,n ); - print_error("recv frame"); - goto error; - } - /* read header */ - header = packet_get_header( chunk ); - - /* first packet received, set timestamp */ - if( i == 0 ) - { - sec = header.sec; - usec = header.usec; - } - - if( sec != header.sec || usec != header.usec ) - { - /* ignore old frames */ - if( header.usec < usec || header.sec < sec ) - { - n = recv( v->sock_fd, chunk, PACKET_PAYLOAD_SIZE,0 ); - if( n <= 0 ) - { - veejay_msg(VEEJAY_MSG_ERROR, "error flushing data!"); - } - i = 0; + } - goto retry; - } - /* got newer packet, take this packet (ignore 'current') */ - if( header.usec > usec || header.sec > sec ) - { - i = 0; - goto retry; - } - - goto error; - } - if( header.seq_num > n_packets ) + packet_header_t hdr = packet_get_header( chunk ); +// packet_dump_header(&hdr); + packet_get_info(&info,chunk ); + + //@ do the first packet +/*if( n_packet==0 ) { - veejay_msg(VEEJAY_MSG_ERROR, "invalid sequence number! %d / %d", header.seq_num, n_packets); - goto error; +#ifdef STRICT_CHECKING + assert( hdr.flag == 1 ); +#endif + *dw = info.width; + *dh = info.height; + *dfmt = info.fmt; + packet_len = info.len; + veejay_memcpy( &header,&hdr, sizeof(packet_header_t)); } - - /* get the data */ - packet_get_data( &header, &info, chunk, dst ); - - /* remove data from receive queue */ - n = recv( v->sock_fd, chunk, PACKET_PAYLOAD_SIZE, 0 ); - if( n <= 0 ) + else { - veejay_msg(VEEJAY_MSG_ERROR, "error removing data from receive queue"); + //@ more packets follow + if( hdr.usec != header.usec ) + { + //@ this packet is older! + if( hdr.usec < header.usec ) + { + //@ check for rollover + if(hdr.usec <= 1 && header.usec >= 0xffff ) + { + veejay_msg(0, "ROLLOVER INTEGER"); + // header.usec = 0; + // if( hdr.usec <= (header.usec + 1 ) ) + // mcast_store_next_packet( v, &hdr,&info,chunk); + } + + put_data = 0; + veejay_msg(0, "Dropped old packet: time=%d, current=%d", hdr.usec, header.usec); + } + else + { + veejay_msg(0, "DROP OLD header %d, take %d", header.usec, hdr.usec ); + packet_len = info + + + + + if(!nos) + { + int mr = mcast_store_next_packet(v, &hdr, &info, chunk ); + if(mr <= 0) + { + packet_len = info.len; + veejay_memcpy( &header, &hdr, sizeof(packet_header_t)); + n_packet = 0; + put_data = 1; + veejay_msg(0, "Out of Pace, take newest packets"); + } + else + { + if( mr == 2 ) + { + uint8_t *dst = linear_buf; + frame_next_t *pn = v->next; +veejay_msg(0, "NEWEST BUFFER FULL, DROP TIMECODE %d, continue with %d", header.usec, pn->hdr.usec); + *dw = pn->inf.width; + *dh = pn->inf.height; + *dfmt = pn->inf.fmt; + + veejay_memcpy( dst, pn->packet, pn->inf.len ); + free(pn->packet); + free(pn); + v->next=NULL; + return pn->inf.len; + } + else + put_data = 0; + } + } + } + } } - tb += n; - i++; - } + */ - return 1; + if( n_packet == 0 ) + { + packet_len = info.len; + veejay_memcpy(&header,&hdr,sizeof(packet_header_t)); + total_recv = 0; + } - error: + if( header.usec != hdr.usec ) + { + if( hdr.usec < header.usec ) + put_data = 0; + else + { + total_recv = 0; + n_packet = 0; + packet_len = info.len; + veejay_memcpy( &header,&hdr,sizeof(packet_header_t)); + } + } - return 0; + + if( put_data ) + { + uint8_t *dst; + dst = linear_buf + (CHUNK_SIZE * hdr.seq_num ); + packet_get_data( &hdr, chunk, dst ); + total_recv += CHUNK_SIZE; + } + + if( n_packet >= hdr.length ) + { + break; + } + + if(put_data) + n_packet ++; + + } + +#ifdef STRICT_CHECKING + assert( total_recv >= packet_len ); +#endif +/* + if(nos) + { + frame_next_t *pn = v->next; + free(pn->packet); + free(pn); + v->next = NULL; + }*/ + *dw = info.width; + *dh = info.height; + *dfmt = info.fmt; + + return packet_len; } @@ -269,5 +415,12 @@ void mcast_close_receiver( mcast_receiver *v ) close(v->sock_fd); if(v->group) free(v->group); v->group = NULL; + if(v->next) + { + frame_next_t *pn = v->next; + free(pn->packet); + free(pn); + } + v->next = NULL; } } diff --git a/veejay-current/libvjnet/mcastreceiver.h b/veejay-current/libvjnet/mcastreceiver.h index 2913b154..eda68b42 100644 --- a/veejay-current/libvjnet/mcastreceiver.h +++ b/veejay-current/libvjnet/mcastreceiver.h @@ -1,6 +1,6 @@ /* vjnet - low level network I/O for VeeJay * - * (C) 2005 Niels Elburg + * (C) 2005-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -38,6 +38,9 @@ typedef struct int port; int sock_fd; int recv_buf_size; + uint8_t *space; + int space_len; + void *next; } mcast_receiver; mcast_receiver *mcast_new_receiver( const char *group_name, int port ); @@ -46,7 +49,8 @@ int mcast_poll( mcast_receiver *v ); int mcast_recv( mcast_receiver *v, void *dst, int len ); -int mcast_recv_frame( mcast_receiver *v, uint8_t *linear_buf , int total_len); +int mcast_recv_frame( mcast_receiver *v, uint8_t *linear_buf , int total_len, int cw, int ch, int fmt, + int *dw, int *dh, int *df); void mcast_close_receiver( mcast_receiver *v ); diff --git a/veejay-current/libvjnet/mcastsender.c b/veejay-current/libvjnet/mcastsender.c index 9e19e4b5..e625af33 100644 --- a/veejay-current/libvjnet/mcastsender.c +++ b/veejay-current/libvjnet/mcastsender.c @@ -1,6 +1,6 @@ /* vjnet - low level network I/O for VeeJay * - * (C) 2005 Niels Elburg + * (C) 2005-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include "mcastsender.h" #include #include @@ -26,6 +26,9 @@ #include #include "common.h" #include "packet.h" +#ifdef STRICT_CHECKING +#include +#endif static void print_error(char *msg) { @@ -44,7 +47,7 @@ mcast_sender *mcast_new_sender( const char *group_name ) v->addr_len = sizeof( struct sockaddr_in ); v->sock_fd = socket( AF_INET, SOCK_DGRAM, 0 ); v->send_buf_size = 240 * 1024; - + v->stamp = 0; if( v->sock_fd == -1 ) { print_error( "socket"); @@ -140,8 +143,18 @@ int mcast_send( mcast_sender *v, const void *buf, int len, int port_num ) return n; } +static void stamp_reset( mcast_sender *v ) +{ + v->stamp = 0; +} -int mcast_send_frame( mcast_sender *v, const VJFrame *frame, const VJFrameInfo *descr, +static uint32_t stamp_make( mcast_sender *v ) +{ + v->stamp ++; + return v->stamp; +} + +int mcast_send_frame( mcast_sender *v, const VJFrame *frame, uint8_t *buf, int total_len, long ms,int port_num) { int n_chunks = total_len / CHUNK_SIZE; @@ -149,27 +162,69 @@ int mcast_send_frame( mcast_sender *v, const VJFrame *frame, const VJFrameInfo int tb = 0; packet_header_t header = packet_construct_header( 1 ); frame_info_t info; - /* 1 = 4:2:2 planer, 0 = 4:2:0 planar */ - info.fmt = (frame->shift_v == 0 ? 1 : 0); - info.width = descr->width; - info.height = descr->height; - header.timeout = ms * 10000; -// header.timeout = 22000; - uint8_t chunk[PACKET_PAYLOAD_SIZE]; + info.fmt = frame->format; + info.width = frame->width; + info.height = frame->height; + info.len = total_len; - for ( i = 0 ; i <= n_chunks ; i ++ ) + uint32_t frame_num = stamp_make(v); + + header.timeout = ms * 10000; + header.sec = 0; + header.usec = frame_num; + + uint8_t chunk[PACKET_PAYLOAD_SIZE]; + int res = 0; + + //@ If we can send in a single packet: + if( total_len <= CHUNK_SIZE ) { - const uint8_t *data = buf + (i * CHUNK_SIZE ); - int n; + header.seq_num = 0; header.flag = 1; header.length = 0; + packet_put_padded_data( &header,&info, chunk, buf, total_len); + packet_dump_header(&header); + res = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); + if(res <= 0 ) + return -1; + return 1; + } + + + int pred_chunks = (total_len / CHUNK_SIZE); + int bytes_left = (total_len % CHUNK_SIZE); + + header.length = pred_chunks + ( bytes_left > 0 ? 1 : 0 ); + + for( i = 0; i < pred_chunks; i ++ ) + { + const uint8_t *data = buf + (i * CHUNK_SIZE); header.seq_num = i; - packet_put_data( &header, &info, chunk, data ); - n = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); - if(n <= 0) + header.flag = 1; + packet_put_data( &header, &info, chunk, data ); + res = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); + if(res <= 0 ) { + veejay_msg(0,"Unable to send packet %d out of %d", i, pred_chunks ); return -1; } - tb += n; - } + } + + if( bytes_left ) + { + i = header.length-1; + header.seq_num = i; + header.flag = 1; + int bytes_done = packet_put_padded_data( &header, &info, chunk, buf + (i * CHUNK_SIZE), bytes_left ); + veejay_memset( chunk + bytes_done, 0, (PACKET_PAYLOAD_SIZE-bytes_done)); + res = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); + if( res <= 0 ) + { + veejay_msg(0, "Unable to send last packet"); + return -1; + } + } + + if( frame_num == 0xffff ) + stamp_reset(v); return 1; } diff --git a/veejay-current/libvjnet/mcastsender.h b/veejay-current/libvjnet/mcastsender.h index 3163b8d4..9d3bc4b1 100644 --- a/veejay-current/libvjnet/mcastsender.h +++ b/veejay-current/libvjnet/mcastsender.h @@ -1,6 +1,6 @@ /* vjnet - low level network I/O for VeeJay * - * (C) 2005 Niels Elburg + * (C) 2005-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ #include #include #include - +#include typedef struct { char *group; @@ -37,6 +37,7 @@ typedef struct int addr_len; struct sockaddr_in addr; int send_buf_size; + uint32_t stamp; } mcast_sender; mcast_sender *mcast_new_sender( const char *group_name ); @@ -44,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 ,const VJFrameInfo *descr, 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 ); void mcast_close_sender(mcast_sender *s ); diff --git a/veejay-current/libvjnet/packet.c b/veejay-current/libvjnet/packet.c index 7cb1a108..cb8e0b82 100644 --- a/veejay-current/libvjnet/packet.c +++ b/veejay-current/libvjnet/packet.c @@ -17,14 +17,22 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include "packet.h" +#ifdef STRICT_CHECKING +#include +#endif + void packet_dump_header( packet_header_t *h) { - veejay_msg(VEEJAY_MSG_DEBUG, "Flag: %x, Sequence Num %x/%d, Timestamp %x:%x Timeout : %ld", - h->flag, h->seq_num,h->seq_num, h->sec, h->usec,h->timeout ); +#ifdef STRICT_CHECKING + assert( h != NULL ); +#endif + veejay_msg(VEEJAY_MSG_DEBUG, "Flag: %x, Sequence Num %d/%d, Timestamp %x:%x Timeout : %ld", + h->flag, h->seq_num,h->length, h->sec, h->usec,h->timeout ); } packet_header_t packet_construct_header(uint8_t flag) @@ -36,7 +44,8 @@ packet_header_t packet_construct_header(uint8_t flag) header.seq_num = 0; // not set header.sec = tv.tv_sec; header.usec = tv.tv_usec; - header.timeout = 350000; + header.timeout = 1000; + header.length = 0; return header; } @@ -46,40 +55,44 @@ packet_header_t packet_get_header(const void *data) veejay_memcpy( &tmp, data, sizeof(packet_header_t) ); h.flag = tmp.flag; h.seq_num = tmp.seq_num; - h.sec = tmp.sec ; - h.usec = tmp.usec ; + h.sec = tmp.sec; + h.length = tmp.length; + h.usec = tmp.usec; h.timeout = tmp.timeout; return h; } -int packet_get_data(packet_header_t *h, frame_info_t *i, const void *data, uint8_t *plane ) +int packet_get_data(packet_header_t *h, const void *data, uint8_t *plane ) { size_t len = sizeof(packet_header_t); - - if(h->flag) - { - veejay_memcpy( i, data + sizeof(packet_header_t) , sizeof( frame_info_t )); - len += sizeof( frame_info_t ); - } - - veejay_memcpy( plane + (CHUNK_SIZE * h->seq_num) , data + len, CHUNK_SIZE ); + len += sizeof( frame_info_t ); + veejay_memcpy( plane , data + len, CHUNK_SIZE ); return 1; } +int packet_get_info(frame_info_t *i, const void *data ) +{ + size_t len = sizeof(packet_header_t); + veejay_memcpy(i, data + sizeof(packet_header_t), sizeof(frame_info_t)); + return 1; +} + +int packet_put_padded_data(packet_header_t *h, frame_info_t *i , void *payload, const uint8_t *plane, int bytes ) +{ + size_t len = sizeof( packet_header_t ); + veejay_memcpy( payload, h , len ); + veejay_memcpy( payload + len, i , sizeof( frame_info_t )); + len += sizeof(frame_info_t ); + veejay_memcpy( payload + len, plane, bytes ); + return (len + bytes); +} int packet_put_data(packet_header_t *h, frame_info_t *i , void *payload, const uint8_t *plane ) { size_t len = sizeof( packet_header_t ); - veejay_memcpy( payload, h , len ); - - if(h->flag) - { - veejay_memcpy( payload + len, i , sizeof( frame_info_t )); - len += sizeof(frame_info_t ); - } - + veejay_memcpy( payload + len, i , sizeof( frame_info_t )); + len += sizeof(frame_info_t ); veejay_memcpy( payload + len, plane, CHUNK_SIZE ); - return 1; } diff --git a/veejay-current/libvjnet/packet.h b/veejay-current/libvjnet/packet.h index 96db92ef..430d251c 100644 --- a/veejay-current/libvjnet/packet.h +++ b/veejay-current/libvjnet/packet.h @@ -1,6 +1,6 @@ /* vjnet - low level network I/O for VeeJay * - * (C) 2005 Niels Elburg + * (C) 2005-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -26,52 +26,8 @@ Veejay - Video streaming over UDP (Multicast) Veejay doesnt care about dropped packet. Dropped packet means drop frame. -video packet header is 16 bytes in length: +Ignoring machine byte order. Fix it yourself -0------8-----......-16---....----48--...------96-- .... 128 -flag | seq. num | time sec | time msec | timeout | ------------------------------------------------------------ - -flag: - if this flag is set, the fixed header is followed by 1 header extension, - that describes the video format for the application - -seq.num: - the sequence number increments by one for each data packet sent, it - is used by the receiver to restore the video frame. the initial value is 0. - -time sec: -time usec: - the timestamp ; the time set from a clock that increments monotonically and - linear in time (to allow synchronization and detection of jittering). - currently, the absolute value of the system clock is used but this will - be changed in later revisions. - -timeout: - the recommended timeout (set by sender) to use the smallest timeout possible - on the receiver end. - - -video format header is 5 bytes in length -0----...16 -----.... 32 ---- 48 -| width | height | format| -------------------------------- - -width: - the width of the video frame - -height: - the height of the video frame - -format: - the format of the video frame - veejay works nativly with YUV 4:2:0 / 4:2:2 Planar (First come all Y, then all Cb, then all Cr) - therefore 0 = 420 , 1 = 422 (for now) - - -Note that this code is very naive ; it does not do byteswapping for -little/big endian machines. Also this is on the TODO list! -Meaning thus veejay x86 cannot communicate with veejay ppc !!! */ #include @@ -85,6 +41,7 @@ typedef struct uint32_t sec; uint32_t usec; uint32_t timeout; + uint32_t length; } packet_header_t; typedef struct @@ -92,13 +49,13 @@ typedef struct uint16_t width; uint16_t height; uint8_t fmt; + uint32_t len; } frame_info_t; -#define CHUNK_SIZE 16384 #define PACKET_HEADER_LENGTH ( sizeof(packet_header_t) ) #define PACKET_APP_HEADER_LENGTH ( sizeof(frame_info_t) ) - +#define CHUNK_SIZE 2048 #define PACKET_PAYLOAD_SIZE (CHUNK_SIZE + PACKET_HEADER_LENGTH + PACKET_APP_HEADER_LENGTH ) void packet_dump_header( packet_header_t *h); @@ -107,8 +64,11 @@ packet_header_t packet_construct_header(uint8_t flag); packet_header_t packet_get_header(const void *data); -int packet_get_data( packet_header_t *h, frame_info_t *i, const void *data, uint8_t *plane); +int packet_get_data( packet_header_t *h, const void *data, uint8_t *plane); int packet_put_data( packet_header_t *h, frame_info_t *i, void *payload, const uint8_t *plane ); +int packet_put_padded_data( packet_header_t *h, frame_info_t *i, void *payload, const uint8_t *plane, int bytes ); + +int packet_get_info(frame_info_t *i, const void *data ); #endif diff --git a/veejay-current/libvjnet/vj-client.c b/veejay-current/libvjnet/vj-client.c index d7e38ef1..fc0f2e28 100644 --- a/veejay-current/libvjnet/vj-client.c +++ b/veejay-current/libvjnet/vj-client.c @@ -1,5 +1,5 @@ /* libvjnet - Linux VeeJay - * (C) 2002-2004 Niels Elburg + * (C) 2002-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -34,6 +34,8 @@ #include #include #include +#include +#include #define VJC_OK 0 #define VJC_NO_MEM 1 #define VJC_SOCKET 2 @@ -44,26 +46,24 @@ vj_client *vj_client_alloc( int w, int h, int f ) { vj_client *v = (vj_client*) malloc(sizeof(vj_client)); + memset(v, 0, sizeof(vj_client)); if(!v) { return NULL; } - v->planes[0] = 0; - v->planes[1] = 0; - v->planes[2] = 0; - // recv. format / w/h v->cur_width = w; v->cur_height = h; v->cur_fmt = f; + v->space = NULL; +// v->lzo = lzo_new(); v->c = (conn_type_t**) malloc(sizeof(conn_type_t*) * 3); v->c[0] = (conn_type_t*) malloc(sizeof(conn_type_t)); v->c[1] = (conn_type_t*) malloc(sizeof(conn_type_t)); v->c[2] = (conn_type_t*) malloc(sizeof(conn_type_t)); v->blob = (unsigned char*) malloc(sizeof(unsigned char) * PACKET_LEN ); v->mcast = 0; - if(!v->blob) - return NULL; - bzero( v->blob, PACKET_LEN ); + if( w > 0 && h > 0 ) + v->space = (uint8_t*) malloc( sizeof(uint8_t) * SOCKETFRAMELEN ); return v; } @@ -81,6 +81,10 @@ void vj_client_free(vj_client *v) free(v->c); if(v->blob) free(v->blob); + if(v->lzo) + free(v->lzo); + if(v->space) + free(v->space); free(v); } } @@ -178,28 +182,56 @@ int vj_client_poll( vj_client *v, int sock_type ) return 0; } -int vj_client_read_i( vj_client *v, uint8_t *dst ) +static void vj_client_decompress( vj_client *t, uint8_t *out, int len, int Y, int UV) +{ + uint8_t *d[3] = { + out, + out + Y, + out + Y + UV }; + + lzo_decompress( t->lzo, t->space, len, d ); +} + +int vj_client_read_i( vj_client *v, uint8_t *dst, int len ) { -// int len = v->planes[0] + v->planes[1] + v->planes[2]; -// char line[32]; char line[32]; int p[4] = {0, 0,0,0 }; int n = 0; int plen = 0; + int conv = 1; + int y_len = 0; + int uv_len = 0; if( v->c[0]->type == VMCAST_C ) { - veejay_msg(0, "FIXME: mcast sender"); - return 0; -// return mcast_recv_frame( v->c[0]->r, dst, 0 ); - } - veejay_memset( line,0, sizeof(line)); -// bzero(line,12); -// if( vj_client_poll( v, V_CMD ) <= 0 ) -// { -// veejay_msg(VEEJAY_MSG_DEBUG, "Frame not ready"); -// return 0; -// } + plen = mcast_recv_frame( v->c[0]->r, v->space, 0, v->cur_width,v->cur_height,v->cur_fmt, + &p[0],&p[1],&p[2] ); + if(plen <= 0) + return 0; + v->in_width = p[0]; + v->in_height = p[1]; + v->in_fmt = p[2]; + + uv_len = 0; + y_len = p[0] * p[1]; + switch(v->in_fmt ) + { + case FMT_420F: + case FMT_420: + uv_len = y_len/4; break; + default: + uv_len = y_len/2;break; + } + + if(plen) + vj_client_decompress( v, dst,plen,y_len,uv_len ); + + if( p[0] != v->cur_width || p[1] != v->cur_height || p[2] != v->cur_fmt ) + return 2; + return 1; + } + + veejay_memset( line,0, sizeof(line)); if( v->c[0]->type == VSOCK_C ) plen = sock_t_recv_w( v->c[0]->fd, line, 20 ); @@ -208,23 +240,40 @@ int vj_client_read_i( vj_client *v, uint8_t *dst ) veejay_msg(VEEJAY_MSG_ERROR, "Frame header error"); return -1; } - n = sscanf( line, "%d %d %d %d", p + 0 , p + 1, p + 2, p + 3 ); + n = sscanf( line, "%d %d %d %d", &p[0],&p[1],&p[2],&p[3] ); if( n != 4) { - veejay_msg(VEEJAY_MSG_ERROR,"Frame header invalid %s",line); + veejay_msg(VEEJAY_MSG_ERROR,"Frame header invalid"); return -1; } + if( v->cur_width != p[0] || v->cur_height != p[1] || v->cur_fmt != p[2]) + conv = 2; + + v->in_width = p[0]; + v->in_height = p[1]; + v->in_fmt = p[2]; + uv_len = 0; + y_len = p[0] * p[1]; + switch(v->in_fmt ) { - veejay_msg(VEEJAY_MSG_ERROR, "Frame contents invalid (video dimension or internal format did not match)"); - return -1; + case FMT_420F: + case FMT_420: + uv_len = y_len/4; break; + default: + uv_len = y_len/2;break; } if( v->c[0]->type == VSOCK_C) - n = sock_t_recv_w( v->c[0]->fd, dst, p[3] ); + { + int n = sock_t_recv_w( v->c[0]->fd, v->space, p[3] ); + if(n) + vj_client_decompress( v, dst, n, y_len, uv_len ); + } if(n > 0 ) plen += n; - return plen; + + return conv; } int vj_client_get_status_fd(vj_client *v, int sock_type ) @@ -299,7 +348,6 @@ int vj_client_send_buf(vj_client *v, int sock_type,unsigned char *buf, int len ) { if( sock_type == V_CMD ) { - // format msg sprintf(v->blob, "V%03dD", len); veejay_memcpy( v->blob+5, buf, len ); diff --git a/veejay-current/libvjnet/vj-client.h b/veejay-current/libvjnet/vj-client.h index e10b3886..6d727ab4 100644 --- a/veejay-current/libvjnet/vj-client.h +++ b/veejay-current/libvjnet/vj-client.h @@ -1,5 +1,5 @@ /* veejay - Linux VeeJay - * (C) 2002-2004 Niels Elburg + * (C) 2002-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -39,9 +39,14 @@ typedef struct int cur_width; int cur_height; int cur_fmt; + int in_width; + int in_height; + int in_fmt; + uint8_t *space; conn_type_t **c; int ports[3]; int mcast; + void *lzo; unsigned char *blob; } vj_client; @@ -54,7 +59,7 @@ void vj_client_flush( vj_client *v, int delay ); int vj_client_poll( vj_client *v, int sock_type ); -int vj_client_read_i(vj_client *v, uint8_t *dst ); +int vj_client_read_i(vj_client *v, uint8_t *dst, int len ); int vj_client_read( vj_client *v, int sock_type, uint8_t *dst, int bytes ); diff --git a/veejay-current/libvjnet/vj-server.c b/veejay-current/libvjnet/vj-server.c index 6d145839..b78a3556 100644 --- a/veejay-current/libvjnet/vj-server.c +++ b/veejay-current/libvjnet/vj-server.c @@ -1,5 +1,5 @@ /* libvjnet - Linux VeeJay - * (C) 2002-2005 Niels Elburg + * (C) 2002-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -26,7 +26,8 @@ #include #include #include - +#include +#include #define __INVALID 0 #define __SENDER 1 @@ -251,12 +252,6 @@ int vj_server_send( vj_server *vje, int link_id, uint8_t *buf, int len ) return 0; } -// if(!FD_ISSET( Link[link_id]->handle, &(vje->wds) ) ) -// { -// veejay_msg(VEEJAY_MSG_ERROR, "Link %d not ready for sending", link_id); -// return 0; -// } - while (total < len) { n = send(Link[link_id]->handle, buf + total, bytes_left, 0); @@ -286,20 +281,29 @@ int vj_server_send( vj_server *vje, int link_id, uint8_t *buf, int len ) } int vj_server_send_frame( vj_server *vje, int link_id, uint8_t *buf, int len, - VJFrame *frame, VJFrameInfo *info, long ms ) + VJFrame *frame, long ms ) { if(len <= 0 || buf == NULL ) + { + veejay_msg(0, "Nothing to send to remote!"); return 0; - + } if(!vje->use_mcast ) { - return vj_server_send( vje, link_id, buf, len ); + fd_set wds; + vj_link **Link = (vj_link**) vje->link; + FD_ZERO(&wds); + FD_SET(Link[link_id]->handle, &wds ); + int n = select( Link[link_id]->handle+1, NULL, &wds, NULL, NULL ); + if( FD_ISSET(Link[link_id]->handle, &wds)) + return vj_server_send( vje, link_id, buf, len ); + return 0; } else { vj_proto **proto = (vj_proto**) vje->protocol; if( vje->server_type == V_CMD ) - return mcast_send_frame( proto[0]->s, frame, info, buf,len,ms, vje->ports[0] ); + return mcast_send_frame( proto[0]->s, frame, buf,len,ms, vje->ports[0] ); } return 0; } diff --git a/veejay-current/libvjnet/vj-server.h b/veejay-current/libvjnet/vj-server.h index f2fc0791..fda6980d 100644 --- a/veejay-current/libvjnet/vj-server.h +++ b/veejay-current/libvjnet/vj-server.h @@ -1,5 +1,5 @@ /* libvjnet - Linux VeeJay - * (C) 2002-2004 Niels Elburg + * (C) 2002-2007 Niels Elburg * * * This program is free software; you can redistribute it and/or modify @@ -53,7 +53,8 @@ int vj_server_poll(vj_server * vje); int vj_server_send(vj_server *vje, int link_id, uint8_t *buf, int len); -int vj_server_send_frame(vj_server *vje, int link_id, uint8_t *buf, int total_len, VJFrame *frame, VJFrameInfo *info,long ms); +int vj_server_send_frame(vj_server *vje, int link_id, uint8_t *buf, int total_len, VJFrame *frame, long ms + ); int vj_server_init(void); diff --git a/veejay-current/libyuv/subsample.c b/veejay-current/libyuv/subsample.c index 780fd9ed..a402fb56 100644 --- a/veejay-current/libyuv/subsample.c +++ b/veejay-current/libyuv/subsample.c @@ -511,18 +511,9 @@ static inline void copy_width( uint8_t *dst, uint8_t *in, int width ) i += 16; } - x = w % 16; - - if( x >= 8 ) - { - copy8( d,i ); - d += 8; - i += 8; - x -= 8; - } - - if( x ) - small_memcpy( d, i, x); + x = (w % 16); + if( x > 4 ) + small_memcpy( d, i, x-1); } @@ -687,7 +678,8 @@ static void tr_422_to_444(void *data, uint8_t *buffer, int width, int height) #else const int mmx_stride = stride >> 3; - const int left = mmx_stride % 8; + int left = (mmx_stride % 8)-1; + if( left < 0 ) left = 0; for( y = height-1; y > 0 ; y -- ) { uint8_t *src = buffer + (y * stride); @@ -698,12 +690,12 @@ static void tr_422_to_444(void *data, uint8_t *buffer, int width, int height) src += 8; dst += 16; } - for(x=0; x < left; x++) // for 1 row + /* for(x=0; x < left; x++) // for 1 row { dst[0] = src[x]; //put to dst dst[1] = src[x]; dst+=2; // increment dst - } + }*/ } #endif } diff --git a/veejay-current/libyuv/yuvconv.c b/veejay-current/libyuv/yuvconv.c index 5ec05b84..16146541 100644 --- a/veejay-current/libyuv/yuvconv.c +++ b/veejay-current/libyuv/yuvconv.c @@ -113,7 +113,7 @@ VJFrame *yuv_rgb_template( uint8_t *rgb_buffer, int w, int h, int fmt ) { #ifdef STRICT_CHECKING assert( fmt == PIX_FMT_RGB24 || fmt == PIX_FMT_BGR24 || - fmt == PIX_FMT_RGB32 ); + fmt == PIX_FMT_RGBA || fmt == PIX_FMT_RGB32 ); assert( w > 0 ); assert( h > 0 ); #endif @@ -152,7 +152,7 @@ void yuv_convert_any( VJFrame *src, VJFrame *dst, int src_fmt, int dst_fmt ) src_fmt == PIX_FMT_YUV422P || src_fmt == PIX_FMT_YUVJ422P || src_fmt == PIX_FMT_YUV444P || src_fmt == PIX_FMT_YUVJ444P || src_fmt == PIX_FMT_RGB24 || src_fmt == PIX_FMT_RGBA || - src_fmt == PIX_FMT_BGR24); + src_fmt == PIX_FMT_BGR24 ); assert( src->width > 0 ); assert( dst->width > 0 ); #endif @@ -179,7 +179,7 @@ void yuv_convert_any3( VJFrame *src, int src_stride[3], VJFrame *dst, int src_fm assert( src_fmt == PIX_FMT_YUV420P || src_fmt == PIX_FMT_YUVJ420P || src_fmt == PIX_FMT_YUV422P || src_fmt == PIX_FMT_YUVJ422P || src_fmt == PIX_FMT_YUV444P || src_fmt == PIX_FMT_YUVJ444P || - src_fmt == PIX_FMT_RGB24 || src_fmt == PIX_FMT_RGBA ); + src_fmt == PIX_FMT_RGB24 || src_fmt == PIX_FMT_RGBA ); #endif struct SwsContext *ctx = sws_getContext( src->width, @@ -784,6 +784,11 @@ int yuv_sws_get_cpu_flags(void) #ifdef HAVE_ALTIVEC cpu_flags = cpu_flags | SWS_CPU_CAPS_ALTIVEC; #endif + + cpu_flags = cpu_flags | SWS_FULL_CHR_H_INT; + + cpu_flags = cpu_flags | SWS_FULL_CHR_H_INP; + return cpu_flags; } diff --git a/veejay-current/share/gveejay.reloaded.glade b/veejay-current/share/gveejay.reloaded.glade index 85eba050..7a618727 100644 --- a/veejay-current/share/gveejay.reloaded.glade +++ b/veejay-current/share/gveejay.reloaded.glade @@ -10,7 +10,7 @@ False True False - veejay-logo.png + veejay-icon.png True False False diff --git a/veejay-current/tools/Makefile.am b/veejay-current/tools/Makefile.am index 00aa9257..52e664f7 100644 --- a/veejay-current/tools/Makefile.am +++ b/veejay-current/tools/Makefile.am @@ -9,6 +9,8 @@ INCLUDES = -I$(top_srcdir) \ VJLIBS = $(top_builddir)/libvjnet/libvjnet.la \ $(top_builddir)/libvjmsg/libvjmsg.la \ + $(top_builddir)/libyuv/libyuv.la \ + $(top_builddir)/liblzo/libminilzo.la \ $(top_builddir)/libvjmem/libvjmem.la yuv2rawdv_SOURCES = yuv2rawdv.c diff --git a/veejay-current/veejay/liblavplayvj.c b/veejay-current/veejay/liblavplayvj.c index 72eae797..b310c833 100644 --- a/veejay-current/veejay/liblavplayvj.c +++ b/veejay-current/veejay/liblavplayvj.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include "jpegutils.h" #include "vj-event.h" @@ -587,7 +588,10 @@ int veejay_init_editlist(veejay_t * info) { settings->spas = 0; } + + veejay_msg(VEEJAY_MSG_DEBUG, "%s: %dx%d, %d,%d", __FUNCTION__, el->video_width,el->video_height); vj_el_set_image_output_size( el ); + return 0; } @@ -875,14 +879,6 @@ static int veejay_screen_update(veejay_t * info ) vj_perform_unlock_primary_frame(); - // get the frame to output, in 420 or 422 - if (info->uc->take_bg==1) - { - vj_perform_get_primary_frame(info,frame,0); - vj_perform_take_bg(info,frame); - info->uc->take_bg = 0; - } - video_playback_setup *settings = info->settings; if(settings->zoom ) { @@ -991,10 +987,15 @@ static int veejay_screen_update(veejay_t * info ) // send a frame to all participants when using mcast // (activated after sending VIMS MCAST SENDER START/STOP) - if( info->settings->use_vims_mcast) + if( info->settings->unicast_frame_sender ) + { + vj_perform_send_primary_frame_s2(info, 0); + info->settings->unicast_frame_sender = 0; + } + if( info->settings->mcast_frame_sender && info->settings->use_vims_mcast ) + { vj_perform_send_primary_frame_s2(info, 1); - - //todo: this sucks, have it modular.( video out drivers ) + } switch (info->video_out) { @@ -1212,6 +1213,7 @@ void veejay_check_homedir(void *arg) { veejay_t *info = (veejay_t *) arg; char path[1024]; + char tmp[1024]; struct stat s; char *home = getenv("HOME"); if(!home) @@ -1222,32 +1224,29 @@ void veejay_check_homedir(void *arg) } snprintf(path,1024, "%s/.veejay", home); - int ret = stat( path, &s ); int error = 0; if( ret < 0 ) { - veejay_msg(VEEJAY_MSG_WARNING, "%s does not exist", path ); - veejay_msg(VEEJAY_MSG_INFO, "Configuring veejay in '%s'", path ); + veejay_msg(VEEJAY_MSG_WARNING, "No veejay config file in %s", path ); ret = mkdir(path,0777); if( ret != 0 ) - error = 1; - if( ret < 0 ) { - switch(errno) - { - case EACCES: - veejay_msg( VEEJAY_MSG_ERROR, "Permission denied");break; - case EEXIST: - veejay_msg( VEEJAY_MSG_ERROR, "Path already exists and may not be a directory");break; - case ELOOP: - veejay_msg( VEEJAY_MSG_ERROR, "Too many symbolic links"); break; - case ENOSPC: - veejay_msg( VEEJAY_MSG_ERROR, "Out of available diskpace. Delete some files and try again"); break; - default: - veejay_msg( VEEJAY_MSG_ERROR, "A mysterious error occured"); - break; - } + error = 1; + } + switch(errno) + { + case EACCES: + veejay_msg( VEEJAY_MSG_ERROR, "\tPermission denied");break; + case EEXIST: + veejay_msg( VEEJAY_MSG_ERROR, "\tPath already exists and may not be a directory");break; + case ELOOP: + veejay_msg( VEEJAY_MSG_ERROR, "\tToo many symbolic links"); break; + case ENOSPC: + veejay_msg( VEEJAY_MSG_ERROR, "\tOut of available diskpace. Delete some files and try again"); break; + default: + veejay_msg( VEEJAY_MSG_ERROR, "\tSome other error occured"); + break; } } @@ -1262,9 +1261,23 @@ void veejay_check_homedir(void *arg) if(!error) { - veejay_msg(VEEJAY_MSG_INFO, "Veejay uses %s", path); + veejay_msg(VEEJAY_MSG_INFO, "Veejay's configuration file is %s", path); info->homedir = strndup( path, 1024 ); } + + sprintf(tmp, "%s/plugins.cfg", path ); + struct statfs ts; + if( statfs( tmp, &ts ) != 0 ) + { + veejay_msg(VEEJAY_MSG_INFO,"\tNo plugins.cfg found (see DOC/HowtoPlugins)"); + } + sprintf(tmp, "%s/viewport.cfg", path); + memset( &ts,0,sizeof(struct statfs)); + if( statfs( tmp, &ts ) != 0 ) + { + veejay_msg(VEEJAY_MSG_INFO,"\tNo viewport.cfg found (press CTRL-V to setup viewport)"); + } + } /****************************************************** @@ -1293,8 +1306,13 @@ void veejay_handle_signal(void *arg, int sig) else veejay_change_state( info, LAVPLAY_STATE_STOP ); - if( sig == SIGSEGV || sig == SIGFPE ) + if( sig == SIGSEGV || sig == SIGFPE || sig == SIGBUS || sig == SIGPWR || sig == SIGABRT) signal( sig, SIG_DFL ); + else + { + veejay_msg(VEEJAY_MSG_DEBUG, "Broken pipe"); + signal( sig, SIG_IGN ); + } } } } @@ -2132,20 +2150,18 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int full_ } } - veejay_msg(VEEJAY_MSG_DEBUG, "ID %d | Mode %d", info->uc->sample_id, info->uc->playback_mode ); - /* After we have fired up the audio and video threads system (which * are assisted if we're installed setuid root, we want to set the * effective user id to the real user id */ - if (info->current_edit_list->has_audio && info->audio == AUDIO_PLAY) - { - if (!vj_perform_audio_start(info)) { - return -1; - } - } + if (info->current_edit_list->has_audio && info->audio == AUDIO_PLAY) + { + if (!vj_perform_audio_start(info)) { + return -1; + } + } if (seteuid(getuid()) < 0) @@ -2180,10 +2196,6 @@ static void veejay_schedule_fifo(veejay_t *info, int pid ) veejay_memset( &schp, 0, sizeof(schp)); schp.sched_priority = sched_get_priority_max( SCHED_FIFO ); - veejay_msg(VEEJAY_MSG_DEBUG, "Min prio = %d, Max prio = %d", - sched_get_priority_min( SCHED_FIFO ), - sched_get_priority_max( SCHED_FIFO )); - if( sched_setscheduler( pid, SCHED_FIFO, &schp ) != 0 ) { veejay_msg(VEEJAY_MSG_WARNING, "Cannot set First-In-First-Out scheduling for process %d",pid); @@ -2191,6 +2203,7 @@ static void veejay_schedule_fifo(veejay_t *info, int pid ) else { veejay_msg(VEEJAY_MSG_INFO, "Using First-In-First-Out II scheduling for process %d", pid); + veejay_msg(VEEJAY_MSG_INFO, "\tPriority is set to %d (RT)", schp.sched_priority ); } } @@ -2210,8 +2223,8 @@ static int veejay_pin_cpu( veejay_t *info, int cpu_num ) if( cpumask == NULL ) { sz = 1 + (2 * sched_ncpus()) / (8 * sizeof(unsigned long)); - mask = (unsigned long*) vj_malloc( sz * sizeof( unsigned long )); - cpumask = (unsigned long*) vj_malloc( sz * sizeof( unsigned long )); + mask = (unsigned long*) vj_calloc( 8 * sz * sizeof( unsigned long )); + cpumask = (unsigned long*) vj_calloc( 8 * sz * sizeof( unsigned long )); retval = sched_getaffinity(0, sz * sizeof(unsigned long), cpumask ); if( retval < 0 ) @@ -2477,10 +2490,10 @@ static void Welcome(veejay_t *info) veejay_msg(VEEJAY_MSG_INFO,"Software scaler - output stream dimensions %d x %d ", info->video_output_width, info->video_output_height ); } - veejay_msg(VEEJAY_MSG_INFO,"Your best friends are 'man' and 'vi'"); + veejay_msg(VEEJAY_MSG_INFO,"Type 'man veejay' in a shell to learn more about veejay"); veejay_msg(VEEJAY_MSG_INFO,"For a list of events, type 'veejay -u |less' in a shell"); - veejay_msg(VEEJAY_MSG_INFO,"Use 'sayVIMS -i' or gveejay to enter interactive mode"); + veejay_msg(VEEJAY_MSG_INFO,"Use 'gveejayreloaded' to enter interactive mode"); veejay_msg(VEEJAY_MSG_INFO,"Alternatives are OSC applications or 'sendVIMS' extension for PD"); } @@ -2587,11 +2600,14 @@ int vj_server_setup(veejay_t * info) "Unable to initialize mcast sender"); return 0; } - //info->settings->mcast_frame_sender = 1; + else + veejay_msg(VEEJAY_MSG_INFO, "VIMS multicast channel ready at port %d group %s", + info->uc->port, info->settings->vims_group_name ); } if(info->settings->use_mcast) + { GoMultiCast( info->settings->group_name ); - + } info->osc = (void*) vj_osc_allocate(info->uc->port+2); if(!info->osc) @@ -2615,8 +2631,10 @@ int vj_server_setup(veejay_t * info) veejay_msg(VEEJAY_MSG_INFO, "Initialized OSC (http://www.cnmat.berkeley.edu/OpenSoundControl/)"); if (info->osc == NULL || info->vjs[0] == NULL || info->vjs[1] == NULL) + { + veejay_msg(0, "Unable to setup basic network I/O. Abort"); return 0; - + } info->uc->is_server = 1; return 1; @@ -3193,14 +3211,17 @@ int veejay_edit_addmovie_sample(veejay_t * info, char *movie, int id ) info->edit_list->video_norm , info->pixel_format); // if that fails, bye if(!sample_edl) + { + veejay_msg(0, "Error while creating EDL"); return -1; - + } // the editlist dimensions must match (there's more) if( sample_edl->video_width != info->edit_list->video_width || sample_edl->video_height != info->edit_list->video_height ) { - veejay_msg(VEEJAY_MSG_ERROR, "Cannot add video file '%s' (wrong dimensions)", movie); - if(sample_edl) vj_el_free(sample_edl); + if(sample_edl) + vj_el_free(sample_edl); + veejay_msg(0, "Frame dimensions do not match. Abort"); return -1; } diff --git a/veejay-current/veejay/veejay.c b/veejay-current/veejay/veejay.c index 3b6761fd..65edfecf 100644 --- a/veejay-current/veejay/veejay.c +++ b/veejay-current/veejay/veejay.c @@ -578,12 +578,12 @@ static int check_command_line_options(int argc, char *argv[]) #ifdef HAVE_GETOPT_LONG while ((n = getopt_long(argc, argv, - "o:G:O:a:H:V:s:c:t:j:l:p:m:x:y:nLFPY:ugr:vdibIjf:A:N:H:W:R:M:Vz:qw:h:C:T", + "o:G:O:a:H:V:s:c:t:j:l:p:m:x:y:nLFPY:ugr:vdibIjf:A:N:H:W:R:M:Vz:qw:h:C:T:", long_options, &option_index)) != EOF) #else while ((n = getopt(argc, argv, - "o:G:s:O:a:c:t:l:t:x:y:m:j:p:nLFPY:vudgibr:Ijf:N:H:W:R:A:M:Vz:qw:h:C:T")) != EOF) + "o:G:s:O:a:c:t:l:t:x:y:m:j:p:nLFPY:vudgibr:Ijf:N:H:W:R:A:M:Vz:qw:h:C:T:")) != EOF) #endif { switch (n) { diff --git a/veejay-current/veejay/vims.h b/veejay-current/veejay/vims.h index 4b581355..4aa12a53 100644 --- a/veejay-current/veejay/vims.h +++ b/veejay-current/veejay/vims.h @@ -62,7 +62,7 @@ enum { VIMS_REC_AUTO_START = 320, VIMS_REC_STOP = 321, VIMS_REC_START = 322, - VIMS_EFFECT_SET_BG = 325, + VIMS_EFFECT_SET_BG = 339, VIMS_SAMPLE_MODE = 323, VIMS_BEZERK = 324, VIMS_DEBUG_LEVEL = 325, diff --git a/veejay-current/veejay/vj-event.c b/veejay-current/veejay/vj-event.c index 4120bcd1..b0e0cba8 100644 --- a/veejay-current/veejay/vj-event.c +++ b/veejay-current/veejay/vj-event.c @@ -1216,32 +1216,23 @@ void vj_event_update_remote(void *ptr) if( vj_server_poll( v->vjs[0] ) ) vj_server_new_connection( v->vjs[0] ); - if( vj_server_poll( v->vjs[1] ) ) vj_server_new_connection( v->vjs[1] ); if( vj_server_poll( v->vjs[3] ) ) vj_server_new_connection( v->vjs[3] ); -// for( i = 0; i < VJ_MAX_CONNECTIONS; i ++ ) -// if( vj_server_link_used( v->vjs[1], i )) -// veejay_pipe_write_status( v, i ); - if( v->settings->use_vims_mcast ) { int res = vj_server_update(v->vjs[2],0 ); if(res > 0) { v->uc->current_link = 0; - // int size = vj_server_min_bufsize( v->vjs[2], 0 ); char *buf = NULL; - // char buf[MESSAGE_SIZE]; - // veejay_memset(buf,0, MESSAGE_SIZE); int len =0; while( ( buf = vj_server_retrieve_msg( v->vjs[2], 0, buf,&len )) != NULL ) { vj_event_parse_msg( v, buf,len ); - // veejay_memset( buf, 0, size ); } } @@ -1258,10 +1249,8 @@ void vj_event_update_remote(void *ptr) if(res>0) { v->uc->current_link = i; - // char buf[MESSAGE_SIZE]; int n = 0; int len = 0; - // veejay_memset( buf,0,MESSAGE_SIZE); char *buf = NULL; while( (buf= vj_server_retrieve_msg(v->vjs[0],i,buf, &len))!= NULL ) { @@ -5927,12 +5916,21 @@ void vj_event_el_add_video_sample(void *ptr, const char format[], va_list ap) int new_sample_id = args[0]; if(new_sample_id == 0 ) - veejay_msg(VEEJAY_MSG_DEBUG, "CREATING NEW"); + { + veejay_msg(VEEJAY_MSG_INFO, "Trying to create new sample from %s", + str ); + } else - veejay_msg(VEEJAY_MSG_DEBUG, "APPENDING TO EXISITING"); + { + veejay_msg(VEEJAY_MSG_INFO, "Trying to append %s to current sample", + str ); + } new_sample_id = veejay_edit_addmovie_sample(v,str,new_sample_id ); if(new_sample_id <= 0) + { + veejay_msg(VEEJAY_MSG_ERROR, "Unable to open %s", str ); new_sample_id = 0; + } vj_event_send_new_id( v,new_sample_id ); } @@ -6041,7 +6039,7 @@ void vj_event_tag_new_net(void *ptr, const char format[], va_list ap) } } - int id = veejay_create_tag(v, VJ_TAG_TYPE_NET, str, v->nstreams, 0,args[0]); + int id = veejay_create_tag(v, VJ_TAG_TYPE_NET, str, v->nstreams, args[0],0); vj_event_send_new_id( v, id); if(id <= 0) @@ -6056,7 +6054,10 @@ void vj_event_tag_new_mcast(void *ptr, const char format[], va_list ap) int args[2]; P_A(args,str,format,ap); - int id = veejay_create_tag(v, VJ_TAG_TYPE_MCAST, str, v->nstreams, 0,args[0]); + + 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) @@ -7386,7 +7387,7 @@ void vj_event_get_scaled_image ( void *ptr, const char format[], va_list ap ) if( w <= 0 || h <= 0 ) { veejay_msg(0, "Invalid image dimension %dx%d requested",w,h ); - SEND_MSG(v, "000000" ); + SEND_MSG(v, "0000000" ); return; } @@ -7410,7 +7411,7 @@ void vj_event_get_scaled_image ( void *ptr, const char format[], va_list ap ) if(!img) { veejay_msg(VEEJAY_MSG_ERROR, "Failed to get image"); - SEND_MSG( v, "000000" ); + SEND_MSG( v, "0000000" ); return; } @@ -7426,16 +7427,18 @@ void vj_event_get_scaled_image ( void *ptr, const char format[], va_list ap ) #endif int size1 = 0; - if ( lzo_compress( lzo_, msg, tmpbuf, &size1, (w*h*3)) == 0) + int input_len = (use_bw_preview_ ? (w*h) : (w*h*3)); + + if ( lzo_compress( lzo_, msg, tmpbuf, &size1, input_len) == 0) { veejay_msg(0, "Unable to compress preview image"); - SEND_MSG( v, "000000" ); + SEND_MSG( v, "0000000" ); } else { - char header[7]; - sprintf(header, "%06d", size1); - vj_server_send( v->vjs[0], v->uc->current_link, header, 6 ); + char header[8]; + sprintf(header, "%06d%1d", size1,use_bw_preview_); + vj_server_send( v->vjs[0], v->uc->current_link, header, 7 ); vj_server_send( v->vjs[0], v->uc->current_link, tmpbuf, size1 ); } @@ -7826,7 +7829,9 @@ void vj_event_send_devices ( void *ptr, const char format[], va_list ap ) void vj_event_send_frame ( void *ptr, const char format[], va_list ap ) { veejay_t *v = (veejay_t*) ptr; - vj_perform_send_primary_frame_s2( v,0 ); + //@ schedule + v->settings->unicast_frame_sender = 1; +// vj_perform_send_primary_frame_s2( v,0 ); } diff --git a/veejay-current/veejay/vj-global.h b/veejay-current/veejay/vj-global.h index 3ec8d0e5..d2b0ff72 100644 --- a/veejay-current/veejay/vj-global.h +++ b/veejay-current/veejay/vj-global.h @@ -72,7 +72,7 @@ enum { #define EL_MIN_BUF (65535 * 4) #define XMLTAG_BUNDLE_FILE "ACTIONFILE" #define XMLTAG_EVENT_AS_KEY "BUNDLE" - +#define SOCKETFRAMELEN (1024*4096) #define FMT_420 0 #define FMT_422 1 #define FMT_420F 2 diff --git a/veejay-current/veejay/vj-lib.h b/veejay-current/veejay/vj-lib.h index 67434b9e..0b7399f5 100644 --- a/veejay-current/veejay/vj-lib.h +++ b/veejay-current/veejay/vj-lib.h @@ -170,6 +170,7 @@ typedef struct { int tag_record; int dct_method; subsample_mode_t sample_mode; + int unicast_frame_sender; int mcast_frame_sender; int use_mcast; char *group_name; diff --git a/veejay-current/veejay/vj-misc.c b/veejay-current/veejay/vj-misc.c index c28755e5..ab48d80c 100644 --- a/veejay-current/veejay/vj-misc.c +++ b/veejay-current/veejay/vj-misc.c @@ -38,7 +38,7 @@ #include static unsigned int vj_relative_time = 0; - +static unsigned int vj_stamp_ = 0; static unsigned int vj_get_timer() { struct timeval tv; @@ -46,6 +46,16 @@ static unsigned int vj_get_timer() return ((tv.tv_sec & 1000000) + tv.tv_usec); } +unsigned int vj_stamp() +{ + vj_stamp_ ++; + return vj_stamp_; +} + +void vj_stamp_clear() +{ + vj_stamp_ = 0; +} unsigned int vj_get_relative_time() { @@ -54,27 +64,24 @@ unsigned int vj_get_relative_time() relative = time - vj_relative_time; vj_relative_time = time; return relative; - // return (float) relative *0.000001F; } int vj_perform_take_bg(veejay_t *info, uint8_t **src) { VJFrame frame; - VJFrameInfo tag; - char *descr = "Difference Overlay"; - memset(&frame, 0, sizeof(VJFrame)); - memset(&tag, 0, sizeof(VJFrameInfo)); + char *descr = "Map B to A (substract background mask)"; + veejay_memset(&frame, 0, sizeof(VJFrame)); frame.data[0] = src[0]; frame.data[1] = src[1]; frame.data[2] = src[2]; - tag.width = info->edit_list->video_width; - tag.height = info->edit_list->video_height; - veejay_msg(VEEJAY_MSG_INFO, "Warning: taking current frame %d as static bg (%p)",info->settings->current_frame_num, src[0]); + frame.width = info->edit_list->video_width; + frame.height = info->edit_list->video_height; - vj_effect_prepare( &frame, &tag, (int) vj_effect_get_by_name( descr ) ); + vj_effect_prepare( &frame, vj_effect_get_by_name( descr ) ); return 1; } + #ifdef HAVE_JPEG int vj_perform_screenshot2(veejay_t * info, uint8_t ** src) { diff --git a/veejay-current/veejay/vj-misc.h b/veejay-current/veejay/vj-misc.h index 66406e81..d1a2a8f7 100644 --- a/veejay-current/veejay/vj-misc.h +++ b/veejay-current/veejay/vj-misc.h @@ -29,6 +29,9 @@ int vj_perform_screenshot2(veejay_t * info, uint8_t ** src); unsigned int vj_get_relative_time(void); +void vj_stamp_clear(); +unsigned int vj_stamp(); + int vj_perform_take_bg( veejay_t *info, uint8_t **src); int veejay_create_temp_file(const char *prefix, char *dst); diff --git a/veejay-current/veejay/vj-perform.c b/veejay-current/veejay/vj-perform.c index 344471cc..c21875b3 100644 --- a/veejay-current/veejay/vj-perform.c +++ b/veejay-current/veejay/vj-perform.c @@ -83,6 +83,8 @@ typedef struct { int active; } varcache_t; +#define RUP8(num)(((num)+8)&~8) + static varcache_t pvar_; static void *lzo_; static void *effect_sampler = NULL; @@ -478,18 +480,17 @@ static int vj_perform_increase_sample_frame(veejay_t * info, long num) static int vj_perform_alloc_row(veejay_t *info, int frame, int c, int frame_len) { - uint8_t *buf = vj_malloc(sizeof(uint8_t) * (helper_frame->len * 3)); + uint8_t *buf = vj_malloc(sizeof(uint8_t) * RUP8(helper_frame->len * 3)); +#ifdef STRICT_CHECKING + assert ( buf != NULL ); +#endif frame_buffer[c]->Y = buf; frame_buffer[c]->Cb = buf + helper_frame->len; frame_buffer[c]->Cr = buf + helper_frame->len + helper_frame->len; frame_buffer[c]->ssm = info->effect_frame1->ssm; - //veejay_memset( frame_buffer[c]->Y, 16, helper_frame->len ); - //veejay_memset( frame_buffer[c]->Cb, 128, helper_frame->len/2); - //veejay_memset( frame_buffer[c]->Cr,128,helper_frame->len/2); return (helper_frame->len * 3 ); - } static void vj_perform_free_row(int c) @@ -575,14 +576,14 @@ static int vj_perform_verify_rows(veejay_t *info, int frame) static int vj_perform_record_buffer_init() { if(record_buffer->Cb==NULL) - record_buffer->Cb = (uint8_t*)vj_malloc(sizeof(uint8_t) * helper_frame->uv_len ); + record_buffer->Cb = (uint8_t*)vj_malloc(sizeof(uint8_t) * RUP8(helper_frame->uv_len) ); if(!record_buffer->Cb) return 0; if(record_buffer->Cr==NULL) - record_buffer->Cr = (uint8_t*)vj_malloc(sizeof(uint8_t) * helper_frame->uv_len ); + record_buffer->Cr = (uint8_t*)vj_malloc(sizeof(uint8_t) * RUP8(helper_frame->uv_len) ); if(!record_buffer->Cr) return 0; if(record_buffer->Y == NULL) - record_buffer->Y = (uint8_t*)vj_malloc(sizeof(uint8_t) * helper_frame->len); + record_buffer->Y = (uint8_t*)vj_malloc(sizeof(uint8_t) * RUP8(helper_frame->len)); if(!record_buffer->Y) return 0; veejay_memset( record_buffer->Y , 16, helper_frame->len ); @@ -634,10 +635,11 @@ int vj_perform_init(veejay_t * info, int use_vp) for( c = 0; c < 5; c ++ ) { primary_buffer[c] = (ycbcr_frame*) vj_calloc(sizeof(ycbcr_frame)); - primary_buffer[c]->Y = (uint8_t*) vj_malloc( sizeof(uint8_t) * (frame_len+w) * 3 ); - if(!primary_buffer[c]->Y ) - return 0; - + primary_buffer[c]->Y = (uint8_t*) vj_malloc( sizeof(uint8_t) * RUP8((frame_len+w) * 3) ); +#ifdef STRICT_CHECKING + assert( primary_buffer[c] != NULL ); + assert( primary_buffer[c]->Y != NULL ); +#endif primary_buffer[c]->Cb = primary_buffer[c]->Y + (frame_len + w); primary_buffer[c]->Cr = primary_buffer[c]->Cb + (frame_len + w); @@ -665,13 +667,13 @@ int vj_perform_init(veejay_t * info, int use_vp) sample_record_init(frame_len); vj_tag_record_init(w,h); // to render fading of effect chain: - temp_buffer[0] = (uint8_t*)vj_malloc(sizeof(uint8_t) * frame_len ); + temp_buffer[0] = (uint8_t*)vj_malloc(sizeof(uint8_t) * RUP8(frame_len) ); if(!temp_buffer[0]) return 0; veejay_memset( temp_buffer[0], 16, frame_len ); - temp_buffer[1] = (uint8_t*)vj_malloc(sizeof(uint8_t) * frame_len ); + temp_buffer[1] = (uint8_t*)vj_malloc(sizeof(uint8_t) * RUP8(frame_len) ); if(!temp_buffer[1]) return 0; veejay_memset( temp_buffer[1], 128, frame_len ); - temp_buffer[2] = (uint8_t*)vj_malloc(sizeof(uint8_t) * frame_len ); + temp_buffer[2] = (uint8_t*)vj_malloc(sizeof(uint8_t) * RUP8(frame_len) ); if(!temp_buffer[2]) return 0; veejay_memset( temp_buffer[2], 128, frame_len ); // to render fading of effect chain: @@ -950,56 +952,6 @@ void vj_perform_audio_stop(veejay_t * info) } } -/* -void vj_perform_update_plugin_frame(VJFrame *frame) -{ - frame->data[0] = (uint8_t*) primary_buffer[0]->Y; - frame->data[1] = (uint8_t*) primary_buffer[0]->Cb; - frame->data[2] = (uint8_t*) primary_buffer[0]->Cr; -} -#ifdef HAVE_FREETYPE -VJFrame *vj_perform_init_plugin_frame(veejay_t *info) -{ - editlist *el = info->edit_list; - VJFrame *frame = (VJFrame*) vj_calloc(sizeof(VJFrame)); - if(!frame) return 0; - if(info->pixel_format == FMT_422 || info->pixel_format == FMT_422F) - vj_el_init_422_frame( el, frame ); - else - vj_el_init_420_frame( el, frame ); - -// frame->data[0] = primary_buffer[0]->Y; -// frame->data[1] = primary_buffer[0]->Cb; -// frame->data[2] = primary_buffer[0]->Cr; - veejay_msg(VEEJAY_MSG_INFO, - "Using font renderer '%s' %d x %d", - (info->pixel_format == FMT_422 ? "YUV 4:2:2" : "YUV 4:2:0" ), - frame->width, - frame->height ); - return frame; -} -#endif - -VJFrameInfo *vj_perform_init_plugin_frame_info(veejay_t *info) -{ - editlist *el = info->edit_list; - VJFrameInfo *frame_info = (VJFrameInfo*) vj_malloc(sizeof(VJFrame)); - if(!frame_info) return NULL; - frame_info->width = el->video_width; - frame_info->height = el->video_height; - frame_info->fps = el->video_fps; - frame_info->timecode = 0; - frame_info->inverse = 0; - // todo: add timestamp info - return frame_info; -} - -void vj_perform_free_plugin_frame(VJFrameInfo *f ) -{ - if(f) - free(f); -} -*/ /******************************************************************** * vj_perform_get_primary_frame : * sets the pointers to the primary frame into **frame @@ -1076,7 +1028,7 @@ int vj_perform_init_cropped_output_frame(veejay_t *info, VJFrame *src, int *dw, int i; for( i = 0; i < 3; i ++ ) { - crop_frame->data[i] = (uint8_t*) vj_malloc(sizeof(uint8_t) * crop_frame->len ); + crop_frame->data[i] = (uint8_t*) vj_malloc(sizeof(uint8_t) * RUP8(crop_frame->len) ); if(!crop_frame->data[i]) return 0; } @@ -1096,13 +1048,13 @@ void vj_perform_init_output_frame( veejay_t *info, uint8_t **frame, free(video_output_buffer[i]->Cr ); video_output_buffer[i]->Y = (uint8_t*) - vj_malloc(sizeof(uint8_t) * dst_w * dst_h ); + vj_malloc(sizeof(uint8_t) * RUP8( dst_w * dst_h) ); veejay_memset( video_output_buffer[i]->Y, 16, dst_w * dst_h ); video_output_buffer[i]->Cb = (uint8_t*) - vj_malloc(sizeof(uint8_t) * dst_w * dst_h ); + vj_malloc(sizeof(uint8_t) * RUP8( dst_w * dst_h) ); veejay_memset( video_output_buffer[i]->Cb, 128, dst_w * dst_h ); video_output_buffer[i]->Cr = (uint8_t*) - vj_malloc(sizeof(uint8_t) * dst_w * dst_h ); + vj_malloc(sizeof(uint8_t) * RUP8(dst_w * dst_h) ); veejay_memset( video_output_buffer[i]->Cr, 128, dst_w * dst_h ); } @@ -1114,16 +1066,11 @@ void vj_perform_init_output_frame( veejay_t *info, uint8_t **frame, -static int __global_frame = 0; -static int __socket_len = 0; -static int __send_frame = 0; +//static int __global_frame = 0; +//static int __socket_len = 0; +//static int __send_frame = 0; -//int vj_perform_send_primary_frame_s(veejay_t *info, int mcast) -//{ -// __send_frame = (mcast ? 2: 1 ); -// return 1; -//} static void long2str(unsigned char *dst, int32_t n) { dst[0] = (n )&0xff; @@ -1132,101 +1079,90 @@ static void long2str(unsigned char *dst, int32_t n) dst[3] = (n>>24)&0xff; } -static int vj_perform_compress_frame( veejay_t *info, uint8_t *dst ) +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_width * info->effect_frame1->uv_height; uint8_t *dstI = dst + (3*4); int size1=0,size2=0,size3=0; - int i = lzo_compress( lzo_ , primary_buffer[1]->Y, dstI, &size1, len ); + + int i = lzo_compress( lzo_ , primary_buffer[info->out_buf]->Y, dstI, &size1, len ); if( i == 0 ) + { + veejay_msg(VEEJAY_MSG_DEBUG, "Unable to compress Y plane"); return 0; + } dstI += size1; - i = lzo_compress( lzo_, primary_buffer[1]->Cb, dstI, &size2, uv_len ); + + i = lzo_compress( lzo_, primary_buffer[info->out_buf]->Cb, dstI, &size2, uv_len ); if( i == 0 ) + { + veejay_msg(VEEJAY_MSG_DEBUG, "Unable to compress U plane"); return 0; + } dstI += size2; - i = lzo_compress( lzo_, primary_buffer[1]->Cr, dstI, &size3, uv_len ); + + i = lzo_compress( lzo_, primary_buffer[info->out_buf]->Cr, dstI, &size3, uv_len ); if( i == 0 ) + { + veejay_msg(VEEJAY_MSG_DEBUG, "Unable to compress V plane"); return 0; - + } + long2str( dst,size1); long2str( dst+4, size2 ); long2str( dst+8, size3 ); - + return (size1+size2+size3+12); - } int vj_perform_send_primary_frame_s2(veejay_t *info, int mcast) { -// if(!info->settings->use_vims_mcast) -// return 1; - - if( info->settings->use_vims_mcast && - !info->settings->mcast_frame_sender ) - { - /* dont send frames if nobody is interested */ - return 1; - } - - if(!mcast && __global_frame) - return 1; // - const int len = info->effect_frame1->width * info->effect_frame1->height; const int uv_len = info->effect_frame1->uv_width * info->effect_frame1->uv_height; int hlen =0; - int compr_len = vj_perform_compress_frame( info, socket_buffer+20 ); - + int compr_len = 0; if( !mcast ) { + compr_len = vj_perform_compress_frame(info,socket_buffer+20); + /* peer to peer connection */ unsigned char info_line[32]; sprintf(info_line, "%04d %04d %1d %08d", info->effect_frame1->width, - info->effect_frame1->height, info->edit_list->pixel_format, + info->effect_frame1->height, info->effect_frame1->format, compr_len ); hlen = strlen(info_line ); +#ifdef STRICT_CHECKING + assert( hlen == 20 ); +#endif veejay_memcpy( socket_buffer, info_line, hlen ); } + else + { + compr_len = vj_perform_compress_frame(info,socket_buffer ); + } -/* - - veejay_memcpy( socket_buffer + hlen, primary_buffer[0]->Y, len ); - veejay_memcpy( socket_buffer + hlen + len,primary_buffer[0]->Cb, uv_len ); - veejay_memcpy( socket_buffer + hlen + len + uv_len, primary_buffer[0]->Cr, uv_len ); -*/ - if(!mcast) __global_frame = 1; int id = (mcast ? 2: 0); - __socket_len = hlen + compr_len; - + int __socket_len = hlen + compr_len; +#ifdef STRICT_CHECKING + assert( info->effect_frame1->ssm == 0 ); +#endif // mcast frame sender = info->vjs[2] ?? if(vj_server_send_frame( info->vjs[id], info->uc->current_link, socket_buffer, __socket_len, - helper_frame, info->effect_frame_info, info->real_fps )<=0) + info->effect_frame1, info->real_fps )<=0) { /* frame send error handling */ veejay_msg(VEEJAY_MSG_ERROR, "Error sending frame to remote"); - __send_frame=0; + //__send_frame=0; } - __send_frame = 1; + //__send_frame = 1; return 1; } -void vj_perform_send_frame_now( veejay_t *info,int k ) -{ - if(vj_server_send_frame( info->vjs[0], k, socket_buffer, __socket_len, - helper_frame, info->effect_frame_info, info->real_fps )<=0) - { - /* frame send error handling */ - veejay_msg(VEEJAY_MSG_ERROR, - "Error sending frame to remote"); - /* uncomment below to end veejay session */ - } - -} void vj_perform_get_output_frame_420p( veejay_t *info, uint8_t **frame, int w, int h ) { @@ -2329,7 +2265,6 @@ static int vj_perform_sample_complete_buffers(veejay_t * info, int entry, int *h frames[0]->data[0] = primary_buffer[0]->Y; frames[0]->data[1] = primary_buffer[0]->Cb; frames[0]->data[2] = primary_buffer[0]->Cr; - // chain_fade = sample_get_fader_active(info->uc->sample_id); // if(chain_fade) if(pvar_.fader_active) @@ -3058,6 +2993,13 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett frame2->height); frame2->ssm=0; } + + if (info->uc->take_bg==1) + { + vj_perform_take_bg(info,pri); + info->uc->take_bg = 0; + veejay_msg(VEEJAY_MSG_INFO, "Snapped background image"); + } } static void vj_perform_render_font( veejay_t *info, video_playback_setup *settings ) @@ -3126,7 +3068,7 @@ static int vj_perform_render_magic( veejay_t *info, video_playback_setup *settin int deep = 0; //@ Finalize the FX chain (Could leave the FX chain supersampled) vj_perform_finish_chain( info ); - + //@ Render any subtitles in sample/stream (Leaves FX chain supersampled) vj_perform_render_font( info, settings ); @@ -3165,6 +3107,8 @@ int vj_perform_queue_video_frame(veejay_t *info, int frame, const int skip_incr) int is444 = 0; int res = 0; + + veejay_memset( &pvar_, 0, sizeof(varcache_t)); if(settings->offline_record) @@ -3225,7 +3169,7 @@ int vj_perform_queue_video_frame(veejay_t *info, int frame, const int skip_incr) } //FIXME: copy from 2 or 0 buffer - if( __send_frame ) +/* if( __send_frame ) { veejay_memcpy( primary_buffer[1]->Y, primary_buffer[info->out_buf]->Y, info->effect_frame1->len ); @@ -3234,7 +3178,7 @@ int vj_perform_queue_video_frame(veejay_t *info, int frame, const int skip_incr) veejay_memcpy( primary_buffer[1]->Cr,primary_buffer[info->out_buf]->Cr, info->effect_frame1->uv_len); __send_frame = 0; - } + }*/ @@ -3263,7 +3207,7 @@ int vj_perform_queue_frame(veejay_t * info, int frame, int skip ) } } vj_perform_clear_cache(); - __global_frame = 0; + //__global_frame = 0; return 0; } diff --git a/veejay-current/veejay/vj-sdl.c b/veejay-current/veejay/vj-sdl.c index e9acd31b..22e94ba9 100644 --- a/veejay-current/veejay/vj-sdl.c +++ b/veejay-current/veejay/vj-sdl.c @@ -116,6 +116,8 @@ int vj_sdl_init(int ncpu, vj_sdl * vjsdl, int scaled_width, int scaled_height, c if (!vjsdl) return 0; + veejay_memset( &wminfo, 0, sizeof(SDL_SysWMinfo)); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { veejay_msg(VEEJAY_MSG_ERROR, "%s", SDL_GetError()); diff --git a/veejay-current/veejay/vj-viewport.c b/veejay-current/veejay/vj-viewport.c index 33c8c75d..5193575c 100644 --- a/veejay-current/veejay/vj-viewport.c +++ b/veejay-current/veejay/vj-viewport.c @@ -1121,17 +1121,12 @@ static viewport_config_t *viewport_load_settings( const char *dir ) } free(buf); - - veejay_msg(VEEJAY_MSG_INFO, - "(1) %fx%f (2) %fx%f (3) %fx%f (4) %fx%f dir=%d, grid=%dx%d color=%x", - vc->x1,vc->y1, - vc->x2,vc->y2, - vc->x3,vc->y3, - vc->x4,vc->y4, - vc->reverse, - vc->grid_size, - vc->grid_size, - vc->grid_color ); + veejay_msg(VEEJAY_MSG_INFO, "Viewport configuration:"); + veejay_msg(VEEJAY_MSG_INFO, "\tBehaviour:\t%s", (vc->reverse ? "Forward" : "Projection") ); + veejay_msg(VEEJAY_MSG_INFO, "\tQuad :\t(1) %fx%f (2) %fx%f", vc->x1,vc->y1,vc->x2,vc->y2); + veejay_msg(VEEJAY_MSG_INFO, "\t :\t(3) %fx%f (4) %fx%f", vc->x2,vc->y2,vc->x3,vc->y3); + veejay_msg(VEEJAY_MSG_INFO, "\tGrid :\t%dx%d", vc->grid_size, vc->grid_size); + veejay_msg(VEEJAY_MSG_INFO, "\tPencil :\t%s", (vc->grid_color == 0xff ? "white" : "black" ) ); return vc; } @@ -1428,6 +1423,8 @@ void viewport_render( void *vdata, uint8_t *in[3], uint8_t *out[3],int width, in else { viewport_draw( v, in[0] ); + veejay_memset( in[1], 128, len ); + veejay_memset( in[2], 128, len ); } }