diff --git a/veejay-current/veejay-server/libel/vj-el.c b/veejay-current/veejay-server/libel/vj-el.c index 80a30dff..683a1e55 100644 --- a/veejay-current/veejay-server/libel/vj-el.c +++ b/veejay-current/veejay-server/libel/vj-el.c @@ -1374,6 +1374,49 @@ void vj_el_scan_video_file( char *filename, int *dw, int *dh, float *dfps, long } +int vj_el_auto_detect_scenes( editlist *el, uint8_t *tmp[4], int w, int h, int dl_threshold ) +{ + long n1 = 0; + long n2 = el->total_frames; + long n; + int dl = 0; + int last_lm = 0; + int index = 0; + long max = (el->total_frames/2) -1; + long prev = 0; + + if( el == NULL || el->is_empty || el->total_frames < 2 ) + return 0; + + for( n = n1; n < n2; n ++ ) { + vj_el_get_video_frame(el, n, tmp ); + int lm = luminance_mean( tmp, w, h ); + if( n == 0 ) { + dl = 0; + } + else { + dl = abs( lm - last_lm ); + } + last_lm = lm; + + veejay_msg(VEEJAY_MSG_DEBUG,"frame %ld/%ld luminance mean %d, delta %d ", n, n2, lm, dl ); + + if( dl > dl_threshold ) { + + if( prev == 0 ) { + sample_new_simple(el,0,n); + veejay_msg(VEEJAY_MSG_INFO,"sampled frames %ld - %ld", 0,n); + } else { + sample_new_simple(el,prev,n); + veejay_msg(VEEJAY_MSG_INFO,"sampled frames %ld - %ld", prev, n ); + } + + prev = n; + index ++; + } + } + return index; +} editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int deinterlace, int force,char norm , int out_format, int width, int height) { diff --git a/veejay-current/veejay-server/libel/vj-el.h b/veejay-current/veejay-server/libel/vj-el.h index 28ee1025..2c868c3e 100644 --- a/veejay-current/veejay-server/libel/vj-el.h +++ b/veejay-current/veejay-server/libel/vj-el.h @@ -155,4 +155,6 @@ float vj_el_get_default_framerate( int norm ); char vj_el_get_default_norm( float fps ); +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 f010dcd9..d3ed3d13 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.c +++ b/veejay-current/veejay-server/libsample/sampleadm.c @@ -337,6 +337,8 @@ sample_info *sample_skeleton_new(long startFrame, long endFrame) return si; } + + int sample_store(sample_info * skel) { hnode_t *sample_node; @@ -359,6 +361,15 @@ int sample_store(sample_info * skel) return 0; } +void sample_new_simple( void *el, long start, long end ) +{ + sample_info *sample = sample_skeleton_new(start,end); + if(sample) { + sample->edit_list = el; + sample_store(sample); + } +} + /**************************************************************************************************** * * sample_get(int sample_id) diff --git a/veejay-current/veejay-server/libsample/sampleadm.h b/veejay-current/veejay-server/libsample/sampleadm.h index 303b04cd..fd58cdb1 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.h +++ b/veejay-current/veejay-server/libsample/sampleadm.h @@ -192,6 +192,7 @@ extern int sample_set_state(int new_state); extern int sample_get_state(); extern sample_info *sample_skeleton_new(long startFrame, long endFrame); extern sample_info *sample_get(int sample_id); +void sample_new_simple( void *el, long start, long end ); extern int sample_store(sample_info * skel); extern int sample_is_deleted(int s1); extern int sample_exists(int sample_id); diff --git a/veejay-current/veejay-server/man/veejay.1 b/veejay-current/veejay-server/man/veejay.1 index 6943f776..f1b692cc 100644 --- a/veejay-current/veejay-server/man/veejay.1 +++ b/veejay-current/veejay-server/man/veejay.1 @@ -179,6 +179,9 @@ Do not start with projection enabled. .B \--qrcode-connection-info Encode veejay server IP and port number in QR code image .TP +.B \-S/--scene-detection +Create new samples based on scene detection threshold. +.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/veejay.c b/veejay-current/veejay-server/veejay/veejay.c index 23092bae..c59b6a34 100644 --- a/veejay-current/veejay-server/veejay/veejay.c +++ b/veejay-current/veejay-server/veejay/veejay.c @@ -294,6 +294,8 @@ static void Usage(char *progname) fprintf(stderr, " --qrcode-connection-info\tEncode veejay's external IP and port number into QR code\n" ); #endif + fprintf(stderr, + " -S/--scene-detection \tCreate new samples based on scene detection threshold \n"); fprintf(stderr," -q/--quit \t\t\tQuit at end of file\n"); fprintf(stderr,"\n\n"); } @@ -412,9 +414,14 @@ static int set_option(const char *name, char *value) } else if (strcmp(name, "size") == 0 || strcmp(name, "s") == 0) { if (sscanf(value, "%dx%d", &info->bes_width, &info->bes_height) != 2) { - fprintf(stderr,"-S/--size parameter requires NxN argument\n"); + fprintf(stderr,"-s/--size parameter requires NxN argument\n"); nerr++; } + } else if (strcmp(name,"scene-detection" ) == 0 || strcmp( name,"S") == 0 ) { + if ((sscanf(value, "%d", &info->uc->scene_detection )) != 1 ) { + fprintf(stderr, "-S/--scene-detection requires threshold argument\n"); + nerr++; + } } #ifdef HAVE_XINERAMA #ifndef X_DISPLAY_MISSING @@ -574,6 +581,7 @@ static int check_command_line_options(int argc, char *argv[]) {"swap-range",0,0,0}, {"load-generators",1,0,0}, {"qrcode-connection-info",0,0,0}, + {"scene-detection",1,0,0}, {0, 0, 0, 0} }; #endif @@ -587,12 +595,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:", + "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:", 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:" + "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:" )) != EOF) #endif { diff --git a/veejay-current/veejay-server/veejay/vj-lib.h b/veejay-current/veejay-server/veejay/vj-lib.h index f378a368..61a656a6 100644 --- a/veejay-current/veejay-server/veejay/vj-lib.h +++ b/veejay-current/veejay-server/veejay/vj-lib.h @@ -252,6 +252,7 @@ typedef struct { int geox; int geoy; int file_as_sample; + int scene_detection; int mouse[4]; char *osd_extra; } user_control; diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c index f5edaa7b..0ec34f34 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -740,6 +740,10 @@ int vj_perform_init(veejay_t * info) ( mlock_success ? "is not going to be" : "may be" ) ); + if( info->uc->scene_detection ) { + vj_el_auto_detect_scenes( info->edit_list, temp_buffer, w,h, info->uc->scene_detection ); + } + return 1; }