From fdd3a4bd4cdfae0857d0cddfff11e2b30d3df381 Mon Sep 17 00:00:00 2001 From: c0ntrol Date: Thu, 19 May 2016 22:53:50 +0200 Subject: [PATCH] issue #111, fix offline recording, allow offline recording while recording from playing sample or stream, added new tag type 'clone' which lets you clone any input stream, added clone callback to sample copy button, added offline recording widgets to sample bank, added new VIMS 252 --- .../share/gveejay.reloaded.glade | 147 ++++++++++- veejay-current/veejay-client/src/callback.c | 41 +++- veejay-current/veejay-client/src/vj-api.c | 10 +- .../veejay-server/libstream/vj-tag.c | 74 +++++- .../veejay-server/libstream/vj-tag.h | 4 +- .../veejay-server/veejay/liblavplayvj.c | 2 +- veejay-current/veejay-server/veejay/vims.h | 1 + .../veejay-server/veejay/vj-event.c | 67 ++--- .../veejay-server/veejay/vj-event.h | 1 + .../veejay-server/veejay/vj-eventman.c | 11 + .../veejay-server/veejay/vj-perform.c | 228 ++++++++++++------ 11 files changed, 463 insertions(+), 123 deletions(-) diff --git a/veejay-current/veejay-client/share/gveejay.reloaded.glade b/veejay-current/veejay-client/share/gveejay.reloaded.glade index bb2f799f..e263c2f8 100644 --- a/veejay-current/veejay-client/share/gveejay.reloaded.glade +++ b/veejay-current/veejay-client/share/gveejay.reloaded.glade @@ -1661,6 +1661,18 @@ + + + + + + + + + + + + True @@ -12903,6 +12915,121 @@ YUV (current) True False + + + True + False + + + True + True + Offline recording duration in frames + False + + 5 + True + False + False + True + True + 1500 0 9999999 1 25 0 + 1 + True + + + False + True + 0 + + + + + True + True + True + True + Start recording + + + + True + False + Start offline recorder + icon_record.png + + + + + False + False + 1 + + + + + True + True + True + True + Cancel offline recording + + + + True + False + 0 + 0 + + + True + False + 2 + + + True + False + icon_recordstop.png + + + False + False + 0 + + + + + + + + + False + False + 2 + + + + + True + True + False + True + Auto play sample after recording has completed + True + True + + + True + False + 3 + + + + + False + True + 0 + + True @@ -12933,7 +13060,7 @@ YUV (current) True True - 0 + 1 @@ -13011,7 +13138,7 @@ YUV (current) False True - 1 + 2 @@ -13044,7 +13171,7 @@ YUV (current) True True - 2 + 3 @@ -14626,7 +14753,7 @@ YUV (current) True True False - Copy sample to new + Copy sample to new or clone stream @@ -16039,6 +16166,18 @@ YUV (current) + + + + + + + + + + + + True diff --git a/veejay-current/veejay-client/src/callback.c b/veejay-current/veejay-client/src/callback.c index af623580..e7469221 100644 --- a/veejay-current/veejay-client/src/callback.c +++ b/veejay-current/veejay-client/src/callback.c @@ -2077,18 +2077,49 @@ void on_button_browse_clicked(GtkWidget *widget, gpointer user_data) free(test); } +void on_button_offline_start_clicked(GtkWidget *widget, gpointer user_data) +{ + int stream_id = 0; + if( info->selection_slot ) { + stream_id = info->selection_slot->sample_type != 0 ? info->selection_slot->sample_id : 0; + } + else if (info->selected_slot ) { + stream_id = info->selected_slot->sample_type != 0 ? info->selected_slot->sample_id : 0; + } + + if( stream_id > 0 ) { + multi_vims( VIMS_STREAM_OFFLINE_REC_START, "%d %d %d", stream_id, get_nums("spin_offlineduration1" ), is_button_toggled("button_offline_autoplay1")); + } +} +void on_button_offline_stop_clicked(GtkWidget *widget, gpointer user_data) +{ + single_vims( VIMS_STREAM_OFFLINE_REC_STOP ); +} + void on_button_clipcopy_clicked(GtkWidget *widget, gpointer user_data) { if(info->selection_slot ) { - multi_vims( VIMS_SAMPLE_COPY, "%d", info->selection_slot->sample_id ); - gveejay_new_slot(MODE_SAMPLE); + if( info->selection_slot->sample_type != 0 ) { + multi_vims( VIMS_STREAM_NEW_CLONE, "%d", info->selection_slot->sample_id ); + gveejay_new_slot(MODE_STREAM); + } + else { + multi_vims( VIMS_SAMPLE_COPY, "%d", info->selection_slot->sample_id ); + gveejay_new_slot(MODE_SAMPLE); + } } else if (info->selected_slot ) { - multi_vims( VIMS_SAMPLE_COPY, "%d", info->selected_slot->sample_id ); - gveejay_new_slot(MODE_SAMPLE); - } + if( info->selected_slot->sample_type != 0 ) { + multi_vims( VIMS_STREAM_NEW_CLONE, "%d", info->selected_slot->sample_id ); + gveejay_new_slot(MODE_STREAM); + } + else { + multi_vims( VIMS_SAMPLE_COPY, "%d", info->selected_slot->sample_id ); + gveejay_new_slot(MODE_SAMPLE); + } + } } void on_check_priout_fullscreen_clicked( diff --git a/veejay-current/veejay-client/src/vj-api.c b/veejay-current/veejay-client/src/vj-api.c index 8381af94..e608b635 100644 --- a/veejay-current/veejay-client/src/vj-api.c +++ b/veejay-current/veejay-client/src/vj-api.c @@ -154,6 +154,8 @@ enum STREAM_MCAST = 14, STREAM_YUV4MPEG = 1, STREAM_AVFORMAT = 12, + STREAM_CLONE = 15, + STREAM_VLOOP = 3, STREAM_PICTURE = 5 }; @@ -4836,6 +4838,12 @@ static void load_samplelist_info(gboolean with_reset_slotselection) case STREAM_GENERATOR: snprintf(source,sizeof(source),"Z%d",values[0]); break; + case STREAM_CLONE: + snprintf(source,sizeof(source),"T%d", values[0]); + break; + case STREAM_VLOOP: + snprintf(source,sizeof(source),"vloop %d", values[0]); + break; default: snprintf(source,sizeof(source),"??? %d", values[0]); break; @@ -8724,7 +8732,7 @@ static void set_selection_of_slot_in_samplebank(gboolean active) color.green = 0; color.red =0; } - + // gtk_widget_modify_fg ( GTK_WIDGET(info->selection_gui_slot->title), // GTK_STATE_NORMAL, &color ); gtk_widget_modify_fg ( GTK_WIDGET(info->selection_gui_slot->timecode), diff --git a/veejay-current/veejay-server/libstream/vj-tag.c b/veejay-current/veejay-server/libstream/vj-tag.c index 81e6d576..6b7f296c 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.c +++ b/veejay-current/veejay-server/libstream/vj-tag.c @@ -343,6 +343,24 @@ void vj_tag_record_init(int w, int h) { } +static int _vj_tag_new_clone(vj_tag *tag, int which_id ) +{ + vj_tag *tag2 = vj_tag_get(which_id); + if( tag2 == NULL ) { + return 0; + } + + char tmp[128]; + snprintf(tmp,sizeof(tmp),"T%d", which_id ); + tag->extra = strdup(tmp); + + tag2->clone ++; + + tag->active = 1; + tag->video_channel = which_id; + return 1; +} + 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 ) { char tmp[1024]; @@ -1108,7 +1126,15 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, int pix_f tag->active = 1; break; + case VJ_TAG_TYPE_CLONE: + snprintf(tag->source_name, SOURCE_NAME_LEN, "[clone %d]", tag->id ); + if( _vj_tag_new_clone(tag,channel) == 0 ) { + free(tag->source_name); + free(tag); + return -1; + } + break; default: veejay_msg(0, "Stream type %d invalid", type ); free(tag->source_name); @@ -1116,7 +1142,7 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, int pix_f return -1; } - vj_tag_get_by_type( tag->source_type, tag->descr); + vj_tag_get_by_type( tag->id, tag->source_type, tag->descr); /* effect chain is empty */ for (i = 0; i < SAMPLE_MAX_EFFECTS; i++) @@ -1244,10 +1270,19 @@ int vj_tag_del(int id) #endif if(tag->extra) - free(tag->extra); + free(tag->extra); /* stop streaming in first */ switch(tag->source_type) { + case VJ_TAG_TYPE_CLONE: + { + int t2 = tag->video_channel; + vj_tag *tag2 = vj_tag_get( t2 ); + if( tag2 ) { + if(tag2->clone > 0 ) + tag2->clone --; + } + } case VJ_TAG_TYPE_V4L: if(tag->capture_type==1) { #ifdef HAVE_V4L2 @@ -2431,7 +2466,7 @@ int vj_tag_disable(int t1) { { net_thread_stop( tag ); } - if(tag->source_type == VJ_TAG_TYPE_V4L ) + if(tag->source_type == VJ_TAG_TYPE_V4L && !tag->clone ) { #ifdef HAVE_V4L2 if(tag->capture_type==1) { @@ -2753,13 +2788,13 @@ void vj_tag_get_source_name(int t1, char *dst) { vj_tag *tag = vj_tag_get(t1); if (tag) { - sprintf(dst, "%s", tag->source_name); + sprintf(dst, "%s", tag->source_name); } else { - vj_tag_get_description( tag->source_type, dst ); + vj_tag_get_description( tag->source_type, dst ); } } -void vj_tag_get_by_type(int type, char *description ) +void vj_tag_get_by_type(int id,int type, char *description ) { switch (type) { case VJ_TAG_TYPE_GENERATOR: @@ -2796,8 +2831,13 @@ void vj_tag_get_by_type(int type, char *description ) case VJ_TAG_TYPE_CALI: sprintf(description, "%s", "Image Calibration"); break; - } - + case VJ_TAG_TYPE_CLONE: + sprintf(description, "%s", "Clone" ); + break; + default: + sprintf(description ,"T%d", id ); + break; + } } void vj_tag_get_descriptive(int id, char *description) @@ -2809,7 +2849,7 @@ void vj_tag_get_descriptive(int id, char *description) } else { - vj_tag_get_by_type( tag->source_type, description ); + vj_tag_get_by_type( id, tag->source_type, description ); } } @@ -3591,13 +3631,25 @@ int vj_tag_get_frame(int t1, VJFrame *dst, uint8_t * abuffer) case VJ_TAG_TYPE_COLOR: dummy_rgb_apply( dst, tag->color_r,tag->color_g,tag->color_b ); break; + case VJ_TAG_TYPE_CLONE: + { + int t2 = tag->video_channel; + vj_tag *tag2 = vj_tag_get(t2); + if(tag2 && tag2->clone == 0) + tag2->clone ++; //@ auto restore + if( vj_tag_get_frame(t2, dst, NULL) <= 0 ) { + dummy_rgb_apply( dst, 0,0,0 ); + } + } + break; case VJ_TAG_TYPE_NONE: break; default: break; - } - return 1; + } + + return 1; } diff --git a/veejay-current/veejay-server/libstream/vj-tag.h b/veejay-current/veejay-server/libstream/vj-tag.h index e75c97c9..53c2ef06 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.h +++ b/veejay-current/veejay-server/libstream/vj-tag.h @@ -31,6 +31,7 @@ #define VJ_TAG_TYPE_SHM 11 #define VJ_TAG_TYPE_NET 13 #define VJ_TAG_TYPE_MCAST 14 +#define VJ_TAG_TYPE_CLONE 15 #define VJ_TAG_MAX_V4L 16 #define VJ_TAG_MAX_STREAM_IN 255 #define VJ_TAG_TYPE_DV1394 17 @@ -80,6 +81,7 @@ typedef struct { int video_channel; int capture_type; int encoder_active; + int clone; unsigned long sequence_num; char encoder_base[256]; char encoder_destination[256]; @@ -330,7 +332,7 @@ int vj_tag_continue_record( int t1 ); int vj_tag_set_logical_index(int t1, int stream_nr); int vj_tag_set_description(int t1, char *descr); int vj_tag_get_description(int t1, char *descr); -void vj_tag_get_by_type( int type, char *descr ); +void vj_tag_get_by_type(int id, int type, char *descr ); int vj_tag_get_width(); int vj_tag_get_height(); int vj_tag_get_uvlen(); diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c index bc2cc66b..ae0e491c 100644 --- a/veejay-current/veejay-server/veejay/liblavplayvj.c +++ b/veejay-current/veejay-server/veejay/liblavplayvj.c @@ -844,7 +844,7 @@ int veejay_create_tag(veejay_t * info, int type, char *filename, int id = vj_tag_new(type, filename, index, info->edit_list, info->pixel_format, channel, device,info->settings->composite ); char descr[200]; veejay_memset(descr,0,200); - vj_tag_get_by_type(type,descr); + vj_tag_get_by_type(id,type,descr); if(id > 0 ) { info->nstreams++; veejay_msg(VEEJAY_MSG_INFO, "New Input Stream '%s' with ID %d created",descr, id ); diff --git a/veejay-current/veejay-server/veejay/vims.h b/veejay-current/veejay-server/veejay/vims.h index 690f06d3..48a3a2ec 100644 --- a/veejay-current/veejay-server/veejay/vims.h +++ b/veejay-current/veejay-server/veejay/vims.h @@ -196,6 +196,7 @@ enum { VIMS_STREAM_NEW_PICTURE = 247, VIMS_STREAM_NEW_GENERATOR = 250, VIMS_STREAM_NEW_SHARED = 251, + VIMS_STREAM_NEW_CLONE = 252, VIMS_STREAM_OFFLINE_REC_START = 228, VIMS_STREAM_OFFLINE_REC_STOP = 229, VIMS_STREAM_REC_START = 230, diff --git a/veejay-current/veejay-server/veejay/vj-event.c b/veejay-current/veejay-server/veejay/vj-event.c index 133b8532..6a0f8421 100644 --- a/veejay-current/veejay-server/veejay/vj-event.c +++ b/veejay-current/veejay-server/veejay/vj-event.c @@ -4464,6 +4464,7 @@ void vj_event_sample_rec_start( void *ptr, const char format[], va_list ap) void vj_event_sample_rec_stop(void *ptr, const char format[], va_list ap) { + char avi_file[1024]; veejay_t *v = (veejay_t*)ptr; if( SAMPLE_PLAYING(v)) @@ -4476,7 +4477,6 @@ void vj_event_sample_rec_stop(void *ptr, const char format[], va_list ap) if( sample_stop_encoder( stop_sample ) == 1 ) { - char avi_file[1024]; v->settings->sample_record = 0; if( sample_get_encoded_file( stop_sample, avi_file) <= 0 ) { @@ -6847,6 +6847,22 @@ void vj_event_cali_write_file( void *ptr, const char format[], va_list ap) } } +void vj_event_stream_new_clone( void *ptr, const char format[], va_list ap ) +{ + char *str = NULL; + int args[2]; + veejay_t *v = (veejay_t*) ptr; + + P_A(args,str,format,ap); + + int id = veejay_create_tag( v, VJ_TAG_TYPE_CLONE, NULL, v->nstreams, args[0],args[0] ); + + if( id <= 0 ) + veejay_msg(VEEJAY_MSG_ERROR, "Unable to create a clone of stream %d", args[0]); + else + veejay_msg(VEEJAY_MSG_ERROR, "Created a clone of stream %d", args[0]); +} + void vj_event_stream_new_cali( void *ptr, const char format[], va_list ap) { char str[1024]; @@ -7446,11 +7462,12 @@ static void _vj_event_tag_record( veejay_t *v , int *args, char *str ) return; } - if( vj_tag_init_encoder( v->uc->sample_id, tmp, format, - args[0]) <= 0 ) + if( vj_tag_init_encoder( v->uc->sample_id, tmp, format, args[0]) <= 0 ) { veejay_msg(VEEJAY_MSG_INFO, "Error trying to start recording from stream %d", v->uc->sample_id); - vj_tag_stop_encoder(v->uc->sample_id); + if(!v->settings->offline_record || v->settings->offline_tag_id != v->uc->sample_id) { + vj_tag_stop_encoder(v->uc->sample_id); + } v->settings->tag_record = 0; return; } @@ -7481,6 +7498,7 @@ void vj_event_tag_rec_start(void *ptr, const char format[], va_list ap) void vj_event_tag_rec_stop(void *ptr, const char format[], va_list ap) { + char avi_file[1024]; veejay_t *v = (veejay_t *)ptr; video_playback_setup *s = v->settings; @@ -7493,12 +7511,7 @@ void vj_event_tag_rec_stop(void *ptr, const char format[], va_list ap) return; } - char avi_file[255]; - if( !vj_tag_get_encoded_file(v->uc->sample_id, avi_file)) - { - veejay_msg(VEEJAY_MSG_ERROR, "Dont know where I put the file?!"); - return; - } + vj_tag_get_encoded_file(v->uc->sample_id, avi_file); // create new sample int ns = veejay_edit_addmovie_sample( v,avi_file, 0 ); @@ -7525,15 +7538,6 @@ void vj_event_tag_rec_stop(void *ptr, const char format[], va_list ap) veejay_change_playback_mode( v, VJ_PLAYBACK_MODE_SAMPLE, last_id ); } } - else - { - if(v->settings->offline_record) - { - veejay_msg(VEEJAY_MSG_ERROR, "Perhaps you want to stop recording from a non visible stream ? See VIMS id %d", - VIMS_STREAM_OFFLINE_REC_STOP); - } - veejay_msg(VEEJAY_MSG_ERROR, "Not recording from visible stream"); - } } void vj_event_tag_rec_offline_start(void *ptr, const char format[], va_list ap) @@ -7548,12 +7552,12 @@ void vj_event_tag_rec_offline_start(void *ptr, const char format[], va_list ap) return; } - if( v->settings->tag_record) + if( v->settings->tag_record && STREAM_PLAYING(v) && v->uc->sample_id == v->settings->offline_tag_id) { - veejay_msg(VEEJAY_MSG_ERROR ,"Please stop the stream recorder first"); + veejay_msg(VEEJAY_MSG_ERROR ,"Please stop the stream recorder on stream %d first", v->uc->sample_id); return; } - + if( vj_tag_exists(args[0])) { char tmp[255]; @@ -7571,7 +7575,7 @@ void vj_event_tag_rec_offline_start(void *ptr, const char format[], va_list ap) if(!veejay_create_temp_file(prefix, tmp )) { - veejay_msg(VEEJAY_MSG_ERROR, "Error creating temporary file %s. Unable to start offline recorder", tmp); + veejay_msg(VEEJAY_MSG_ERROR, "(Offline) Error creating temporary file %s. Unable to start offline recorder", tmp); return; } @@ -7596,22 +7600,20 @@ void vj_event_tag_rec_offline_start(void *ptr, const char format[], va_list ap) void vj_event_tag_rec_offline_stop(void *ptr, const char format[], va_list ap) { + char avi_file[1024]; veejay_t *v = (veejay_t*)ptr; video_playback_setup *s = v->settings; if(s->offline_record) { - if( vj_tag_stop_encoder( s->offline_tag_id ) == 0 ) + if( vj_tag_stop_encoder( s->offline_tag_id ) == 1 ) { - char avi_file[255]; - - if( vj_tag_get_encoded_file(v->uc->sample_id, avi_file)!=0) return; - + vj_tag_get_encoded_file(s->offline_tag_id, avi_file); + // create new sample int ns = veejay_edit_addmovie_sample(v,avi_file,0); - if(ns) { - if( vj_tag_get_encoded_frames(v->uc->sample_id) > 0) + if( vj_tag_get_encoded_frames(s->offline_tag_id) > 0) veejay_msg(VEEJAY_MSG_INFO, "Created new sample %d from file %s", ns,avi_file); } @@ -7620,7 +7622,7 @@ void vj_event_tag_rec_offline_stop(void *ptr, const char format[], va_list ap) veejay_msg(VEEJAY_MSG_ERROR, "Cannot add videofile %s to EditList!",avi_file); } - vj_tag_reset_encoder( v->uc->sample_id); + vj_tag_reset_encoder(s->offline_tag_id); if(s->offline_created_sample) { @@ -7633,6 +7635,9 @@ void vj_event_tag_rec_offline_stop(void *ptr, const char format[], va_list ap) s->offline_tag_id = 0; s->offline_created_sample = 0; } + else { + veejay_msg(0, "(Offline) recorder not active" ); + } } diff --git a/veejay-current/veejay-server/veejay/vj-event.h b/veejay-current/veejay-server/veejay/vj-event.h index 84c6eb7b..d25e21e9 100644 --- a/veejay-current/veejay-server/veejay/vj-event.h +++ b/veejay-current/veejay-server/veejay/vj-event.h @@ -314,6 +314,7 @@ void vj_event_v4l_blackframe( void *ptr, const char format[], va_list ap ); void vj_event_cali_write_file( void *ptr, const char format[], va_list ap ); void vj_event_stream_new_cali( void *ptr, const char format[], va_list ap ); +void vj_event_stream_new_clone( void *ptr, const char format[], va_list ap ); void vj_event_get_cali_image ( void *ptr, const char format[], va_list ap ); void vj_event_sub_render( void *ptr, const char format[], va_list ap ); void vj_event_send_shm_info( void *ptr, const char format[], va_list ap); diff --git a/veejay-current/veejay-server/veejay/vj-eventman.c b/veejay-current/veejay-server/veejay/vj-eventman.c index 490c846d..af2c2c41 100644 --- a/veejay-current/veejay-server/veejay/vj-eventman.c +++ b/veejay-current/veejay-server/veejay/vj-eventman.c @@ -1249,6 +1249,17 @@ void vj_init_vevo_events(void) ".so plugin filename (must have been loaded at startup)", NULL ); + index_map_[VIMS_STREAM_NEW_CLONE] = _new_event( + "%d", + VIMS_STREAM_NEW_CLONE, + "Clone an existing stream as a new stream", + vj_event_stream_new_clone, + 1, + VIMS_REQUIRE_ALL_PARAMS, + "Stream ID", + 0, + NULL ); + index_map_[VIMS_STREAM_NEW_V4L] = _new_event( "%d %d", VIMS_STREAM_NEW_V4L, diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c index 17557911..7353fddd 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -2629,25 +2629,42 @@ static int vj_perform_render_sample_frame(veejay_t *info, uint8_t *frame[4], int return res; } +static int vj_perform_render_offline_tag_frame(veejay_t *info, uint8_t *frame[4]) +{ + vj_tag_get_frame( info->settings->offline_tag_id, info->effect_frame1, NULL ); + + return vj_tag_record_frame( info->settings->offline_tag_id, info->effect_frame1->data, NULL, 0, info->pixel_format ); +} static int vj_perform_render_tag_frame(veejay_t *info, uint8_t *frame[4]) { - int sample_id = info->uc->sample_id; - - if(info->settings->offline_record) - sample_id = info->settings->offline_tag_id; - - if(info->settings->offline_record) - { - if (!vj_tag_get_frame(sample_id, info->effect_frame1, NULL)) - { - return 0;//skip and dont care - } - } - - return vj_tag_record_frame( sample_id, frame, NULL, 0, info->pixel_format); + return vj_tag_record_frame( info->uc->sample_id, frame, NULL, 0, info->pixel_format); } +static int vj_perform_record_offline_commit_single(veejay_t *info) +{ + char filename[1024]; + + int stream_id = info->settings->offline_tag_id; + if(vj_tag_get_encoded_file(stream_id, filename)) + { + int df = vj_event_get_video_format(); + int id = 0; + if( df == ENCODER_YUV4MPEG || df == ENCODER_YUV4MPEG420 ) { + id = veejay_create_tag( info, VJ_TAG_TYPE_YUV4MPEG,filename,info->nstreams,0,0 ); + } else { + id = veejay_edit_addmovie_sample(info, filename, 0); + } + if( id <= 0 ) + { + veejay_msg(VEEJAY_MSG_ERROR, "Adding file %s to new sample", filename); + return 0; + } + return id; + } + return 0; +} + static int vj_perform_record_commit_single(veejay_t *info) { char filename[1024]; @@ -2672,7 +2689,7 @@ static int vj_perform_record_commit_single(veejay_t *info) return id; } else { - if(info->uc->playback_mode == VJ_PLAYBACK_MODE_SAMPLE && !info->settings->offline_record) + if(info->uc->playback_mode == VJ_PLAYBACK_MODE_SAMPLE) { if(sample_get_encoded_file(info->uc->sample_id, filename)) { @@ -2694,9 +2711,9 @@ static int vj_perform_record_commit_single(veejay_t *info) } } - if(info->uc->playback_mode==VJ_PLAYBACK_MODE_TAG || info->settings->offline_record) + if(info->uc->playback_mode==VJ_PLAYBACK_MODE_TAG) { - int stream_id = (info->settings->offline_record ? info->settings->offline_tag_id : info->uc->sample_id); + int stream_id = info->uc->sample_id; if(vj_tag_get_encoded_file(stream_id, filename)) { int df = vj_event_get_video_format(); @@ -2718,12 +2735,42 @@ static int vj_perform_record_commit_single(veejay_t *info) return 0; } +void vj_perform_record_offline_stop(veejay_t *info) +{ + video_playback_setup *settings = info->settings; + int df = vj_event_get_video_format(); + + int stream_id = settings->offline_tag_id; + int play = settings->offline_created_sample; + + vj_tag_reset_encoder(stream_id); + vj_tag_reset_autosplit(stream_id); + + settings->offline_record = 0; + settings->offline_created_sample = 0; + settings->offline_tag_id = 0; + + if( play ) { + if(df != ENCODER_YUV4MPEG && df != ENCODER_YUV4MPEG420) + { + info->uc->playback_mode = VJ_PLAYBACK_MODE_SAMPLE; + int id = sample_highest_valid_id(); + veejay_set_sample(info, id ); + veejay_msg(VEEJAY_MSG_INFO, "Autoplaying new sample %d",id); + } + else { + + veejay_msg(VEEJAY_MSG_INFO, "Completed offline recording"); + } + } +} + void vj_perform_record_stop(veejay_t *info) { video_playback_setup *settings = info->settings; int df = vj_event_get_video_format(); - if(info->uc->playback_mode==VJ_PLAYBACK_MODE_SAMPLE && !info->settings->offline_record) + if(info->uc->playback_mode==VJ_PLAYBACK_MODE_SAMPLE) { sample_reset_encoder(info->uc->sample_id); sample_reset_autosplit(info->uc->sample_id); @@ -2741,24 +2788,17 @@ void vj_perform_record_stop(veejay_t *info) settings->sample_record = 0; settings->sample_record_switch =0; settings->render_list = 0; - } else if(info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG || info->settings->offline_record) + + } + else if(info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG) { - int stream_id = (settings->offline_record ? settings->offline_tag_id : info->uc->sample_id); + int stream_id = info->uc->sample_id; int play = settings->tag_record_switch; vj_tag_reset_encoder(stream_id); - vj_tag_reset_autosplit(stream_id); - if(settings->offline_record) - { - play = settings->offline_created_sample; - settings->offline_record = 0; - settings->offline_created_sample = 0; - settings->offline_tag_id = 0; - } - else - { - settings->tag_record = 0; - settings->tag_record_switch = 0; - } + vj_tag_reset_autosplit(stream_id); + + settings->tag_record = 0; + settings->tag_record_switch = 0; if(play) { @@ -2837,32 +2877,82 @@ void vj_perform_record_sample_frame(veejay_t *info, int sample, int type) { } } +void vj_perform_record_offline_tag_frame(veejay_t *info) +{ + video_playback_setup *settings = info->settings; + uint8_t *frame[4]; + int res = 1; + int stream_id = settings->offline_tag_id; + + if( record_buffer->Y == NULL ) + vj_perform_record_buffer_init(); + + frame[0] = record_buffer->Y; + frame[1] = record_buffer->Cb; + frame[2] = record_buffer->Cr; + frame[3] = NULL; + + info->effect_frame1->data[0] = frame[0]; + info->effect_frame1->data[1] = frame[1]; + info->effect_frame1->data[2] = frame[2]; + info->effect_frame1->data[3] = frame[3]; + + if(available_diskspace()) + res = vj_perform_render_offline_tag_frame(info, frame); + + if( res == 2) + { + int df = vj_event_get_video_format(); + long frames_left = vj_tag_get_frames_left(stream_id) ; + + vj_tag_stop_encoder( stream_id ); + int n = vj_perform_record_offline_commit_single( info ); + vj_tag_reset_encoder( stream_id ); + + if(frames_left > 0 ) + { + if( vj_tag_init_encoder( stream_id, NULL, + df, frames_left)==-1) + { + veejay_msg(VEEJAY_MSG_WARNING,"Error while auto splitting."); + report_bug(); + } + } + else + { + long len = vj_tag_get_total_frames(stream_id); + + veejay_msg(VEEJAY_MSG_DEBUG, "Added new sample %d of %ld frames",n,len); + vj_tag_reset_encoder( stream_id ); + vj_tag_reset_autosplit( stream_id ); + } + } + + if( res == 1) + { + vj_tag_stop_encoder(stream_id); + vj_perform_record_offline_commit_single( info ); + vj_perform_record_offline_stop(info); + } + + if( res == -1) + { + vj_tag_stop_encoder(stream_id); + vj_perform_record_offline_stop(info); + } + +} void vj_perform_record_tag_frame(veejay_t *info) { video_playback_setup *settings = info->settings; uint8_t *frame[4]; int res = 1; int stream_id = info->uc->sample_id; - if( settings->offline_record ) - stream_id = settings->offline_tag_id; - - if(settings->offline_record) - { - if( record_buffer->Y == NULL ) - vj_perform_record_buffer_init(); - - frame[0] = record_buffer->Y; - frame[1] = record_buffer->Cb; - frame[2] = record_buffer->Cr; - frame[3] = NULL; - } - else - { - frame[0] = primary_buffer[0]->Y; - frame[1] = primary_buffer[0]->Cb; - frame[2] = primary_buffer[0]->Cr; - frame[3] = NULL; - } + + frame[0] = primary_buffer[0]->Y; + frame[1] = primary_buffer[0]->Cb; + frame[2] = primary_buffer[0]->Cr; + frame[3] = NULL; info->effect_frame1->data[0] = frame[0]; info->effect_frame1->data[1] = frame[1]; @@ -2882,8 +2972,7 @@ void vj_perform_record_tag_frame(veejay_t *info) { vj_tag_reset_encoder( stream_id ); if(frames_left > 0 ) { - if( vj_tag_init_encoder( stream_id, NULL, - df, frames_left)==-1) + if( vj_tag_init_encoder( stream_id, NULL, df, frames_left)==-1) { veejay_msg(VEEJAY_MSG_WARNING, "Error while auto splitting."); @@ -2908,10 +2997,10 @@ void vj_perform_record_tag_frame(veejay_t *info) { } if( res == -1) - { + { vj_tag_stop_encoder(stream_id); vj_perform_record_stop(info); - } + } } @@ -3639,6 +3728,11 @@ static void vj_perform_render_font( veejay_t *info, video_playback_setup *settin //FIXME refactor recorders - there only needs to be two: online (what is playing) , offline (what is not playing but active) static void vj_perform_record_frame( veejay_t *info ) { + if( info->settings->offline_record ) + { + vj_perform_record_offline_tag_frame(info); + } + if( info->seq->active && info->seq->rec_id > 0 ) { int type = 0; if( info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG ) @@ -3648,9 +3742,9 @@ static void vj_perform_record_frame( veejay_t *info ) } else { - if(info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG ) + if(info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG && info->settings->tag_record ) vj_perform_record_tag_frame(info); - else if (info->uc->playback_mode == VJ_PLAYBACK_MODE_SAMPLE ) + else if (info->uc->playback_mode == VJ_PLAYBACK_MODE_SAMPLE && info->settings->sample_record ) vj_perform_record_sample_frame(info, info->uc->sample_id,0 ); } } @@ -3661,14 +3755,10 @@ static int vj_perform_render_magic( veejay_t *info, video_playback_setup *settin vj_perform_finish_chain( info, is444 ); vj_perform_render_font( info, settings); - //@ record frame -// if( pvar_.enc_active ) -// vj_perform_record_frame(info); if(!info->settings->composite) vj_perform_render_osd( info, settings, deep ); - //@ Do the subsampling vj_perform_finish_render( info, settings,deep ); return deep; @@ -3676,7 +3766,6 @@ static int vj_perform_render_magic( veejay_t *info, video_playback_setup *settin void vj_perform_record_video_frame(veejay_t *info) { - //@ record frame if( pvar_.enc_active ) vj_perform_record_frame(info); } @@ -3699,9 +3788,6 @@ int vj_perform_queue_video_frame(veejay_t *info, const int skip_incr) pvar_.fade_value = safe_fv; pvar_.fade_entry = -1; - if(settings->offline_record) - vj_perform_record_tag_frame(info); - int cur_out = info->out_buf; info->effect_frame_info->timecode = settings->current_frame_num; @@ -3727,7 +3813,7 @@ int vj_perform_queue_video_frame(veejay_t *info, const int skip_incr) &(pvar_.fade_entry), &(pvar_.fade_alpha)); - if( info->seq->active && info->seq->rec_id ) + if( (info->seq->active && info->seq->rec_id) || info->settings->offline_record ) pvar_.enc_active = 1; vj_perform_plain_fill_buffer(info, &res); @@ -3742,6 +3828,10 @@ int vj_perform_queue_video_frame(veejay_t *info, const int skip_incr) break; case VJ_PLAYBACK_MODE_PLAIN: + + if( info->settings->offline_record ) + pvar_.enc_active = 1; + vj_perform_plain_fill_buffer(info, &res); if( res > 0 ) { cur_out = vj_perform_render_magic( info, info->settings,0 ); @@ -3759,7 +3849,7 @@ int vj_perform_queue_video_frame(veejay_t *info, const int skip_incr) &(pvar_.fade_entry), &(pvar_.fade_alpha)); - if( info->seq->active && info->seq->rec_id ) + if( (info->seq->active && info->seq->rec_id) || info->settings->offline_record ) pvar_.enc_active = 1;