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;