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;