From 2494d9df261162ab0032790fb8c2ec9f2b98f3de Mon Sep 17 00:00:00 2001 From: niels Date: Fri, 5 Jun 2015 02:05:40 +0200 Subject: [PATCH] remove old stuff, fix ssize_t, align multiple of 32 bytes, fix Map B to A by threshold, fix some leaks at exit, pre-allocate memory for fx-chain to eliminate dynamic memory allocation when switching samples or manipulating the fx chain, add docs/README.memory, add commandline option to disable static fx chain, take size of static chain in account when combined with -m option, update man page, clear font worker after samples are deleted, fix possible oob write in srt get list, lock static chain to RAM (non fatal), dont clear job and task argument in multithreader (no effect) --- veejay-current/veejay-client/src/vj-api.c | 14 +-- .../veejay-server/doc/README.memory | 18 ++++ veejay-current/veejay-server/libel/vj-el.c | 2 +- veejay-current/veejay-server/libel/vj-el.h | 2 + .../veejay-server/libsample/sampleadm.c | 2 +- .../veejay-server/libstream/vj-net.c | 2 +- .../veejay-server/libstream/vj-tag.c | 2 +- .../veejay-server/libvje/effects/threshold.c | 85 +------------------ .../veejay-server/libvje/vj-effect.c | 51 ++++++----- .../veejay-server/libvjmem/memcpy.c | 18 ++++ .../veejay-server/libvjmem/vj-x86.c | 2 +- veejay-current/veejay-server/libvjmem/vjmem.h | 1 + .../veejay-server/libvjmsg/vj-common.c | 2 +- veejay-current/veejay-server/man/veejay.1 | 5 +- .../veejay-server/veejay/liblavplayvj.c | 33 ++++--- veejay-current/veejay-server/veejay/veejay.c | 21 +++-- .../veejay-server/veejay/vj-event.c | 12 ++- veejay-current/veejay-server/veejay/vj-font.c | 11 +-- veejay-current/veejay-server/veejay/vj-lib.h | 21 ++--- .../veejay-server/veejay/vj-perform.c | 80 +++++++++++------ .../veejay-server/veejay/vj-perform.h | 2 +- veejay-current/veejay-server/veejay/vj-task.c | 4 +- 22 files changed, 192 insertions(+), 198 deletions(-) create mode 100644 veejay-current/veejay-server/doc/README.memory diff --git a/veejay-current/veejay-client/src/vj-api.c b/veejay-current/veejay-client/src/vj-api.c index 58328ba1..1c1de072 100644 --- a/veejay-current/veejay-client/src/vj-api.c +++ b/veejay-current/veejay-client/src/vj-api.c @@ -8313,16 +8313,6 @@ static void update_sample_slot_data(int page_num, int slot_num, int sample_id, g sample_slot_t *slot = info->sample_banks[page_num]->slot[slot_num]; sample_gui_slot_t *gui_slot = info->sample_banks[page_num]->gui_slot[slot_num]; -#ifdef STRICT_CHECKING - veejay_msg(VEEJAY_MSG_DEBUG, "update slot %d on page %d with (type=%d,id=%d)", - slot_num, page_num, sample_type, sample_id ); - veejay_msg(VEEJAY_MSG_DEBUG, "(#%d,type=%d,%s,%s) change to (#%d,type=%d,%s,%s)", - slot->sample_id,slot->sample_type,slot->timecode,slot->title, - sample_id,sample_type,timecode,title ); -#endif - - - if(slot->timecode) free(slot->timecode); if(slot->title) free(slot->title); @@ -8350,9 +8340,7 @@ static void update_sample_slot_data(int page_num, int slot_num, int sample_id, g if(sample_id > 0 ) { - gchar frame_title[8]; - snprintf(frame_title, sizeof(frame_title)-1, "%s", slot->title ); - gtk_frame_set_label( GTK_FRAME(gui_slot->frame),frame_title ); + gtk_frame_set_label( GTK_FRAME(gui_slot->frame),slot->title ); } else { diff --git a/veejay-current/veejay-server/doc/README.memory b/veejay-current/veejay-server/doc/README.memory new file mode 100644 index 00000000..55194d19 --- /dev/null +++ b/veejay-current/veejay-server/doc/README.memory @@ -0,0 +1,18 @@ + +STATIC FX CHAIN + +Veejay pre-allocates a large buffer (aprox. 180 MB for 1280x720 video) to cache the entire fx_chain. +If you wish to turn off this option, you can use the -X or --dynamic-fx-chain commandline parameters. +When dynamic allocation is enabled, each chain entry is allocated and freed on the fly between switching samples. +Individual FX are always allocated and freed between switching samples. + +MEMORY CACHE + +Veejay can (optionally) use your RAM to cache video frames from file to memory. By default this option is turned off. +you can enable it by specifying both the -m and -l commandline parameters. They both expect arguments. +Enter a percentage of your total phsyical RAM memory to use for -m and divide it equally over -l slots. + +These options will allow you to commit the frames from the sample's EDL to memory while playing, so that subsequent loops no longer require disk-access. +This option should help you increase the audio playback quality when using the FX chain (reducing or elminating stutter) + + diff --git a/veejay-current/veejay-server/libel/vj-el.c b/veejay-current/veejay-server/libel/vj-el.c index 971800fe..a6907106 100644 --- a/veejay-current/veejay-server/libel/vj-el.c +++ b/veejay-current/veejay-server/libel/vj-el.c @@ -479,7 +479,7 @@ vj_decoder *_el_new_decoder( void *ctx, int id , int width, int height, float fp d->img->height = height; } - ssize_t safe_max_frame_size = (max_frame_size < GREMLIN_GUARDIAN) ? 128 * 1024: RUP8(max_frame_size); + size_t safe_max_frame_size = (max_frame_size < GREMLIN_GUARDIAN) ? 128 * 1024: RUP8(max_frame_size); d->tmp_buffer = (uint8_t*) vj_malloc( sizeof(uint8_t) * safe_max_frame_size ); d->fmt = id; diff --git a/veejay-current/veejay-server/libel/vj-el.h b/veejay-current/veejay-server/libel/vj-el.h index 2c868c3e..3ff0f131 100644 --- a/veejay-current/veejay-server/libel/vj-el.h +++ b/veejay-current/veejay-server/libel/vj-el.h @@ -155,6 +155,8 @@ float vj_el_get_default_framerate( int norm ); char vj_el_get_default_norm( float fps ); +long vj_el_get_mem_size(); + int vj_el_auto_detect_scenes( editlist *el, uint8_t *tmp[4], int w, int h, int dl_threshold ); #endif diff --git a/veejay-current/veejay-server/libsample/sampleadm.c b/veejay-current/veejay-server/libsample/sampleadm.c index 3bc8b9c7..afc973c2 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.c +++ b/veejay-current/veejay-server/libsample/sampleadm.c @@ -2811,7 +2811,7 @@ void ParseEffect(xmlDocPtr doc, xmlNodePtr cur, int dst_sample, int start_at) if (effect_id != -1) { int j; if (!sample_chain_add(dst_sample, chain_index, effect_id)) { - veejay_msg(VEEJAY_MSG_ERROR, "Error parsing effect %d (pos %d)\n", effect_id, chain_index); + veejay_msg(VEEJAY_MSG_ERROR, "Error parsing effect %d (pos %d)", effect_id, chain_index); } else { /* load the parameter values */ diff --git a/veejay-current/veejay-server/libstream/vj-net.c b/veejay-current/veejay-server/libstream/vj-net.c index 1042a82f..ce47176b 100644 --- a/veejay-current/veejay-server/libstream/vj-net.c +++ b/veejay-current/veejay-server/libstream/vj-net.c @@ -56,7 +56,7 @@ typedef struct void *scaler; VJFrame *a; VJFrame *b; - ssize_t bufsize; + size_t bufsize; } threaded_t; #define STATE_INACTIVE 0 diff --git a/veejay-current/veejay-server/libstream/vj-tag.c b/veejay-current/veejay-server/libstream/vj-tag.c index 7b7517f1..30e4d699 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.c +++ b/veejay-current/veejay-server/libstream/vj-tag.c @@ -3878,7 +3878,7 @@ static void tagParseEffect(xmlDocPtr doc, xmlNodePtr cur, int dst_sample) int res = vj_tag_set_effect( dst_sample, chain_index, effect_id ); if(res < 0 ) { - veejay_msg(VEEJAY_MSG_ERROR, "Error parsing effect %d (pos %d) to stream %d\n", + veejay_msg(VEEJAY_MSG_ERROR, "Error parsing effect %d (pos %d) to stream %d", effect_id, chain_index, dst_sample); } else { diff --git a/veejay-current/veejay-server/libvje/effects/threshold.c b/veejay-current/veejay-server/libvje/effects/threshold.c index cd912138..3e330bf6 100644 --- a/veejay-current/veejay-server/libvje/effects/threshold.c +++ b/veejay-current/veejay-server/libvje/effects/threshold.c @@ -83,58 +83,10 @@ static int _dilate_kernel3x3( uint8_t *kernel, uint8_t img[9]) return 1; return 0; } -#ifdef HAVE_ASM_MMX -static inline void load_binary_map( uint8_t *mask ) -{ - __asm __volatile( - "movq (%0), %%mm0\n\t" - :: "r" (mask) - ); -} - -static inline void map_luma( uint8_t *dst, uint8_t *B ) -//static inline void map_luma( uint8_t *dst, uint8_t *B, uint8_t *mask ) -{ - __asm __volatile( - // "movq (%0), %%mm0\n\t" - "movq (%0), %%mm1\n\t" - "pand %%mm0, %%mm1\n\t" - "movq %%mm1, (%1)\n\t" - // :: "r" (mask), "r" (B), "r" (dst) - :: "r" (B) , "r" (dst) - ); -} - -static inline void load_chroma( uint8_t val ) -{ - uint8_t mask[8] = { val,val,val,val, val,val,val,val }; - uint8_t *m = &mask[0]; - - __asm __volatile( - "movq (%0), %%mm3\n\t # mm3: 128,128,128,128, ..." - :: "r" (m) - ); -} - -static inline void map_chroma( uint8_t *dst, uint8_t *B ) -{ - __asm __volatile( - "movq (%0), %%mm1\n\t" - "pand %%mm0, %%mm1\n\t" - "pxor %%mm5, %%mm5\n\t" - "pcmpeqb %%mm1,%%mm5\n\t" - "pand %%mm3,%%mm5\n\t" - "paddb %%mm5,%%mm1\n\t" - "movq %%mm1, (%1) \n\t" - :: "r" (B), "r" (dst) - ); - -} -#endif void threshold_apply( VJFrame *frame, VJFrame *frame2,int width, int height, int threshold, int reverse ) { - unsigned int y; + unsigned int y,x; uint8_t *Y = frame->data[0]; uint8_t *Cb = frame->data[1]; uint8_t *Cr = frame->data[2]; @@ -143,40 +95,10 @@ void threshold_apply( VJFrame *frame, VJFrame *frame2,int width, int height, int uint8_t *Cr2=frame2->data[2]; uint8_t *bmap = binary_img; - + int len = frame->len; softblur_apply( frame, width,height,0 ); - binarify_1src( binary_img,Y,threshold,reverse, width,height); - -#ifdef HAVE_ASM_MMX - int work = (width*height)>>3; - load_chroma( 128 ); - for( y = 0 ; y < work; y ++ ) - { - load_binary_map( bmap ); - map_luma(Y , Y2 ); - map_chroma( Cb, Cb2 ); - map_chroma( Cr, Cr2 ); - //@ we could mmx-ify dilation - Y += 8; - Y2 += 8; - Cb += 8; - Cb2 += 8; - Cr += 8; - Cr2 +=8; - bmap += 8; - } - - do_emms; -#else - -// veejay_memset( Y, 0, width ); -// veejay_memset( Cb, 128, width ); -// veejay_memset( Cr, 128, width ); - -// veejay_memset(Y+(len-width),0, width ); -// veejay_memset(Cb+(len-width),128,width); -// veejay_memset(Cr+(len-width),128,width); + binarify_1src( binary_img,Y,threshold,0, width,height); // len -= width; @@ -223,5 +145,4 @@ void threshold_apply( VJFrame *frame, VJFrame *frame2,int width, int height, int } } } -#endif } diff --git a/veejay-current/veejay-server/libvje/vj-effect.c b/veejay-current/veejay-server/libvje/vj-effect.c index 0680fdc1..ef3fce1f 100644 --- a/veejay-current/veejay-server/libvje/vj-effect.c +++ b/veejay-current/veejay-server/libvje/vj-effect.c @@ -176,6 +176,9 @@ int pixel_U_hi_ = 240; int pixel_Y_lo_ = 16; int pixel_U_lo_ = 16; +static uint8_t *vje_buffer = NULL; +static ssize_t vje_buflen = 0; + int get_pixel_range_min_Y() { return pixel_Y_lo_; } @@ -511,8 +514,8 @@ void vj_effect_initialize(int width, int height, int full_range) veejay_msg(VEEJAY_MSG_WARNING,"Video width should be a multiple of 32 for some effects" ); } - for(k=0; k < MAX_EFFECTS; k++) - vj_effects[k] = NULL; + veejay_memset( vj_effects, 0, sizeof(vj_effects)); + veejay_memset( vj_effect_ready,0,sizeof(vj_effect_ready)); vj_effects[0] = dummy_init(width,height); vj_effects[1] = overlaymagic_init( width,height ); @@ -683,32 +686,35 @@ void vj_effect_initialize(int width, int height, int full_range) } +static void vj_effect_free_parameters( vj_effect *v ) +{ + int i; + for( i = 0; i < v->num_params; i ++ ) { + if( v->param_description[i] ) + free( v->param_description[i] ); + } + free( v->param_description ); +} + void vj_effect_free(vj_effect *ve) { - if(ve->limits[0]) free(ve->limits[0]); - if(ve->limits[1]) free(ve->limits[1]); - if(ve->defaults) free(ve->defaults); - int i = 0; -/* if( ve->param_description != NULL ) { - for( i = 0; ve->param_description[i] != NULL; i ++ ) - free(ve->param_description[i]); - - free(ve->param_description); - } */ - // FIXME cleanup - // if(ve->vjed) free(ve->vjed); - free(ve); + if( ve ) { + if(ve->limits[0]) free(ve->limits[0]); + if(ve->limits[1]) free(ve->limits[1]); + if(ve->defaults) free(ve->defaults); + if(ve->param_description) vj_effect_free_parameters( ve ); + free(ve); + } } void vj_effect_shutdown() { int i; vj_effect_deactivate_all(); for(i=0; i < vj_effect_max_effects(); i++) { - if(vj_effects[i]) { - if( i >= MAX_EFFECTS ) - if(vj_effects[i]->description) free(vj_effects[i]->description); - vj_effect_free(vj_effects[i]); - - } + if(vj_effects[i]) { + if( i >= MAX_EFFECTS && vj_effects[i]->description) + free(vj_effects[i]->description); + vj_effect_free(vj_effects[i]); + } } diff_destroy(); @@ -717,7 +723,6 @@ void vj_effect_shutdown() { rotozoom_destroy(); distortion_destroy(); cali_destroy(); - plug_sys_free(); } @@ -833,7 +838,7 @@ char *vj_effect_get_param_description(int effect_id, int param_nr) int entry; entry = vj_effect_real_to_sequence(effect_id); if (entry > 0 && param_nr < vj_effects[entry]->num_params) - return vj_effects[entry]->param_description[param_nr]; + return vj_effects[entry]->param_description[param_nr]; return "Invalid paramater"; } diff --git a/veejay-current/veejay-server/libvjmem/memcpy.c b/veejay-current/veejay-server/libvjmem/memcpy.c index 09f7ab5c..9b015d91 100644 --- a/veejay-current/veejay-server/libvjmem/memcpy.c +++ b/veejay-current/veejay-server/libvjmem/memcpy.c @@ -1728,3 +1728,21 @@ void benchmark_veejay(int w, int h) benchmark_tasks( n_tasks, n_frames,w,h ); } +void *vj_hmalloc(size_t sze, const char *name) +{ + void *data = vj_malloc( sze ); + if( data == NULL ) { + veejay_msg(VEEJAY_MSG_ERROR, "Unable to allocate memory (needed %ld bytes)", (long) sze ); + return NULL; + } + int tiedtoram = 1; + if( mlock( data,sze ) != 0 ) + tiedtoram = 0; + + veejay_msg(VEEJAY_MSG_DEBUG,"Using %.2f MB RAM %s (memory %s paged to the swap area)", + ((float) sze/1048576.0f), + name, + (tiedtoram ? "is not going to be" : "may be" ) + ); + return data; +} diff --git a/veejay-current/veejay-server/libvjmem/vj-x86.c b/veejay-current/veejay-server/libvjmem/vj-x86.c index 8053f533..c2714665 100644 --- a/veejay-current/veejay-server/libvjmem/vj-x86.c +++ b/veejay-current/veejay-server/libvjmem/vj-x86.c @@ -35,7 +35,7 @@ extern void find_best_memset(void); extern void yuyv_plane_init(); extern void benchmark_tasks(int n_tasks, long n_frames, int w, int h); extern void init_parallel_tasks(int n_tasks); -static int MEM_ALIGNMENT_SIZE = 0; +static int MEM_ALIGNMENT_SIZE = 32; static int CACHE_LINE_SIZE = 64; diff --git a/veejay-current/veejay-server/libvjmem/vjmem.h b/veejay-current/veejay-server/libvjmem/vjmem.h index 2cd79929..c7fbf6e1 100644 --- a/veejay-current/veejay-server/libvjmem/vjmem.h +++ b/veejay-current/veejay-server/libvjmem/vjmem.h @@ -52,4 +52,5 @@ extern void vj_frame_clear1( uint8_t *input, unsigned int value, int size ); extern uint8_t num_threaded_tasks(); extern void vj_frame_slow_threaded( uint8_t **p0_buffer, uint8_t **p1_buffer, uint8_t **img, int len, int uv_len,const float frac ); extern void benchmark_veejay(int w, int h); +extern void *vj_hmalloc(size_t sze, const char *name); #endif diff --git a/veejay-current/veejay-server/libvjmsg/vj-common.c b/veejay-current/veejay-server/libvjmsg/vj-common.c index ec245bcc..b35b2e11 100644 --- a/veejay-current/veejay-server/libvjmsg/vj-common.c +++ b/veejay-current/veejay-server/libvjmsg/vj-common.c @@ -82,7 +82,7 @@ typedef struct { sem_t *semaphore; char **dommel; uint64_t pos; - ssize_t size; + size_t size; } message_ring_t; /* diff --git a/veejay-current/veejay-server/man/veejay.1 b/veejay-current/veejay-server/man/veejay.1 index f1b692cc..71ad9a9f 100644 --- a/veejay-current/veejay-server/man/veejay.1 +++ b/veejay-current/veejay-server/man/veejay.1 @@ -151,7 +151,7 @@ Specify framerate of dummy video .B \-N [01] Specify norm of dummy video (0=PAL, 1=NTSC). defaults to PAL .TP -.B \-M/--multicast-osc
+.B \--multicast-osc
Starts OSC receiver in multicast mode .TP .B \-T/--multicast-vims
@@ -182,6 +182,9 @@ Encode veejay server IP and port number in QR code image .B \-S/--scene-detection Create new samples based on scene detection threshold. .TP +.B \-M/--dynamic-fx-chain +Do not keep the fx chain buffers in RAM. Specify this option if you prefer dynamic allocation instead (slower, but no RAM is reserved) +.TP .B \--benchmark NxN Benchmark veejay's core functions (multi-thread vs single thread model) using a specific resolution NxN .TP diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c index e73c5896..4765c2a7 100644 --- a/veejay-current/veejay-server/veejay/liblavplayvj.c +++ b/veejay-current/veejay-server/veejay/liblavplayvj.c @@ -637,8 +637,6 @@ static int veejay_start_playing_sample( veejay_t *info, int sample_id ) info->sfd = sample_get_framedup(sample_id); - info->uc->render_changed = 1; /* different render list */ - if( info->settings->sample_restart ) sample_reset_offset( sample_id ); /* reset mixing offsets */ @@ -666,7 +664,6 @@ static int veejay_start_playing_stream(veejay_t *info, int stream_id ) int tmp = vj_tag_chain_malloc( stream_id); - info->uc->render_changed = 1; settings->min_frame_num = 1; settings->max_frame_num = vj_tag_get_n_frames( stream_id ); #ifdef HAVE_FREETYPE @@ -1157,10 +1154,6 @@ void veejay_pipe_write_status(veejay_t * info) if (info->uc->chain_changed == 1) info->uc->chain_changed = 0; - if (info->uc->render_changed == 1) - info->uc->render_changed = 0; - - } static char *veejay_concat_paths(char *path, char *suffix) { @@ -1825,7 +1818,11 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t { veejay_msg(VEEJAY_MSG_ERROR, "Unable to initialize Veejay Performer"); return -1; - } + } + + if( vj_el_get_mem_size() == 0 ) + prepare_cache_line( info->uc->max_cached_mem,info->uc->max_cached_slots ); + info->shm = vj_shm_new_master( info->homedir,info->effect_frame1 ); if( !info->shm ) { veejay_msg(VEEJAY_MSG_WARNING, "Unable to initialize shared resource!"); @@ -2665,6 +2662,14 @@ int prepare_cache_line(int perc, int n_slots) } max_memory -= mmap_memory; + max_memory -= (vj_perform_fx_chain_size()/1024); + + if( max_memory <= 0 ) { + veejay_msg(VEEJAY_MSG_ERROR, "Please enter a larger value for -m"); + veejay_msg(VEEJAY_MSG_ERROR, "Need a minimum of %ld MB RAM to run if -M is not specified", vj_perform_fx_chain_size()/(1024*1024)); + veejay_msg(VEEJAY_MSG_ERROR, "Memory frame cache disabled"); + return 1; + } if( n_slots <= 0) n_slots = 1; @@ -2684,10 +2689,9 @@ int prepare_cache_line(int perc, int n_slots) vj_el_init_chunk( chunk_size ); } else { - veejay_msg(VEEJAY_MSG_INFO, "Memory cache disabled"); + veejay_msg(VEEJAY_MSG_INFO, "Memory frame cache disabled"); } - veejay_msg(VEEJAY_MSG_INFO, "Memory map size per EDL is %2.2f Mb",(float) mmap_memory / 1024.0f); - + veejay_msg(VEEJAY_MSG_INFO, "Memory cache size per EDL is %2.2f Mb",(float) mmap_memory / 1024.0f); return 1; } @@ -2763,11 +2767,12 @@ veejay_t *veejay_malloc() info->uc->direction = 1; /* pause */ info->uc->sample_start = 0; info->uc->sample_end = 0; - info->net = 1; + info->uc->ram_chain = 1; /* enable, keep FX chain buffers in memory (reduces the number of malloc/free of frame buffers) */ + info->net = 1; info->status_line = (char*) vj_calloc(sizeof(char) * 1500 ); for( i =0; i < VJ_MAX_CONNECTIONS ; i ++ ) { - info->rlinks[i] = -1; - info->rmodes[i] = -1; + info->rlinks[i] = -1; + info->rmodes[i] = -1; } veejay_memset(info->action_file[0],0,sizeof(info->action_file[0])); diff --git a/veejay-current/veejay-server/veejay/veejay.c b/veejay-current/veejay-server/veejay/veejay.c index b579597f..007cccf7 100644 --- a/veejay-current/veejay-server/veejay/veejay.c +++ b/veejay-current/veejay-server/veejay/veejay.c @@ -48,7 +48,6 @@ #include #include extern void veejay_init_msg_ring(); -extern long vj_el_get_mem_size(); extern void vj_libav_ffmpeg_version(); static veejay_t *info = NULL; static float override_fps = 0.0; @@ -66,7 +65,7 @@ static int n_slots_ = 0; static int max_mem_ = 0; static int live =0; static int ta = 0; -static int osl = 0; + static void CompiledWith() { veejay_msg(VEEJAY_MSG_INFO,"Compilation flags:"); @@ -296,6 +295,8 @@ static void Usage(char *progname) #endif fprintf(stderr, " -S/--scene-detection \tCreate new samples based on scene detection threshold \n"); + fprintf(stderr, + " -M/--dynamic-fx-chain\t\tDo not keep FX chain buffers in RAM (default off)\n"); fprintf(stderr," -q/--quit \t\t\tQuit at end of file\n"); fprintf(stderr,"\n\n"); } @@ -351,7 +352,7 @@ static int set_option(const char *name, char *value) info->settings->use_vims_mcast = 1; info->settings->vims_group_name = strdup(optarg); } - else if (strcmp(name, "multicast-osc") == 0 || strcmp(name, "M") == 0 ) + else if (strcmp(name, "multicast-osc") == 0 ) { check_val(optarg,name); info->settings->use_mcast = 1; @@ -361,11 +362,13 @@ static int set_option(const char *name, char *value) { n_slots_ = atoi( optarg ); if(n_slots_ < 0 ) n_slots_ = 0; else if (n_slots_ > 100) n_slots_ = 100; + info->uc->max_cached_slots = n_slots_; } else if (strcmp(name, "memory" ) == 0 || strcmp(name, "m" ) == 0) { max_mem_ = atoi(optarg); if(max_mem_ < 0 ) max_mem_ = 0; else if (max_mem_ > 100) max_mem_ = 100; + info->uc->max_cached_mem = max_mem_; } else if (strcmp(name, "synchronization") == 0 || strcmp(name, "c") == 0) { info->sync_correction = atoi(optarg); @@ -515,6 +518,10 @@ static int set_option(const char *name, char *value) { info->dummy->active = 1; // enable DUMMY MODE } + else if (strcmp(name, "dynamic-fx-chain" ) == 0 || strcmp(name, "M" ) == 0 ) + { + info->uc->ram_chain = 0; + } else nerr++; /* unknown option - error */ @@ -582,6 +589,7 @@ static int check_command_line_options(int argc, char *argv[]) {"load-generators",1,0,0}, {"qrcode-connection-info",0,0,0}, {"scene-detection",1,0,0}, + {"dynamic-fx-chain",0,0,0}, {0, 0, 0, 0} }; #endif @@ -595,12 +603,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:s:c:t:j:l:p:m:h:w:x:y:r:f:Y:A:N:H:W:M:T:F:nILPVDugvBdibjqeZ:S:", + "o:G:O:a:H:s:c:t:j:l:p:m:h:w:x:y:r:f:Y:A:N:H:W:T:F:nILPVDugvBdibjqeZMS:X:", long_options, &option_index)) != EOF) #else while ((n = getopt(argc, argv, - "o:G:O:a:H:s:c:t:j:l:p:m:h:w:x:y:r:f:Y:A:N:H:W:M:T:F:nILPVDugvBdibjqeZ:S:" + "o:G:O:a:H:s:c:t:j:l:p:m:h:w:x:y:r:f:Y:A:N:H:W:T:F:nILPVDugvBdibjqeZMS:X:" )) != EOF) #endif { @@ -740,9 +748,6 @@ int main(int argc, char **argv) return 0; } - if( vj_el_get_mem_size() == 0 ) - prepare_cache_line( max_mem_, n_slots_ ); - veejay_check_homedir( info ); sigsegfault_handler(); diff --git a/veejay-current/veejay-server/veejay/vj-event.c b/veejay-current/veejay-server/veejay/vj-event.c index ad3c0c9b..b83ee428 100644 --- a/veejay-current/veejay-server/veejay/vj-event.c +++ b/veejay-current/veejay-server/veejay/vj-event.c @@ -4911,6 +4911,8 @@ void vj_event_sample_clear_all(void *ptr, const char format[], va_list ap) } sample_del_all(v->edit_list); + vj_font_set_dict( v->font, NULL ); + veejay_memset(v->seq->samples, 0, sizeof(int) * MAX_SEQUENCES ); v->seq->active = 0; v->seq->size = 0; @@ -9814,6 +9816,12 @@ void vj_event_get_srt_list( void *ptr, const char format[], va_list ap ) return; } + void *font = vj_font_get_dict( v->font ); + if(!font) { + SEND_MSG(v, "000000" ); + return; + } + char **list = vj_font_get_sequences( v->font ); int i; @@ -9835,7 +9843,9 @@ void vj_event_get_srt_list( void *ptr, const char format[], va_list ap ) return; } - str = vj_calloc( len + 20 ); + for ( i = 0; list[i] != NULL; i ++ ) { } + + str = vj_calloc( len + (i*2) + 6 ); char *p = str; sprintf(p, "%06d", len ); p += 6; diff --git a/veejay-current/veejay-server/veejay/vj-font.c b/veejay-current/veejay-server/veejay/vj-font.c index 8eb9d8e0..5ec2aee9 100644 --- a/veejay-current/veejay-server/veejay/vj-font.c +++ b/veejay-current/veejay-server/veejay/vj-font.c @@ -1096,7 +1096,6 @@ static char *select_font( vj_font_t *ec, int id ) static char *get_font_name( vj_font_t *f,const char *font, int id ) { - int len = 0; char *string; int platform,encoding,lang; int error; @@ -1112,7 +1111,6 @@ static char *get_font_name( vj_font_t *f,const char *font, int id ) } FT_SfntName sn,qn,zn; - FT_SfntName sname; FT_UInt snamei,snamec; FT_Face face; @@ -1176,7 +1174,7 @@ static char *get_font_name( vj_font_t *f,const char *font, int id ) } } - int i,k; + int i; for( i=0; i < tlen; i +=2 ) { fontName[i/2] = string[i+1]; @@ -1294,11 +1292,10 @@ void vj_font_dictionary_destroy( void *font, void *dict ) char **items = vevo_list_properties(dict ); if(!items) { vpf(dict); + dict = NULL; return; } - vj_font_t *f = (vj_font_t*) font; - int i; for( i = 0; items[i] != NULL ; i ++ ) { @@ -1312,6 +1309,7 @@ void vj_font_dictionary_destroy( void *font, void *dict ) } free(items); vpf( dict ); + dict = NULL; } @@ -1382,7 +1380,7 @@ static int configure(vj_font_t *f, int size, int font) fallback_font( f ); } - veejay_msg(VEEJAY_MSG_DEBUG, "Using font %s, size %d (#%d)", f->font, size, font ); +// veejay_msg(VEEJAY_MSG_DEBUG, "Using font %s, size %d (#%d)", f->font, size, font ); veejay_memset( selected_default_font, 0, sizeof(selected_default_font)); strncpy( selected_default_font, f->font,strlen(f->font)) ; @@ -2264,7 +2262,6 @@ int vj_font_norender(void *ctx, long position) void vj_font_render_osd_status( void *ctx, void *_picture, char *status_str, int placement ) { - vj_font_t *f = (vj_font_t*) ctx; vj_font_set_osd_text(ctx,status_str); if(placement == 1) { vj_font_text_osd_render( ctx, _picture, 5, 5 ); diff --git a/veejay-current/veejay-server/veejay/vj-lib.h b/veejay-current/veejay-server/veejay/vj-lib.h index 61a656a6..055515ef 100644 --- a/veejay-current/veejay-server/veejay/vj-lib.h +++ b/veejay-current/veejay-server/veejay/vj-lib.h @@ -32,18 +32,13 @@ enum { NO_AUDIO = 0, - AUDIO_PLAY = 1, - AUDIO_RENDER = 2, + AUDIO_PLAY = 1 }; - - - enum { LAVPLAY_STATE_STOP = 0, /* uninitialized state */ LAVPLAY_STATE_PAUSED = 1, /* also known as: speed = 0 */ - LAVPLAY_STATE_PLAYING = 2, /* speed != 0 */ - LAVPLAY_STATE_RENDER_READY = 3, /* render mode */ + LAVPLAY_STATE_PLAYING = 2 /* speed != 0 */ }; /* nmacro recorder, 5 lines code for play back of what you changed at navigation */ @@ -115,7 +110,6 @@ typedef struct int rec_id; } sequencer_t; - typedef struct { pthread_t software_playback_thread; pthread_t playback_thread; @@ -128,10 +122,8 @@ typedef struct { pthread_t signal_thread; sigset_t signal_set; struct timespec lastframe_completion; /* software sync variable */ - long old_field_len; uint64_t save_list_len; /* for editing purposes */ - double spvf; /* seconds per video frame */ int usec_per_frame; /* milliseconds per frame */ int min_frame_num; /* the lowest frame to be played back - normally 0 */ @@ -153,7 +145,6 @@ typedef struct { double spas; /* seconds per audio sample */ int audio_mute; /* controls whether to currently play audio or not */ int state; /* playing, paused or stoppped */ - // pthread_t playback_thread; /* the thread for the whole playback-library */ int offline_ready; int offline_record; int offline_tag_id; @@ -247,7 +238,6 @@ typedef struct { int port; float rtc_delay; int is_server; - int render_changed; int input_device; int geox; int geoy; @@ -255,6 +245,9 @@ typedef struct { int scene_detection; int mouse[4]; char *osd_extra; + int ram_chain; /* keep fx chain buffers in RAM (1) or dynamic pattern (0) */ + int max_cached_mem; + int max_cached_slots; } user_control; typedef struct { @@ -272,8 +265,6 @@ typedef struct { editlist *current_edit_list; editlist *edit_list; /* the playing editlist */ user_control *uc; /* user control */ - -// v4l_video *vj[4]; /* v4l input */ void *osc; VJFrame *plugin_frame; VJFrameInfo *plugin_frame_info; @@ -284,8 +275,6 @@ typedef struct { #ifdef HAVE_DIRECTFB void *dfb; #endif - //vj_ladspa_instance *vli; - //int vli_enabled; int video_out; #ifdef HAVE_GL void *gl; diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c index 55039f89..475f2ac7 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -118,6 +118,8 @@ static uint8_t *down_sample_buffer = NULL; static uint8_t *temp_buffer[4]; static uint8_t *feedback_buffer[4]; static uint8_t *socket_buffer = NULL; +static uint8_t *fx_chain_buffer = NULL; +static size_t fx_chain_buflen = 0; static int sbic = 0; static ycbcr_frame *record_buffer = NULL; // needed for recording invisible streams static VJFrame *helper_frame = NULL; @@ -160,7 +162,7 @@ static void vj_perform_apply_secundary(veejay_t * info, int sample_id,int type, static int vj_perform_tag_complete_buffers(veejay_t * info, int *h); static int vj_perform_increase_sample_frame(veejay_t * info, long num); static int vj_perform_sample_complete_buffers(veejay_t * info, int *h); -static void vj_perform_use_cached_ycbcr_frame(veejay_t *info, int centry, int chain_entry, int width, int height); +static void vj_perform_use_cached_ycbcr_frame(veejay_t *info, int centry, int chain_entry); static int vj_perform_apply_first(veejay_t *info, vjp_kf *todo_info, VJFrame **frames, VJFrameInfo *frameinfo, int e, int c, int n_frames, void *ptr, int playmode ); static int vj_perform_render_sample_frame(veejay_t *info, uint8_t *frame[4], int sample); static int vj_perform_render_tag_frame(veejay_t *info, uint8_t *frame[4]); @@ -519,8 +521,14 @@ static int vj_perform_increase_sample_frame(veejay_t * info, long num) static long vj_perform_alloc_row(veejay_t *info, int c, int plane_len) { const long frame_len = RUP8( ((plane_len+helper_frame->width)/7)*8 ); - uint8_t *buf = vj_malloc(sizeof(uint8_t) * frame_len * 3 * 3); - mlock( buf, frame_len * 3 * sizeof(uint8_t)); + uint8_t *buf; + if(fx_chain_buffer!=NULL) { + buf = fx_chain_buffer + (c * frame_len * 3 * 3); + } + else { + buf = vj_malloc(sizeof(uint8_t) * frame_len * 3 * 3); + mlock( buf, frame_len * 3 * sizeof(uint8_t)); + } if(!buf) return 0; @@ -539,8 +547,10 @@ static void vj_perform_free_row(int c) if(frame_buffer[c]->Y) { - munlock( frame_buffer[c]->Y, frame_len * 3 * 3 ); - free( frame_buffer[c]->Y ); + if(fx_chain_buffer == NULL ) { + munlock( frame_buffer[c]->Y, frame_len * 3 * 3 ); + free( frame_buffer[c]->Y ); + } } frame_buffer[c]->Y = NULL; frame_buffer[c]->Cb = NULL; @@ -672,9 +682,8 @@ int vj_perform_init(veejay_t * info) preview_buffer->Y = (uint8_t*) vj_calloc( RUP8(preview_max_w * preview_max_h * 3) ); - video_output_buffer_convert = 0; - video_output_buffer = - (ycbcr_frame**) vj_malloc(sizeof(ycbcr_frame*) * 2 ); + video_output_buffer_convert = 0; + video_output_buffer = (ycbcr_frame**) vj_malloc(sizeof(ycbcr_frame*) * 2 ); if(!video_output_buffer) return 0; @@ -719,12 +728,12 @@ int vj_perform_init(veejay_t * info) total_used += buf_len; //temp_buffer total_used += buf_len; //feedback_buffer - /* allocate space for frame_buffer, the place we render effects in */ - for (c = 0; c < SAMPLE_MAX_EFFECTS; c++) { + /* allocate space for frame_buffer pointers */ + for (c = 0; c < SAMPLE_MAX_EFFECTS; c++) { frame_buffer[c] = (ycbcr_frame *) vj_calloc(sizeof(ycbcr_frame)); - if(!frame_buffer[c]) return 0; - } + if(!frame_buffer[c]) return 0; + } vj_perform_clear_cache(); veejay_memset( frame_info[0],0,SAMPLE_MAX_EFFECTS); @@ -734,10 +743,26 @@ int vj_perform_init(veejay_t * info) veejay_memset( &pvar_, 0, sizeof( varcache_t)); + size_t tmp1 = 0; + if( info->uc->ram_chain ) { + //allocate fx_chain_buffer + tmp1 = buf_len * 3 * sizeof(uint8_t) * SAMPLE_MAX_EFFECTS; + fx_chain_buffer = vj_hmalloc( tmp1, "in fx chain buffers" ); + if(fx_chain_buffer == NULL ) { + veejay_msg(VEEJAY_MSG_WARNING,"Unable to allocate sufficient memory to keep all FX chain buffers in RAM"); + } else { + total_used += tmp1; + fx_chain_buflen = tmp1; + } + /* tmp1 = [ secundary source on entry X ] [ slow motion buffer A ] [ slow motion buffer B ] + */ + } + veejay_msg(VEEJAY_MSG_INFO, - "Using %.2f MB RAM in performer (memory %s paged to the swap area)", + "Using %.2f MB RAM in performer (memory %s paged to the swap area, %.2f MB pre-allocated for fx-chain)", ((float)total_used/1048576.0f), - ( mlock_success ? "is not going to be" : "may be" ) + ( mlock_success ? "is not going to be" : "may be" ), + ((float)tmp1/1048576.0f) ); if( info->uc->scene_detection ) { @@ -747,6 +772,11 @@ int vj_perform_init(veejay_t * info) return 1; } +size_t vj_perform_fx_chain_size() +{ + return fx_chain_buflen; +} + static void vj_perform_close_audio() { if( lin_audio_buffer_ ) @@ -877,8 +907,6 @@ void vj_perform_free(veejay_t * info) if(frame_buffer[c]) { if(frame_buffer[c]->Y) free(frame_buffer[c]->Y); - if(frame_buffer[c]->Cb) free(frame_buffer[c]->Cb); - if(frame_buffer[c]->Cr) free(frame_buffer[c]->Cr); free(frame_buffer[c]); } } @@ -919,6 +947,12 @@ void vj_perform_free(veejay_t * info) free(preview_buffer->Y); free(preview_buffer); + if(fx_chain_buffer) + { + munlock(fx_chain_buffer, fx_chain_buflen); + free(fx_chain_buffer); + } + if(lzo_) lzo_free(lzo_); } @@ -1334,16 +1368,14 @@ static void vj_perform_reverse_audio_frame(veejay_t * info, int len, } #endif -static void vj_perform_use_cached_ycbcr_frame(veejay_t *info, int centry, int chain_entry, int width, int height) +static void vj_perform_use_cached_ycbcr_frame(veejay_t *info, int centry, int chain_entry) { - int len1 = (width*height); + int len1 = info->effect_frame1->len; if( centry == 0 ) { int len2 = ( info->effect_frame1->ssm == 1 ? len1 : info->effect_frame1->uv_len ); - - vj_perform_copy( primary_buffer[0], frame_buffer[chain_entry], len1, len2 ); frame_buffer[chain_entry]->ssm = info->effect_frame1->ssm; } @@ -1746,7 +1778,7 @@ static void vj_perform_apply_secundary_tag(veejay_t * info, int sample_id, int t } else { - vj_perform_use_cached_ycbcr_frame(info, centry, chain_entry, width,height); + vj_perform_use_cached_ycbcr_frame(info, centry, chain_entry); error = 0; } if(!error) @@ -1764,7 +1796,7 @@ static void vj_perform_apply_secundary_tag(veejay_t * info, int sample_id, int t } else { - vj_perform_use_cached_ycbcr_frame( info, centry, chain_entry, width,height ); + vj_perform_use_cached_ycbcr_frame( info, centry, chain_entry); cached_sample_frames[ 1 + chain_entry ] = sample_id; error = 0; } @@ -1924,7 +1956,7 @@ static void vj_perform_apply_secundary(veejay_t * info, int sample_id, int type, } else { - vj_perform_use_cached_ycbcr_frame(info,centry, chain_entry, width, height); + vj_perform_use_cached_ycbcr_frame(info,centry, chain_entry); error = 0; } if(!error ) @@ -1940,7 +1972,7 @@ static void vj_perform_apply_secundary(veejay_t * info, int sample_id, int type, } else { - vj_perform_use_cached_ycbcr_frame(info,centry, chain_entry,width,height); + vj_perform_use_cached_ycbcr_frame(info,centry, chain_entry); cached_sample_frames[ 1 + chain_entry ] = sample_id; error = 0; } diff --git a/veejay-current/veejay-server/veejay/vj-perform.h b/veejay-current/veejay-server/veejay/vj-perform.h index 293b99b2..391f979a 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.h +++ b/veejay-current/veejay-server/veejay/vj-perform.h @@ -73,7 +73,7 @@ int vj_perform_get_width( veejay_t *info ); int vj_perform_get_height( veejay_t *info ); void vj_perform_follow_fade(int status); - +size_t vj_perform_fx_chain_size(); void vj_perform_record_video_frame(veejay_t *info); diff --git a/veejay-current/veejay-server/veejay/vj-task.c b/veejay-current/veejay-server/veejay/vj-task.c index 0e083ab8..5f27516c 100644 --- a/veejay-current/veejay-server/veejay/vj-task.c +++ b/veejay-current/veejay-server/veejay/vj-task.c @@ -122,8 +122,8 @@ static void task_reset() memset( &p_threads,0,sizeof(p_threads)); memset( &p_tasks,0,sizeof(p_tasks)); - memset( job_list,0,sizeof(pjob_t*) * MAX_WORKERS ); - memset( &vj_task_args,0,sizeof(vj_task_arg_t*) * MAX_WORKERS ); +// memset( job_list,0,sizeof(pjob_t*) * MAX_WORKERS ); +// memset( &vj_task_args,0,sizeof(vj_task_arg_t*) * MAX_WORKERS ); for( i = 0; i < MAX_WORKERS; i ++ ) { memset( job_list[i],0, sizeof(pjob_t)); memset( vj_task_args[i],0, sizeof(vj_task_arg_t));