diff --git a/veejay-current/veejay-server/libel/avhelper.c b/veejay-current/veejay-server/libel/avhelper.c index f2acff64..b5649f6e 100644 --- a/veejay-current/veejay-server/libel/avhelper.c +++ b/veejay-current/veejay-server/libel/avhelper.c @@ -45,10 +45,10 @@ static struct { { "vj20", CODEC_ID_YUV420F }, { "vj22", CODEC_ID_YUV422F }, - { "mjpg" ,CODEC_ID_MJPEG }, + { "mjpg" ,CODEC_ID_MJPEG }, { "mjpb", CODEC_ID_MJPEGB }, - { "i420", CODEC_ID_YUV420 }, - { "i422", CODEC_ID_YUV422 }, + { "i420", CODEC_ID_YUV420 }, + { "i422", CODEC_ID_YUV422 }, { "dmb1", CODEC_ID_MJPEG }, { "jpeg", CODEC_ID_MJPEG }, { "mjpa", CODEC_ID_MJPEG }, @@ -81,10 +81,13 @@ static struct { "rpza", CODEC_ID_RPZA }, { "y42b", CODEC_ID_YUV422F }, { "pict", 0xffff }, + { NULL , 0, }, }; +#define MAX_PACKETS 5 + typedef struct { AVCodec *codec; @@ -97,12 +100,20 @@ typedef struct VJFrame *output; VJFrame *input; void *scaler; + int video_stream_id; + AVPacket packets[MAX_PACKETS]; + uint32_t write_index; + uint32_t read_index; + double spvf; } el_decoder_t; + //instead of iterating _supported_codecs and using a strncasecmp on every entry to find the codec_id, use a hash table that returns the codec identifier on hashed fourcc key //this collection is never freed and initialized on first access static hash_t *fourccTable = NULL; +static inline void *avhelper_get_decoder_intra( const char *filename, int dst_pixfmt, int dst_width, int dst_height, int force_intra_frame_only ); + typedef struct { int codec_id; } fourcc_node; @@ -260,6 +271,112 @@ void *avhelper_get_mjpeg_decoder(VJFrame *output) { } void *avhelper_get_decoder( const char *filename, int dst_pixfmt, int dst_width, int dst_height ) { + return avhelper_get_decoder_intra(filename, dst_pixfmt,dst_width,dst_height,1); +} + +void *avhelper_get_stream_decoder( const char *filename, int dst_pixfmt, int dst_width, int dst_height ) { + + el_decoder_t *x = (el_decoder_t*) avhelper_get_decoder_intra(filename, dst_pixfmt,dst_width,dst_height,0); + + veejay_memset( &(x->packets[0]), 0, sizeof(AVPacket)); + veejay_memset( &(x->packets[1]), 0, sizeof(AVPacket)); + + x->read_index = 0; + x->write_index = 0; + + return (void*) x; +} + + +#define MAX_QUEUE 1000 +#define OK 0 +// FIXME dirty now, refactor later +// need timing information, pts, packet queue + +double avhelper_get_spvf( void *decoder ) { + el_decoder_t *x = (el_decoder_t*) decoder; + return x->spvf; +} + +int avhelper_recv_frame_packet( void *decoder ) +{ + el_decoder_t *x = (el_decoder_t*) decoder; + + int ret = av_read_frame(x->avformat_ctx, &(x->packets[x->write_index]) ); + + if( ret == OK ) { + if( x->packets[ x->write_index ].stream_index != x->video_stream_id ) { + av_free_packet( &(x->packets[x->write_index]) ); + veejay_memset( &(x->packets[x->write_index]), 0, sizeof(AVPacket) ); + return 2; // discarded + } + + x->write_index = (x->write_index + 1) % MAX_PACKETS; + return 1; // accepted + } + + return -1; // error +} + +int avhelper_recv_decode( void *decoder, int *got_picture ) +{ + el_decoder_t *x = (el_decoder_t*) decoder; + int result = 0; + int gp = 0; + + + while(1) { + + // only decode video + if( x->packets[ x->read_index ].stream_index != x->video_stream_id ) + break; + + result = avcodec_decode_video( x->codec_ctx, x->frame, &gp, x->packets[ x->read_index ].data, x->packets[ x->read_index ].size ); + avhelper_frame_unref(x->frame); + + av_free_packet( &(x->packets[x->write_index]) ); + veejay_memset( &(x->packets[x->write_index]), 0, sizeof(AVPacket) ); + + x->read_index = (x->read_index + 1) % MAX_PACKETS; + + if( gp ) + break; + } + *got_picture = gp; + return result; +} + + +int avhelper_get_frame( void *decoder, int *got_picture ) +{ + el_decoder_t *x = (el_decoder_t*) decoder; + + veejay_memset( &(x->pkt), 0, sizeof(AVPacket)); + + int gp = 0; + int result = 0; + while(1) { + int ret = av_read_frame(x->avformat_ctx, &(x->pkt)); + if( ret < 0 ) + break; + + if ( x->pkt.stream_index == x->video_stream_id ) { + result = avcodec_decode_video( x->codec_ctx,x->frame,&gp, x->pkt.data, x->pkt.size ); + avhelper_frame_unref(x->frame); + } + + av_free_packet( &(x->pkt) ); + + if( gp ) + break; + } + + *got_picture = gp; + + return result; +} + +static inline void *avhelper_get_decoder_intra( const char *filename, int dst_pixfmt, int dst_width, int dst_height, int force_intra_frame_only ) { char errbuf[512]; el_decoder_t *x = (el_decoder_t*) vj_calloc( sizeof( el_decoder_t )); if(!x) { @@ -298,31 +415,35 @@ void *avhelper_get_decoder( const char *filename, int dst_pixfmt, int dst_width, unsigned int i,j; unsigned int n = x->avformat_ctx->nb_streams; - int vi = -1; + + x->video_stream_id = -1; for( i = 0; i < n; i ++ ) { if( !x->avformat_ctx->streams[i]->codec ) continue; - if( x->avformat_ctx->streams[i]->codec->codec_type > CODEC_ID_FIRST_SUBTITLE ) + if( x->avformat_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO ) continue; - - if( x->avformat_ctx->streams[i]->codec->codec_type < CODEC_ID_FIRST_AUDIO ) + + if( x->avformat_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ) { - int sup_codec = 0; - for( j = 0; _supported_codecs[j].name != NULL; j ++ ) { - if( x->avformat_ctx->streams[i]->codec->codec_id == _supported_codecs[j].id ) { - sup_codec = 1; - goto further; - } - } + int sup_codec = !force_intra_frame_only; + if( force_intra_frame_only ) { + for( j = 0; _supported_codecs[j].name != NULL; j ++ ) { + if( x->avformat_ctx->streams[i]->codec->codec_id == _supported_codecs[j].id ) { + sup_codec = 1; + goto further; + } + } + } further: if( !sup_codec ) { avhelper_close_input_file( x->avformat_ctx ); free(x); return NULL; } + x->codec = avcodec_find_decoder( x->avformat_ctx->streams[i]->codec->codec_id ); if(x->codec == NULL ) { @@ -330,22 +451,22 @@ further: free(x); return NULL; } - vi = i; + x->video_stream_id = i; - veejay_msg(VEEJAY_MSG_DEBUG, "FFmpeg: video stream %d, codec_id %d", vi, x->avformat_ctx->streams[i]->codec->codec_id); + veejay_msg(VEEJAY_MSG_DEBUG, "FFmpeg: video stream %d, codec_id %d", x->video_stream_id, x->avformat_ctx->streams[i]->codec->codec_id); break; } } - if( vi == -1 ) { + if( x->video_stream_id == -1 ) { veejay_msg(VEEJAY_MSG_DEBUG, "FFmpeg: No video streams found"); avhelper_close_input_file( x->avformat_ctx ); free(x); return NULL; } - x->codec_ctx = x->avformat_ctx->streams[vi]->codec; + x->codec_ctx = x->avformat_ctx->streams[x->video_stream_id]->codec; int wid = dst_width; int hei = dst_height; @@ -369,6 +490,7 @@ further: veejay_memset( &(x->pkt), 0, sizeof(AVPacket)); AVFrame *f = avhelper_alloc_frame(); x->output = yuv_yuv_template( NULL,NULL,NULL, wid, hei, dst_pixfmt ); + x->spvf = ( (double) x->codec_ctx->framerate.den ) / ( (double) x->codec_ctx->framerate.num); int got_picture = 0; while(1) { @@ -376,7 +498,7 @@ further: if( ret < 0 ) break; - if ( x->pkt.stream_index == vi ) { + if ( x->pkt.stream_index == x->video_stream_id ) { avcodec_decode_video( x->codec_ctx,f,&got_picture, x->pkt.data, x->pkt.size ); avhelper_frame_unref( f ); } @@ -477,6 +599,11 @@ VJFrame *avhelper_get_decoded_video(void *ptr) { e->input->data[2] = e->frame->data[2]; e->input->data[3] = e->frame->data[3]; + e->input->stride[0] = e->frame->linesize[0]; + e->input->stride[1] = e->frame->linesize[1]; + e->input->stride[2] = e->frame->linesize[2]; + e->input->stride[3] = e->frame->linesize[3]; + return e->input; } diff --git a/veejay-current/veejay-server/libel/avhelper.h b/veejay-current/veejay-server/libel/avhelper.h index f46121e1..492a151a 100644 --- a/veejay-current/veejay-server/libel/avhelper.h +++ b/veejay-current/veejay-server/libel/avhelper.h @@ -26,6 +26,8 @@ #define CODEC_ID_YUV420F 996 #define CODEC_ID_YUVLZO 900 +// This is not a library, it is a collection of helper functions for various purposes + void *avhelper_alloc_frame(); int avhelper_get_codec_by_id(int id); @@ -44,6 +46,8 @@ void avhelper_rescale_video(void *ptr, uint8_t *dst[4]); void *avhelper_get_decoder( const char *filename, int dst_pixfmt, int dst_width, int dst_height ); +void *avhelper_get_stream_decoder( const char *filename, int dst_pixfmt, int dst_width, int dst_height ); + VJFrame *avhelper_get_decoded_video(void *ptr); void avhelper_free_context(AVCodecContext **avctx); @@ -52,8 +56,16 @@ void avhelper_frame_unref(AVFrame *ptr); void *avhelper_get_mjpeg_decoder(VJFrame *output_info); +int avhelper_get_frame( void *decoder, int *got_picture ); + VJFrame *avhelper_get_input_frame( void *ptr ); VJFrame *avhelper_get_output_frame( void *ptr); +int avhelper_recv_decode( void *decoder, int *got_picture ); + +int avhelper_recv_frame_packet( void *decoder ); + +double avhelper_get_spvf( void *decoder ); + #endif diff --git a/veejay-current/veejay-server/libel/rawdv.c b/veejay-current/veejay-server/libel/rawdv.c index c462467e..2003ab01 100644 --- a/veejay-current/veejay-server/libel/rawdv.c +++ b/veejay-current/veejay-server/libel/rawdv.c @@ -35,6 +35,8 @@ #define DV_PAL_SIZE 144000 #define DV_NTSC_SIZE 120000 +#define DVSD "dvsd" + static void rawdv_free(dv_t *dv) { if(dv->filename) free(dv->filename); @@ -288,8 +290,7 @@ int rawdv_compressor(dv_t *dv) char *rawdv_video_compressor(dv_t *dv) { - char res[5] = "dvsd\0"; - return res; + return DVSD; } int rawdv_audio_channels(dv_t *dv) diff --git a/veejay-current/veejay-server/libsample/sampleadm.c b/veejay-current/veejay-server/libsample/sampleadm.c index 28000758..b64de3aa 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.c +++ b/veejay-current/veejay-server/libsample/sampleadm.c @@ -352,7 +352,6 @@ sample_info *sample_skeleton_new(long startFrame, long endFrame) si->audio_volume = 50; si->marker_start = 0; si->marker_end = 0; - si->loopcount = 0; si->effect_toggle = 1; si->fade_method = 0; si->fade_alpha = 0; @@ -1160,6 +1159,29 @@ int sample_get_first_mix_offset(int s1, int *parent, int look_for) return 0; } +void sample_update_ascociated_samples(int s1) +{ + sample_info *sample = sample_get(s1); + if(!sample) { + return; + } + + int p = 0; + for( p = 0; p < SAMPLE_MAX_EFFECTS; p ++ ) { + if( sample->effect_chain[p]->source_type != 0 ) + continue; + if( !sample_exists(sample->effect_chain[p]->channel) ) + continue; + + int pos = sample->effect_chain[p]->frame_offset; + if(pos == 0 ) + continue; + + sample_set_resume( sample->effect_chain[p]->channel, pos ); + veejay_msg(VEEJAY_MSG_DEBUG, "Sample %d will resume playback from position %d", + sample->effect_chain[p]->channel, pos ); + } +} int sample_set_resume(int s1,long position) { @@ -1302,6 +1324,28 @@ int sample_set_chain_status(int s1, int position, int status) return 1; } +int sample_get_frame_length(int s1) +{ + sample_info *sample = sample_get(s1); + if (!sample) + return 0; + + int len = 1 + abs( sample->last_frame - sample->first_frame ); + int speed = abs( sample->speed ); + + len = len / speed; + + if( sample->dup > 0) { + len = len * sample->dup; + } + + if(sample->looptype == 2) { + len *= 2; + } + + return len; +} + /**************************************************************************************************** * * sample_get_speed @@ -1667,6 +1711,36 @@ int sample_set_chain_source(int s1, int position, int input) return 1; } +int sample_get_loops(int s1) { + sample_info *sample = sample_get(s1); + if (!sample) return 0; + return sample->loops; +} + +void sample_set_loops(int s1, int loops) { + sample_info *sample = sample_get(s1); + if(!sample) return; + if(loops==-1) { + if(sample->looptype == 2) { + sample->loops = 2; + } + else { + sample->loops = 1; + } + return; + } + sample->loops = loops; +} + +int sample_loop_dec(int s1) +{ + sample_info *sample = sample_get(s1); + if(!sample) return 0; + if(sample->loops > 0) + sample->loops --; + return sample->loops; +} + /**************************************************************************************************** * * sample_set_speed @@ -1675,28 +1749,6 @@ int sample_set_chain_source(int s1, int position, int input) * returns -1 on error. * ****************************************************************************************************/ -void sample_loopcount(int s1) -{ - sample_info *sample = sample_get(s1); - if (!sample) return; - sample->loopcount ++; - if(sample->loopcount > 1000000 ) - sample->loopcount = 0; -} -int sample_get_loopcount(int s1) -{ - sample_info *sample = sample_get(s1); - if (!sample) return 0; - - return sample->loopcount; -} -void sample_reset_loopcount(int s1) -{ - sample_info *sample = sample_get(s1); - if (!sample) return; - sample->loopcount = 0; -} - int sample_set_speed(int s1, int speed) { sample_info *sample = sample_get(s1); @@ -1747,23 +1799,6 @@ int sample_get_chain_source(int s1, int position) return sample->effect_chain[position]->source_type; } -int sample_get_loops(int s1) -{ - sample_info *sample = sample_get(s1); - if (sample) { - return sample->max_loops; - } - return -1; -} -int sample_get_loops2(int s1) -{ - sample_info *sample; - sample = sample_get(s1); - if (!sample) - return -1; - return sample->max_loops2; -} - /**************************************************************************************************** * * sample_set_looptype @@ -1780,6 +1815,14 @@ int sample_set_looptype(int s1, int looptype) if( looptype >= 0 && looptype < 5 ) { sample->looptype = looptype; + + if(looptype == 2) { + sample->loops = 2; + } + else { + sample->loops = 1; + } + return 1; } return 0; @@ -1910,22 +1953,6 @@ int sample_get_next(int s1) return -1; return sample->next_sample_id; } -int sample_set_loops(int s1, int nr_of_loops) -{ - sample_info *sample = sample_get(s1); - if (!sample) - return -1; - sample->max_loops = nr_of_loops; - return 1; -} -int sample_set_loops2(int s1, int nr_of_loops) -{ - sample_info *sample = sample_get(s1); - if (!sample) - return -1; - sample->max_loops2 = nr_of_loops; - return 1; -} int sample_get_subrender(int s1) { @@ -2315,8 +2342,6 @@ int sample_set_offset(int s1, int chain_entry, int frame_offset) sample_info *sample = sample_get(s1); if (!sample) return -1; - /* set to zero if frame_offset is greater than sample length */ - //if(frame_offset > (sample->last_frame - sample->first_frame)) frame_offset=0; sample->effect_chain[chain_entry]->frame_offset = frame_offset; return 1; } @@ -2550,19 +2575,6 @@ int sample_chain_remove(int s1, int position) return 1; } -int sample_set_loop_dec(int s1, int active) { - sample_info *sample = sample_get(s1); - if(!sample) return -1; - sample->loop_dec = active; - return 1; -} - -int sample_get_loop_dec(int s1) { - sample_info *sample = sample_get(s1); - if(!sample) return -1; - return sample->loop_dec; -} - editlist *sample_get_editlist(int s1) { sample_info *sample = sample_get(s1); @@ -2604,27 +2616,6 @@ int sample_set_editlist(int s1, editlist *edl) return 1; } -int sample_apply_loop_dec(int s1, double fps) { - sample_info *sample = sample_get(s1); - if(!sample) return -1; -/* if(sample->loop_dec==1) { - if( (sample->first_frame + inc) >= sample->last_frame) { - sample->first_frame = sample->last_frame-1; - sample->loop_dec = 0; - } - else { - sample->first_frame += (inc / sample->loop_periods); - } - veejay_msg(VEEJAY_MSG_DEBUG, "New starting postions are %ld - %ld", - sample->first_frame, sample->last_frame); - return ( sample_update(sample, s1)); - }*/ - - sample->loop_dec ++; - - return 1; -} - /* print sample status information into an allocated string str*/ //int sample_chain_sprint_status(int s1, int entry, int changed, int r_changed,char *str, diff --git a/veejay-current/veejay-server/libsample/sampleadm.h b/veejay-current/veejay-server/libsample/sampleadm.h index 6a437e7f..6638cfc8 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.h +++ b/veejay-current/veejay-server/libsample/sampleadm.h @@ -169,14 +169,14 @@ typedef struct sample_info_t { int effect_toggle; int offset; int play_length; - int loopcount; editlist *edit_list; char *edit_list_file; int soft_edl; void *dict; void *kf; long resume_pos; - int subrender; + int subrender; + int loops; } sample_info; #define SAMPLE_YUV420_BUFSIZE 16 @@ -219,15 +219,10 @@ extern int sample_get_playmode(int s1); extern int sample_set_playmode(int s1, int playmode); extern int sample_get_subrender(int s1); extern void sample_set_subrender(int s1, int status); -extern int sample_get_loops(int s1); -extern int sample_get_loops2(int s1); extern int sample_get_next(int s1); extern int sample_get_depth(int s1); extern int sample_set_depth(int s1, int n); extern int sample_set_speed(int s1, int speed); -extern void sample_loopcount(int s1); -extern void sample_reset_loopcount(int s1); -extern int sample_get_loopcount(int s1); extern int sample_set_framedup(int s1, int n); extern int sample_get_framedup(int s1); extern int sample_set_framedups(int s1, int n); @@ -236,8 +231,6 @@ extern int sample_marker_clear(int sample_id); extern int sample_set_looptype(int s1, int looptype); extern int sample_get_speed(int s1); extern int sample_get_looptype(int s1); -extern int sample_set_loops(int s1, int nr_of_loops); -extern int sample_set_loops2(int s1, int nr); extern int sample_set_next(int s1, int next_sample_id); extern int sample_get_chain_source(int sample_id, int position); extern int sample_set_chain_source(int sample_id, int position, int source); @@ -356,11 +349,14 @@ extern int sample_start_playing(int s1, int no_cache); extern int sample_get_kf_tokens( int s1, int entry, int id, int *start,int *end, int *type); extern char *UTF8toLAT1(unsigned char *in); extern int sample_read_edl( sample_info *sample ); - +extern void sample_set_loops(int s1, int loops); +extern int sample_get_loops(int s1); +extern int sample_get_frame_length(int s1); +extern int sample_loop_dec(int s1); extern int sample_max_video_length(int s1); - extern long sample_get_resume(int s1); extern int sample_set_resume(int s1, long pos ); +extern void sample_update_ascociated_samples(int s1); extern void sample_chain_alloc_kf( int s1, int entry ); extern void sample_set_chain_paused( int s1, int paused ); diff --git a/veejay-current/veejay-server/libstream/Makefile.am b/veejay-current/veejay-server/libstream/Makefile.am index 9b7b2ccc..507fe58f 100644 --- a/veejay-current/veejay-server/libstream/Makefile.am +++ b/veejay-current/veejay-server/libstream/Makefile.am @@ -18,6 +18,6 @@ AM_CPPFLAGS += $(XML2_CFLAGS) $(FFMPEG_CFLAGS) $(PTHREAD_CFLAGS) $(MJPEGTOOLS_CF STREAM_LIB_FILE = libstream.la noinst_LTLIBRARIES = $(STREAM_LIB_FILE) -libstream_la_SOURCES = vj-yuv4mpeg.c vj-net.c vj-dv1394.c vj-vloopback.c vj-tag.c v4l2utils.c +libstream_la_SOURCES = vj-yuv4mpeg.c vj-net.c vj-avformat.c vj-dv1394.c vj-vloopback.c vj-tag.c v4l2utils.c pkginclude_HEADERS = vj-net.h EXTRA_DIST = dv1394.h v4lutils.h v4l2utils.h vj-dv1394.h vj-tag.h vj-vloopback.h v4lvideo.h vj-net.h vj-yuv4mpeg.h diff --git a/veejay-current/veejay-server/libstream/v4l2utils.c b/veejay-current/veejay-server/libstream/v4l2utils.c index 0cf6c520..cd5b72aa 100644 --- a/veejay-current/veejay-server/libstream/v4l2utils.c +++ b/veejay-current/veejay-server/libstream/v4l2utils.c @@ -1176,7 +1176,7 @@ v4l2_rw_fallback: } - //FIXME this is here since libstream and libsample should be refactored (for now) + //TODO this is here since libstream and libsample should be refactored (for now) if( v->format.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32 || v->format.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32 ) { // this allows us to convert to yuva regardless diff --git a/veejay-current/veejay-server/libstream/vj-tag.c b/veejay-current/veejay-server/libstream/vj-tag.c index 763ddb70..aab04fd9 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.c +++ b/veejay-current/veejay-server/libstream/vj-tag.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #ifdef HAVE_V4L2 #include @@ -377,28 +378,9 @@ int _vj_tag_new_net(vj_tag *tag, int stream_nr, int w, int h,int f, char *host, return 0; } -/* vj_tag_input->net[stream_nr] = vj_client_alloc(w,h,f); - v = vj_tag_input->net[stream_nr]; - if(!v) - { - veejay_msg(0, "Memory allocation error while creating network stream"); - return 0; - }*/ snprintf(tmp,sizeof(tmp), "%s %d", host, port ); tag->extra = (void*) strdup(tmp); - if( tag->socket_ready == 0 ) - { - tag->socket_frame = (uint8_t*) vj_calloc(sizeof(uint8_t) * RUP8( w * h * 3)); - tag->socket_len = w * h * 3; - if(!tag->socket_frame) - { - veejay_msg(VEEJAY_MSG_ERROR, "Insufficient error to allocate memory for Network Stream"); - return 0; - } - tag->socket_ready = 1; - } - return 1; } @@ -702,6 +684,7 @@ int _vj_tag_new_yuv4mpeg(vj_tag * tag, int stream_nr, int w, int h, float fps) } return 1; } + #ifdef SUPPORT_READ_DV2 int _vj_tag_new_dv1394(vj_tag *tag, int stream_nr, int channel,int quality, editlist *el) { @@ -921,18 +904,19 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, int pix_f tag->selected_entry = 0; tag->depth = 0; tag->effect_toggle = 1; /* same as for samples */ - tag->socket_ready = 0; - tag->socket_frame = NULL; - tag->socket_len = 0; tag->color_r = 0; tag->color_g = 0; tag->color_b = 0; tag->opacity = 0; tag->priv = NULL; tag->subrender = 1; - if(type == VJ_TAG_TYPE_MCAST || type == VJ_TAG_TYPE_NET) + + if(type == VJ_TAG_TYPE_MCAST || type == VJ_TAG_TYPE_NET) tag->priv = net_threader(_tag_info->effect_frame1); + if(type == VJ_TAG_TYPE_AVFORMAT ) + tag->priv = avformat_thread_allocate(_tag_info->effect_frame1); + palette = get_ffmpeg_pixfmt( pix_fmt ); switch (type) { @@ -965,6 +949,9 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, int pix_f return -1; } break; + case VJ_TAG_TYPE_AVFORMAT: + snprintf(tag->source_name,SOURCE_NAME_LEN, "%s", filename ); + break; case VJ_TAG_TYPE_DV1394: #ifdef SUPPORT_READ_DV2 snprintf(tag->source_name, SOURCE_NAME_LEN,"dv1394 %d", channel); @@ -1306,7 +1293,11 @@ int vj_tag_del(int id) tag->source_name,id); vj_yuv_stream_stop_read(vj_tag_input->stream[tag->index]); // vj_yuv4mpeg_free( vj_tag_input->stream[tag->index]); - break; + break; + case VJ_TAG_TYPE_AVFORMAT: + avformat_thread_stop(tag); + if(tag->priv) free(tag->priv); + break; #ifdef SUPPORT_READ_DV2 case VJ_TAG_TYPE_DV1394: vj_dv1394_close( vj_tag_input->dv1394[tag->index] ); @@ -1371,12 +1362,6 @@ int vj_tag_del(int id) tag->effect_chain[i] = NULL; } - if(tag->socket_frame) - { - free(tag->socket_frame); - tag->socket_frame = NULL; - } - #ifdef ARCH_X86_64 uint64_t tid = (uint64_t) tag->id; #else @@ -2041,7 +2026,7 @@ int vj_tag_chain_free(int t1, int global) if( tag->effect_chain[i]->source_type == 1 && vj_tag_get_active( tag->effect_chain[i]->channel ) && - vj_tag_get_type( tag->effect_chain[i]->channel ) == VJ_TAG_TYPE_NET ) { + vj_tag_get_type( tag->effect_chain[i]->channel ) == VJ_TAG_TYPE_NET ) { //FIXME: check if this behaviour is correct vj_tag_disable( tag->effect_chain[i]->channel ); } } @@ -2194,7 +2179,7 @@ int vj_tag_set_effect(int t1, int position, int effect_id) if( tag->effect_chain[position]->source_type == 1 && vj_tag_get_active( tag->effect_chain[position]->channel ) && tag->effect_chain[position]->channel != t1 && - vj_tag_get_type( tag->effect_chain[position]->channel ) == VJ_TAG_TYPE_NET ) { + vj_tag_get_type( tag->effect_chain[position]->channel ) == VJ_TAG_TYPE_NET ) { //FIXME: test if this behaviour is correct vj_tag_disable( tag->effect_chain[position]->channel ); } } @@ -2457,6 +2442,11 @@ int vj_tag_disable(int t1) { { net_thread_stop( tag ); } + + if(tag->source_type == VJ_TAG_TYPE_AVFORMAT ) { + avformat_thread_stop( tag ); + } + if(tag->source_type == VJ_TAG_TYPE_V4L && !tag->clone ) { #ifdef HAVE_V4L2 @@ -2509,6 +2499,16 @@ int vj_tag_enable(int t1) { return 1; } } + + if(tag->source_type == VJ_TAG_TYPE_AVFORMAT ) + { + if(!avformat_thread_start(tag, _tag_info->effect_frame1)) { + veejay_msg(VEEJAY_MSG_ERROR, "Unable to start thread"); + return 1; + } + + } + #ifdef USE_GDK_PIXBUF if( tag->source_type == VJ_TAG_TYPE_PICTURE ) { @@ -2571,6 +2571,7 @@ int vj_tag_set_active(int t1, int active) vj_yuv_stream_stop_read( vj_tag_input->stream[tag->index]); } break; + case VJ_TAG_TYPE_AVFORMAT: case VJ_TAG_TYPE_MCAST: case VJ_TAG_TYPE_NET: case VJ_TAG_TYPE_PICTURE: @@ -2756,7 +2757,7 @@ int vj_tag_chain_remove(int t1, int index) if( tag->effect_chain[index]->source_type == 1 && vj_tag_get_active( tag->effect_chain[index]->channel ) && tag->effect_chain[index]->channel != t1 && - vj_tag_get_type( tag->effect_chain[index]->channel ) == VJ_TAG_TYPE_NET ) { + vj_tag_get_type( tag->effect_chain[index]->channel ) == VJ_TAG_TYPE_NET ) { //FIXME test if this behaviour is correct vj_tag_disable( tag->effect_chain[index]->channel ); } @@ -2838,6 +2839,9 @@ void vj_tag_get_by_type(int id,int type, char *description ) case VJ_TAG_TYPE_NET: sprintf(description, "%s", "Unicast"); break; + case VJ_TAG_TYPE_AVFORMAT: + sprintf(description, "%s", "AVFormat stream reader"); + break; #ifdef USE_GDK_PIXBUF case VJ_TAG_TYPE_PICTURE: sprintf(description, "%s", "GdkPixbuf"); @@ -3658,6 +3662,12 @@ int vj_tag_get_frame(int t1, VJFrame *dst, uint8_t * abuffer) plug_process( tag->generator, -1.0 ); } break; + case VJ_TAG_TYPE_AVFORMAT: + if(!avformat_thread_get_frame( tag,dst )) //TODO: net and avformat seem to be the same, just like all other types. use a modular structure + return 0; + return 1; + + break; case VJ_TAG_TYPE_COLOR: dummy_rgb_apply( dst, tag->color_r,tag->color_g,tag->color_b ); break; diff --git a/veejay-current/veejay-server/libstream/vj-tag.h b/veejay-current/veejay-server/libstream/vj-tag.h index 73fe7b81..799ea981 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.h +++ b/veejay-current/veejay-server/libstream/vj-tag.h @@ -49,6 +49,7 @@ typedef struct } vj_picture; #endif +// very old junk, should be re-written typedef struct { void *unicap[VJ_TAG_MAX_STREAM_IN]; vj_yuv *stream[VJ_TAG_MAX_STREAM_IN]; @@ -57,7 +58,8 @@ typedef struct { #ifdef USE_GDK_PIXBUF vj_picture *picture[VJ_TAG_MAX_STREAM_IN]; #endif - void *cali[VJ_TAG_MAX_STREAM_IN]; + void *cali[VJ_TAG_MAX_STREAM_IN]; + void *avformat[VJ_TAG_MAX_STREAM_IN]; int width; int height; int depth; @@ -108,9 +110,6 @@ typedef struct { int fade_alpha; int selected_entry; int effect_toggle; - int socket_ready; - int socket_len; - uint8_t *socket_frame; int n_frames; void *priv; void *extra; diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c index 5c0b3965..04b0a4c4 100644 --- a/veejay-current/veejay-server/veejay/liblavplayvj.c +++ b/veejay-current/veejay-server/veejay/liblavplayvj.c @@ -316,7 +316,8 @@ int veejay_hold_frame(veejay_t * info, int rel_resume_pos, int hold_pos) settings->hold_resume ++; if(settings->hold_resume < hold_pos ) settings->hold_resume = hold_pos; - } else + } + else { //@first press aprox settings->hold_pos = hold_pos + rel_resume_pos; @@ -597,60 +598,37 @@ int veejay_start_playing_sample( veejay_t *info, int sample_id ) settings->max_frame_num = sample_video_length( sample_id ); settings->first_frame = 1; - sample_reset_loopcount( sample_id ); - #ifdef HAVE_FREETYPE if(info->font && info->uc->sample_id != sample_id) { void *dict = sample_get_dict( sample_id ); vj_font_set_dict( info->font, dict ); - vj_font_prepare( info->font,start,end ); - - veejay_msg(VEEJAY_MSG_DEBUG, "Subtitling sample %d: %ld - %ld", sample_id, + if( vj_font_prepare( info->font,start,end ) > 0 ) { + veejay_msg(VEEJAY_MSG_DEBUG, "Subtitling sample %d: %ld - %ld", sample_id, start, end ); - + } } #endif -/* if(info->composite ) - { - void *cur = sample_get_composite_view(sample_id); - if( cur == NULL ) { - composite_set_file_mode( info->composite, info->homedir, info->uc->playback_mode,sample_id); - if( sample_load_composite_config( info->composite, sample_id ) ) { - veejay_msg(VEEJAY_MSG_WARNING, "Sample %d has composite view %p", sample_id, sample_get_composite_view(sample_id) ); - } - } - else { - composite_set_backing( info->composite, cur ); - } - switch(composite_has_back(info->composite)) { - case 2: - settings->composite = composite_restore_config(info->composite); - break; - default: - settings->composite = 0; - break; - } - } -*/ info->uc->sample_id = sample_id; info->last_sample_id = sample_id; info->sfd = sample_get_framedup(sample_id); - if( info->settings->sample_restart ) - sample_reset_offset( sample_id ); /* reset mixing offsets */ - - veejay_sample_resume_at( info, sample_id ); + if(!info->seq->active) { + if( info->settings->sample_restart ) + sample_reset_offset( sample_id ); /* reset mixing offsets */ + } + veejay_sample_resume_at( info, sample_id ); + if( speed != 0 ) settings->previous_playback_speed = speed; - veejay_set_speed(info, speed); + veejay_set_speed(info, speed); - veejay_msg(VEEJAY_MSG_INFO, "Playing sample %d (FX=%x, Sl=%d, Speed=%d, Start=%d, Loop=%d)", - sample_id, tmp,info->sfd, speed, start, looptype ); + veejay_msg(VEEJAY_MSG_INFO, "Playing sample %d (FX=%x, Sl=%d, Speed=%d, Start=%d, End=%d, Loop=%d)", + sample_id, tmp,info->sfd, speed, start, end, looptype ); return 1; } @@ -719,20 +697,19 @@ void veejay_change_playback_mode( veejay_t *info, int new_pm, int sample_id ) int cur_id = info->uc->sample_id; if( cur_id == sample_id && new_pm == VJ_PLAYBACK_MODE_SAMPLE ) { - if( info->settings->sample_restart ) - { - sample_set_resume(cur_id,-1); - - long pos = sample_get_resume( cur_id ); - - veejay_set_frame(info, pos ); - - veejay_msg(VEEJAY_MSG_INFO, "Sample %d starts playing from frame %d",sample_id,pos); - } - else { - veejay_msg(VEEJAY_MSG_INFO, "Already playing sample (continous mode is on)"); + if( !info->seq->active ) { + if( info->settings->sample_restart) + { + sample_set_resume(cur_id,-1); + long pos = sample_get_resume( cur_id ); + veejay_set_frame(info, pos ); + veejay_msg(VEEJAY_MSG_INFO, "Sample %d starts playing from frame %d",sample_id,pos); + } + else { + veejay_msg(VEEJAY_MSG_INFO, "Already playing sample (continous mode is on)"); + } + return; } - return; } else { @@ -742,12 +719,7 @@ void veejay_change_playback_mode( veejay_t *info, int new_pm, int sample_id ) if( info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG ) { int cur_id = info->uc->sample_id; - if( cur_id == sample_id && new_pm == VJ_PLAYBACK_MODE_TAG ) - { - return; - } - else - { + if( cur_id != sample_id) { veejay_stop_playing_stream(info, cur_id ); } info->settings->min_frame_num = 0; @@ -766,11 +738,6 @@ void veejay_change_playback_mode( veejay_t *info, int new_pm, int sample_id ) settings->min_frame_num = 0; settings->max_frame_num = info->edit_list->total_frames; - /* if(info->composite) { - composite_set_file_mode( info->composite, info->homedir, new_pm, 0); - composite_restore_config( info->composite ); - } - */ veejay_msg(VEEJAY_MSG_INFO, "Playing plain video, frames %ld - %ld", (long)settings->min_frame_num, (long)settings->max_frame_num ); } if(new_pm == VJ_PLAYBACK_MODE_TAG) @@ -785,22 +752,81 @@ void veejay_change_playback_mode( veejay_t *info, int new_pm, int sample_id ) } } -void veejay_set_sample_f(veejay_t *info, int sample_id, int offset ) +void veejay_sample_set_initial_positions(veejay_t *info) { - if( info->uc->playback_mode == VJ_PLAYBACK_MODE_SAMPLE && info->uc->sample_id == sample_id ) - { - int start = sample_get_startFrame( info->uc->sample_id ); - veejay_set_frame(info,start+offset); - veejay_msg(VEEJAY_MSG_INFO, "Sample %d starts playing from frame %d",sample_id,start); - return; + int first_sample = -1; + int i; + for( i = 0; i < MAX_SEQUENCES; i ++ ) { + if( info->seq->samples[i].sample_id > 0 && first_sample == -1) { + first_sample = i; + } + + if( info->seq->samples[i].type != 0 ) + continue; + int id = info->seq->samples[i].sample_id; + int stats[4]; + + sample_reset_offset(id); + sample_set_loops(id,-1); + sample_get_short_info( id, &stats[0],&stats[1],&stats[2],&stats[3]); + if( stats[2] == 2 ) { + if( stats[3] < 0 ) { + sample_set_speed(id, -1 * stats[3]); + } + sample_set_resume(id, stats[0]); + } + else { + if( stats[3] < 0 ) { + sample_set_resume(id, stats[1]); + } + else if(stats[3] > 0) { + sample_set_resume(id, stats[0]); + } + } } - veejay_change_playback_mode( info, VJ_PLAYBACK_MODE_SAMPLE, sample_id ); + if(first_sample >= 0) { + veejay_change_playback_mode(info, (info->seq->samples[first_sample].type == 0 ? + VJ_PLAYBACK_MODE_SAMPLE : VJ_PLAYBACK_MODE_TAG), info->seq->samples[first_sample].sample_id); + } } -void veejay_set_stream_f(veejay_t *info, int stream_id ) +void veejay_prepare_sample_positions(int id) { + int stats[4]; + + sample_reset_offset(id); + sample_set_loops(id,-1); + sample_get_short_info( id, &stats[0],&stats[1],&stats[2],&stats[3]); + if( stats[2] == 2 ) { + if( stats[3] < 0 ) { + sample_set_speed(id, -1 * stats[3]); + sample_set_resume(id, stats[0]); + } + } + else { + if( stats[3] < 0 ) { + sample_set_resume(id, stats[1]); + } + else if(stats[3] > 0) { + sample_set_resume(id, stats[0]); + } + } +} + +void veejay_reset_sample_positions(veejay_t *info, int sample_id) { - veejay_change_playback_mode( info, VJ_PLAYBACK_MODE_TAG, stream_id ); + if( sample_id == -1 ) { + int i; + for( i = 0; i < MAX_SEQUENCES; i ++ ) { + if( info->seq->samples[i].type != 0 ) + continue; + int id = info->seq->samples[i].sample_id; + veejay_prepare_sample_positions(id); + } + } + else { + veejay_prepare_sample_positions(sample_id); + } } void veejay_set_sample(veejay_t * info, int sampleid) @@ -808,10 +834,10 @@ void veejay_set_sample(veejay_t * info, int sampleid) if ( info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG) { veejay_start_playing_stream(info,sampleid ); - } + } else if( info->uc->playback_mode == VJ_PLAYBACK_MODE_SAMPLE) { - if( info->uc->sample_id == sampleid ) + if( info->uc->sample_id == sampleid) { veejay_sample_resume_at( info, sampleid ); } diff --git a/veejay-current/veejay-server/veejay/libveejay.h b/veejay-current/veejay-server/veejay/libveejay.h index 712b092a..15c92157 100644 --- a/veejay-current/veejay-server/veejay/libveejay.h +++ b/veejay-current/veejay-server/veejay/libveejay.h @@ -53,9 +53,14 @@ int get_total_mem(void); char *veejay_title(veejay_t *info); +void veejay_sample_set_initial_positions(veejay_t *info); + +void veejay_prepare_sample_positions(int id); + +void veejay_reset_sample_positions(veejay_t *info, int sample_id); + void veejay_stop_sampling(veejay_t *info); -void veejay_set_sample_f(veejay_t *info, int sample, int offset ); -void veejay_set_stream_f(veejay_t *info, int stream ); + void veejay_set_sample(veejay_t *info, int sample); int veejay_set_frame(veejay_t *info, long frame_num); diff --git a/veejay-current/veejay-server/veejay/vims.h b/veejay-current/veejay-server/veejay/vims.h index aefe7e44..9f8ba930 100644 --- a/veejay-current/veejay-server/veejay/vims.h +++ b/veejay-current/veejay-server/veejay/vims.h @@ -39,7 +39,7 @@ enum { VIMS_FEEDBACK = 49, VIMS_MACRO = 33, VIMS_MACRO_SELECT = 34, - VIMS_CONTINUOUS_PLAY = 35, + VIMS_CONTINUOUS_PLAY = 35, //FIXME delete this event VIMS_RECVIEWPORT = 90, VIMS_VIDEO_INFORMATION = 400, VIMS_PROMOTION = 444, /* obsolete */ @@ -189,6 +189,7 @@ enum { VIMS_STREAM_ACTIVATE = 205, VIMS_STREAM_DEACTIVATE = 206, VIMS_STREAM_DELETE = 220, + VIMS_STREAM_NEW_AVFORMAT = 239, VIMS_STREAM_NEW_V4L = 240, VIMS_STREAM_NEW_DV1394 = 241, VIMS_STREAM_NEW_COLOR = 242, diff --git a/veejay-current/veejay-server/veejay/vj-event.c b/veejay-current/veejay-server/veejay/vj-event.c index 91dd04e4..dd54a9d6 100644 --- a/veejay-current/veejay-server/veejay/vj-event.c +++ b/veejay-current/veejay-server/veejay/vj-event.c @@ -3555,8 +3555,6 @@ void vj_event_play_slow(void *ptr, const char format[],va_list ap) if(veejay_set_framedup(v, args[0])) { - if( SAMPLE_PLAYING(v)) - sample_reset_loopcount( v->uc->sample_id ); veejay_msg(VEEJAY_MSG_INFO,"A/V frames will be repeated %d times ",args[0]); } else @@ -3904,56 +3902,36 @@ void vj_event_sample_set_loop_type(void *ptr, const char format[], va_list ap) SAMPLE_DEFAULTS(args[0]); - if(args[1] == -1) - { - if(sample_exists(args[0])) - { - if(sample_get_looptype(args[0])==2) - { - int lp; - sample_set_looptype(args[0],1); - lp = sample_get_looptype(args[0]); - veejay_msg(VEEJAY_MSG_INFO, "Sample %d loop type is now %s",args[0], - ( lp==1 ? "Normal Looping" : (lp==2 ? "Pingpong Looping" : "No Looping" ) ) ); - return; - } - else - { - int lp; - sample_set_looptype(args[0],2); - lp = sample_get_looptype(args[0]); - veejay_msg(VEEJAY_MSG_INFO, "Sample %d loop type is now %s",args[0], - ( lp==1 ? "Normal Looping" : lp==2 ? "Pingpong Looping" : "No Looping" ) ); - return; - } - } - else - { - p_no_sample(args[0]); - return; - } - } + if(!sample_exists(args[0])) { + p_no_sample(args[0]); + return; + } + + if(args[1] == -1) { + int lp = sample_get_looptype(args[0]); + if( lp == 1 && args[1] == -1 ) + lp = 2; + else if ( lp == 2 && args[1] == -1 ) + lp = 1; + + sample_set_looptype( args[0], lp ); + + veejay_msg(VEEJAY_MSG_INFO, "Sample %d loop type is now %s",args[0], + ( lp==1 ? "Normal Looping" : lp==2 ? "Pingpong Looping" : "No Looping" ) ); - if(args[1] >= 0 && args[1] <= 4) - { - if(sample_exists(args[0])) - { - int lp; - sample_set_looptype( args[0] , args[1]); - lp = sample_get_looptype(args[0]); - switch(lp) - { - case 0: veejay_msg(VEEJAY_MSG_INFO, "Play once");break; - case 1: veejay_msg(VEEJAY_MSG_INFO, "Normal looping");break; - case 2: veejay_msg(VEEJAY_MSG_INFO, "Pingpong looping");break; - case 3: veejay_msg(VEEJAY_MSG_INFO, "Random frame");break; - case 4: veejay_msg(VEEJAY_MSG_INFO, "Play once (no pause)");break; - } - } } - else + else if(args[1] >= 0 && args[1] <= 4) { - veejay_msg(VEEJAY_MSG_ERROR, "Sample %d does not exist or invalid looptype %d",args[1],args[0]); + int lp = sample_set_looptype( args[0] , args[1]); + lp = sample_get_looptype(args[0]); + switch(lp) + { + case 0: veejay_msg(VEEJAY_MSG_INFO, "Play once");break; + case 1: veejay_msg(VEEJAY_MSG_INFO, "Normal looping");break; + case 2: veejay_msg(VEEJAY_MSG_INFO, "Pingpong looping");break; + case 3: veejay_msg(VEEJAY_MSG_INFO, "Random frame");break; + case 4: veejay_msg(VEEJAY_MSG_INFO, "Play once (no pause)");break; + } } } @@ -4188,7 +4166,6 @@ void vj_event_sample_set_dup(void *ptr, const char format[], va_list ap) { veejay_msg(VEEJAY_MSG_ERROR,"Cannot set frame repeat to %d for sample %d",args[0],args[1]); } - sample_reset_loopcount( args[0] ); } else { @@ -4386,15 +4363,17 @@ void vj_event_sample_rec_start( void *ptr, const char format[], va_list ap) for( i = 0; i < MAX_SEQUENCES; i ++ ) { if( v->seq->samples[i].type == 0) - args[0] += sample_get_longest( v->seq->samples[i].sample_id ); + args[0] += sample_get_frame_length( v->seq->samples[i].sample_id ); else args[0] += vj_tag_get_n_frames( v->seq->samples[i].sample_id ); } + + veejay_sample_set_initial_positions( v ); + v->seq->current = 0; } veejay_msg(VEEJAY_MSG_DEBUG, "\tRecording %d frames (sequencer is %s)", args[0], (v->seq->active ? "active" : "inactive")); } - if(args[0] <= 1 ) { @@ -4425,6 +4404,7 @@ void vj_event_sample_rec_start( void *ptr, const char format[], va_list ap) sample_stop_encoder( v->uc->sample_id ); result = 0; v->settings->sample_record = 0; + v->seq->rec_id = 0; return; } @@ -4436,36 +4416,11 @@ void vj_event_sample_rec_start( void *ptr, const char format[], va_list ap) if( v->seq->active ) { - int i; - int start_at = 0; - int type_at = 0; - for( i = 0; i < MAX_SEQUENCES; i ++ ) - { - if( sample_exists( v->seq->samples[i].sample_id ) || vj_tag_exists( v->seq->samples[i].sample_id) ) - { - start_at = v->seq->samples[i].sample_id; - type_at = v->seq->samples[i].type; - break; - } - } - v->seq->rec_id = v->uc->sample_id; - - if( type_at == 0 ) { - if( start_at == v->uc->sample_id ) - veejay_set_frame(v,sample_get_startFrame(v->uc->sample_id)); - else - veejay_change_playback_mode(v, VJ_PLAYBACK_MODE_SAMPLE, start_at ); - } - else { - veejay_change_playback_mode(v, VJ_PLAYBACK_MODE_TAG, start_at ); - } } else { - //veejay_set_frame(v, sample_get_startFrame(v->uc->sample_id)); veejay_set_frame(v, sample_get_resume(v->uc->sample_id)); - v->seq->rec_id = 0; } } @@ -4479,12 +4434,13 @@ void vj_event_sample_rec_stop(void *ptr, const char format[], va_list ap) video_playback_setup *s = v->settings; int stop_sample = v->uc->sample_id; - if(v->seq->active && v->seq->rec_id ) + if(v->seq->rec_id ) stop_sample = v->seq->rec_id; if( sample_stop_encoder( stop_sample ) == 1 ) { v->settings->sample_record = 0; + v->seq->rec_id = 0; if( sample_get_encoded_file( stop_sample, avi_file) <= 0 ) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to append file '%s' to sample %d", avi_file, stop_sample); @@ -4502,7 +4458,6 @@ void vj_event_sample_rec_stop(void *ptr, const char format[], va_list ap) sample_reset_encoder( stop_sample ); s->sample_record = 0; s->sample_record_id = 0; - v->seq->rec_id = 0; if(s->sample_record_switch) { s->sample_record_switch = 0; @@ -4522,33 +4477,6 @@ void vj_event_sample_rec_stop(void *ptr, const char format[], va_list ap) } } -void vj_event_sample_set_num_loops(void *ptr, const char format[], va_list ap) -{ - veejay_t *v = (veejay_t *)ptr; - int args[2]; - P_A(args,sizeof(args),NULL,0,format,ap); - - SAMPLE_DEFAULTS(args[0]); - - if(sample_exists(args[0])) - { - - if( sample_set_loops(args[0], args[1])) - { veejay_msg(VEEJAY_MSG_INFO, "Setted %d no. of loops for sample %d", - sample_get_loops(args[0]),args[0]); - } - else - { - veejay_msg(VEEJAY_MSG_ERROR,"Cannot set %d loops for sample %d",args[1],args[0]); - } - - } - else - { - p_no_sample(args[0]); - } -} - void vj_event_sample_rel_start(void *ptr, const char format[], va_list ap) { veejay_t *v = (veejay_t *)ptr; @@ -6846,6 +6774,27 @@ void vj_event_stream_new_cali( void *ptr, const char format[], va_list ap) } +void vj_event_tag_new_avformat(void *ptr, const char format[], va_list ap) +{ + veejay_t *v = (veejay_t*) ptr; + + char input[1024]; + P_A(NULL,0, input,sizeof(input),format,ap); + + int id = vj_tag_new(VJ_TAG_TYPE_AVFORMAT, input, v->nstreams, + v->edit_list, + v->pixel_format, + -1, + -1, + v->settings->composite ); + + if(id > 0 ) + v->nstreams++; + + if( id <= 0 ) + veejay_msg(VEEJAY_MSG_ERROR, "Unable to create new video stream "); +} + void vj_event_tag_new_v4l(void *ptr, const char format[], va_list ap) { veejay_t *v = (veejay_t*) ptr; @@ -7505,14 +7454,13 @@ void vj_event_tag_rec_offline_start(void *ptr, const char format[], va_list ap) if( vj_tag_exists(args[0])) { - char tmp[255]; - + char tmp[1024]; int rec_format = _recorder_format; char prefix[40]; if(rec_format==-1) { - veejay_msg(VEEJAY_MSG_ERROR, "Error, no video format selected"); + veejay_msg(VEEJAY_MSG_ERROR, "(Offline) Error, no video recording format selected"); return; } @@ -7539,7 +7487,7 @@ void vj_event_tag_rec_offline_start(void *ptr, const char format[], va_list ap) } else { - veejay_msg(VEEJAY_MSG_ERROR, "Stream %d does not exist",args[0]); + veejay_msg(VEEJAY_MSG_ERROR, "(Offline) Unable to record from stream %d as it does not exists",args[0]); } } @@ -10248,7 +10196,7 @@ static void vj_event_sample_next1( veejay_t *v ) } } else { if( vj_tag_exists( n ) ) { - veejay_set_stream_f(v, n ); + veejay_change_playback_mode(v,VJ_PLAYBACK_MODE_TAG,n); } } } @@ -10426,11 +10374,14 @@ void vj_event_sample_sequencer_active( void *ptr, const char format[], { v->seq->active = 0; v->seq->current = 0; + veejay_reset_sample_positions( v, -1 ); veejay_msg(VEEJAY_MSG_INFO, "Sample sequencer disabled"); } else { v->seq->active = 1; + v->seq->current = 0; + veejay_reset_sample_positions( v, -1 ); veejay_msg(VEEJAY_MSG_INFO, "Sample sequencer enabled"); } } diff --git a/veejay-current/veejay-server/veejay/vj-event.h b/veejay-current/veejay-server/veejay/vj-event.h index e9749edb..8f66aef9 100644 --- a/veejay-current/veejay-server/veejay/vj-event.h +++ b/veejay-current/veejay-server/veejay/vj-event.h @@ -326,4 +326,5 @@ void vj_event_send_shm_info( void *ptr, const char format[], va_list ap); void vj_event_connect_split_shm( void *ptr, const char format[], va_list ap ); void vj_event_get_sample_image(void *ptr,const char format[],va_list ap ); void vj_event_alpha_composite(void *ptr, const char format[], va_list ap ); +void vj_event_tag_new_avformat(void *ptr, const char format[], va_list ap); #endif diff --git a/veejay-current/veejay-server/veejay/vj-eventman.c b/veejay-current/veejay-server/veejay/vj-eventman.c index 93e320c2..973243b8 100644 --- a/veejay-current/veejay-server/veejay/vj-eventman.c +++ b/veejay-current/veejay-server/veejay/vj-eventman.c @@ -1321,6 +1321,18 @@ void vj_init_vevo_events(void) 0, NULL ); + index_map_[VIMS_STREAM_NEW_AVFORMAT] = _new_event( + "%s", + VIMS_STREAM_NEW_AVFORMAT, + "Open video stream using libavformat", + vj_event_tag_new_avformat, + 1, + VIMS_REQUIRE_ALL_PARAMS, + "Filename or connection string", + NULL, + 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 400b14ea..4a4b336f 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -164,8 +164,7 @@ static int vj_perform_get_frame_fx(veejay_t *info, int s1, long nframe, VJFrame static void vj_perform_pre_chain(veejay_t *info, VJFrame *frame); static int vj_perform_post_chain_sample(veejay_t *info, VJFrame *frame); static int vj_perform_post_chain_tag(veejay_t *info, VJFrame *frame); -static void seq_play_sample( veejay_t *info, int n, int t); -static int vj_perform_valid_sequence( veejay_t *info, int *type ); +static int vj_perform_next_sequence( veejay_t *info, int *type ); static void vj_perform_plain_fill_buffer(veejay_t * info, int *result); static void vj_perform_tag_fill_buffer(veejay_t * info); static void vj_perform_clear_cache(void); @@ -320,15 +319,14 @@ static int vj_perform_increase_tag_frame(veejay_t * info, long num) if( settings->current_frame_num >= settings->max_frame_num ) { settings->current_frame_num = settings->min_frame_num; int type = 0; - int n = vj_perform_valid_sequence( info, &type ); - if( n >= 0 ) - seq_play_sample(info,n,type); + int n = vj_perform_next_sequence( info, &type ); + if( n > 0 ) + veejay_change_playback_mode(info,(type == 0 ? VJ_PLAYBACK_MODE_SAMPLE: VJ_PLAYBACK_MODE_TAG),n ); } } if (settings->current_frame_num >= settings->max_frame_num) { settings->current_frame_num = settings->min_frame_num; - return 0; } return 0; @@ -364,69 +362,65 @@ static int vj_perform_increase_plain_frame(veejay_t * info, long num) return 0; } - -static int vj_perform_valid_sequence( veejay_t *info, int *type ) +static int vj_perform_next_sequence( veejay_t *info, int *type ) { - int cur = info->seq->current + 1; - int cycle = 0; + + if( info->seq->samples[info->seq->current].type == 0 && + info->seq->samples[info->seq->current].sample_id > 0 ) { + + if(sample_loop_dec(info->seq->samples[info->seq->current].sample_id) != 0) /* loop count zero, select next sequence */ + return 0; + veejay_prepare_sample_positions( info->seq->samples[info->seq->current].sample_id ); + } + + + int cur = info->seq->current + 1; + int cycle = 0; + + if( cur >= MAX_SEQUENCES ) + cur = 0; + while( info->seq->samples[ cur ].sample_id == 0 ) { cur ++; - if( cur >= MAX_SEQUENCES && !cycle) - { - cur = 0; - cycle = 1; - } - else if ( cur >= MAX_SEQUENCES && cycle ) - { - veejay_msg(VEEJAY_MSG_ERROR, "No valid sequence to play. Sequence Play disabled"); + if( cur >= MAX_SEQUENCES && !cycle) { + cur = 0; + cycle = 1; + } + else if (cur >= MAX_SEQUENCES && cycle) { + veejay_msg(VEEJAY_MSG_ERROR, "No valid sequence to play. Sequence Play disabled"); info->seq->active = 0; - return -1; - } - } + return 0; + } + } + + info->seq->current = cur; + + sample_update_ascociated_samples( info->seq->samples[cur].sample_id ); + sample_reset_offset( info->seq->samples[cur].sample_id ); + sample_set_loops( info->seq->samples[cur].sample_id, -1 ); /* reset loop count */ *type = info->seq->samples[cur].type; - - return cur; -} - -static void seq_play_sample( veejay_t *info, int n, int type) -{ - info->seq->current = n; - - if( type == 0 ) { - - int which_sample = 0; - int offset = sample_get_first_mix_offset( info->uc->sample_id, &which_sample, info->seq->samples[info->seq->current].sample_id ); - - veejay_set_sample_f( info, info->seq->samples[ info->seq->current ].sample_id , offset ); - } - else { - veejay_set_stream_f( info, info->seq->samples[ info->seq->current ].sample_id ); - } + return info->seq->samples[cur].sample_id; } static int vj_perform_try_sequence( veejay_t *info ) { if(! info->seq->active ) return 0; - - if( sample_get_loop_dec( info->uc->sample_id ) >= 1 ) + + int type = 0; + int n = vj_perform_next_sequence( info, &type ); + if( n > 0 ) { - int type = 0; - int n = vj_perform_valid_sequence( info, &type ); - if( n >= 0 ) - { - if( type == 0 ) - sample_set_loop_dec( info->uc->sample_id, 0 ); //reset loop + veejay_msg(VEEJAY_MSG_INFO, "Sequence play selects %s %d", (type == 0 ? "sample" : "stream" ) , info->seq->samples[info->seq->current].sample_id); - veejay_msg(0, "Sequence play selects %s %d", (type == 0 ? "sample" : "stream" ) , info->seq->samples[n].sample_id); - - seq_play_sample(info, n, type ); - return 1; - } - return 0; - } + veejay_change_playback_mode( info, + info->seq->samples[ info->seq->current ].type == 0 ? VJ_PLAYBACK_MODE_SAMPLE : VJ_PLAYBACK_MODE_TAG, + info->seq->samples[ info->seq->current ].sample_id); + + return 1; + } return 0; } @@ -458,124 +452,93 @@ static int vj_perform_increase_sample_frame(veejay_t * info, long num) if( cur_sfd != 0 ) return 0; - } - settings->current_frame_num += num; - sample_set_resume( info->uc->sample_id, settings->current_frame_num ); - - - if( num == 0 ) - return 0; + if( num == 0 ) { + sample_set_resume( info->uc->sample_id, settings->current_frame_num ); + return 0; + } if (speed >= 0) { /* forward play */ - if(looptype==3) - { - int range = end - start; - int n2 = start + ((int) ( (double)range * rand()/(RAND_MAX))); - settings->current_frame_num = n2; - } + if(looptype==3) + { + int range = end - start; + int n2 = start + ((int) ( (double)range * rand()/(RAND_MAX))); + settings->current_frame_num = n2; + } - if (settings->current_frame_num > end || settings->current_frame_num < start) { - switch (looptype) { - case 2: - sample_loopcount( info->uc->sample_id); - info->uc->direction = -1; - if(!vj_perform_try_sequence( info ) ) - { - editlist *E = sample_get_editlist(info->uc->sample_id); - sample_apply_loop_dec( info->uc->sample_id,E->video_fps); - veejay_set_frame(info, end); - veejay_set_speed(info, (-1 * speed)); - } - sample_loopcount( info->uc->sample_id); - break; - case 1: - sample_loopcount( info->uc->sample_id); - if(! info->seq->active ) - veejay_set_frame(info, start); - else - { - int type = 0; - int n = vj_perform_valid_sequence( info, &type ); - if( n >= 0 ) - seq_play_sample( info, n, type ); - else - veejay_set_frame(info,start); - } - break; - case 3: - sample_loopcount( info->uc->sample_id); - veejay_set_frame(info, start); - break; - case 4: - veejay_set_frame(info,end); - break; - default: - veejay_set_frame(info, end); - veejay_set_speed(info, 0); + if (settings->current_frame_num > end || settings->current_frame_num < start) { + switch (looptype) { + case 2: + info->uc->direction = -1; + if(!vj_perform_try_sequence( info ) ) + { + veejay_set_frame(info, end); + veejay_set_speed(info, (-1 * speed)); + } + break; + case 1: + if(!vj_perform_try_sequence(info) ) { + veejay_set_frame(info, start); + } + break; + case 3: + veejay_set_frame(info, start); + break; + case 4: + veejay_set_frame(info,end); + break; + default: + veejay_set_frame(info, end); + veejay_set_speed(info, 0); + break; + } } - } - } else { /* reverse play */ - if( looptype == 3) - { - int range = end - start; - int n2 = end - ((int) ( (double)range*rand()/(RAND_MAX))); - settings->current_frame_num = n2; - } - - if (settings->current_frame_num < start || settings->current_frame_num >= end ) { - switch (looptype) { - case 2: - sample_loopcount( info->uc->sample_id); - - info->uc->direction = 1; - if(!vj_perform_try_sequence(info) ) - { - editlist *E = sample_get_editlist(info->uc->sample_id); - sample_apply_loop_dec( info->uc->sample_id, E->video_fps); - veejay_set_frame(info, start); - veejay_set_speed(info, (-1 * speed)); - } - break; - case 1: - sample_loopcount( info->uc->sample_id); - - if(!info->seq->active) - veejay_set_frame(info, end); - else - { - int type = 0; - int n = vj_perform_valid_sequence( info, &type ); - if( n >= 0 ) - { - seq_play_sample(info, n, type ); - } - else - veejay_set_frame(info,end); - } - break; - case 3: - sample_loopcount( info->uc->sample_id); - - veejay_set_frame(info,end); - break; - case 4: - veejay_set_frame(info,start); - break; - default: - veejay_set_frame(info, start); - veejay_set_speed(info, 0); + } + else + { /* reverse play */ + if( looptype == 3) + { + int range = end - start; + int n2 = end - ((int) ( (double)range*rand()/(RAND_MAX))); + settings->current_frame_num = n2; + } + + if (settings->current_frame_num < start || settings->current_frame_num >= end ) { + switch (looptype) { + case 2: + info->uc->direction = 1; + if(!vj_perform_try_sequence(info) ) + { + veejay_set_frame(info, start); + veejay_set_speed(info, (-1 * speed)); + } + break; + case 1: + if(!vj_perform_try_sequence(info)) { + veejay_set_frame(info, end); + } + break; + case 3: + veejay_set_frame(info,end); + break; + case 4: + veejay_set_frame(info,start); + break; + default: + veejay_set_frame(info, start); + veejay_set_speed(info, 0); + break; + } } - } } - // sample_update_offset( info->uc->sample_id, settings->current_frame_num ); - sample_set_resume( info->uc->sample_id, settings->current_frame_num ); - + if(!info->seq->active) { + sample_set_resume( info->uc->sample_id, settings->current_frame_num ); + } vj_perform_rand_update( info ); return 0; @@ -1207,14 +1170,6 @@ int vj_perform_get_cropped_frame( veejay_t *info, uint8_t **frame, int crop ) return 1; } -static void long2str(uint8_t *dst, uint32_t n) -{ - dst[0] = (n )&0xff; - dst[1] = (n>> 8)&0xff; - dst[2] = (n>>16)&0xff; - dst[3] = (n>>24)&0xff; -} - static long stream_pts_ = 0; static int vj_perform_compress_primary_frame_s2(veejay_t *info,VJFrame *frame ) { @@ -1850,7 +1805,10 @@ static int vj_perform_apply_secundary_tag(veejay_t * info, int sample_id, int ty break; case VJ_TAG_TYPE_NONE: - nframe = vj_perform_get_subframe_tag(info, sample_id, chain_entry); + nframe = vj_perform_get_subframe_tag(info, sample_id, chain_entry); + + sample_set_resume( sample_id, nframe ); + if(!subrender) centry = vj_perform_sample_is_cached(info,sample_id, chain_entry); if(centry == -1 || info->no_caching|| subrender ) @@ -2068,10 +2026,14 @@ static int vj_perform_apply_secundary(veejay_t * info, int this_sample_id, int s break; case VJ_TAG_TYPE_NONE: - nframe = vj_perform_get_subframe(info,this_sample_id, sample_id, chain_entry); // get exact frame number to decode + nframe = vj_perform_get_subframe(info,this_sample_id, sample_id, chain_entry); // get exact frame number to decode + + sample_set_resume( sample_id, nframe ); + if(!subrender) centry = vj_perform_sample_is_cached(info,sample_id, chain_entry); - if(centry == -1 || info->no_caching||subrender) { + + if(centry == -1 || info->no_caching||subrender) { len = vj_perform_get_frame_fx( info, sample_id, nframe, src, dst, p0_ref, p1_ref ); if(len > 0 ) { error = 0; @@ -2623,7 +2585,6 @@ static int vj_perform_record_commit_single(veejay_t *info) } } - info->seq->rec_id = 0; return id; } else { @@ -2708,7 +2669,7 @@ 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) + if(info->uc->playback_mode==VJ_PLAYBACK_MODE_SAMPLE || ( info->seq->active && info->seq->rec_id > 0 )) { sample_reset_encoder(info->uc->sample_id); sample_reset_autosplit(info->uc->sample_id); @@ -2727,6 +2688,8 @@ void vj_perform_record_stop(veejay_t *info) settings->sample_record_switch =0; settings->render_list = 0; + info->seq->rec_id = 0; + } else if(info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG) { @@ -2759,7 +2722,7 @@ void vj_perform_record_stop(veejay_t *info) void vj_perform_record_sample_frame(veejay_t *info, int sample, int type) { uint8_t *frame[4]; int res = 1; - int n = 0; + frame[0] = primary_buffer[0]->Y; frame[1] = primary_buffer[0]->Cb; frame[2] = primary_buffer[0]->Cr; @@ -2767,51 +2730,19 @@ void vj_perform_record_sample_frame(veejay_t *info, int sample, int type) { res = vj_perform_render_sample_frame(info, frame, sample,type); - if( res == 2) + if( res == 2 || res == 1) { - int df = vj_event_get_video_format(); - long frames_left = sample_get_frames_left(sample) ; - sample_stop_encoder( sample ); - n = vj_perform_record_commit_single( info ); - - if(frames_left > 0 ) - { - veejay_msg(VEEJAY_MSG_DEBUG, "Continue, %d frames left to record", frames_left); - if( sample_init_encoder( sample, NULL, - df, info->effect_frame1, info->current_edit_list, frames_left)==-1) - { - veejay_msg(VEEJAY_MSG_ERROR, - "Error while auto splitting "); - report_bug(); - } - } - else - { - int len = sample_get_total_frames(sample); - - veejay_msg(VEEJAY_MSG_DEBUG, "Added new sample %d of %d frames",n,len); - sample_reset_encoder( sample ); - sample_reset_autosplit( sample ); - } - } - - if( res == 1) - { - sample_stop_encoder(sample); vj_perform_record_commit_single( info ); - vj_perform_record_stop(info); + vj_perform_record_stop(info); } - + if( res == -1) { - if( info->seq->active && info->seq->rec_id ) - info->seq->rec_id = 0; - sample_stop_encoder(sample); vj_perform_record_stop(info); - } + } } void vj_perform_record_offline_tag_frame(veejay_t *info) @@ -3666,11 +3597,7 @@ static void vj_perform_record_frame( veejay_t *info ) } if( info->seq->active && info->seq->rec_id > 0 ) { - int type = 0; - if( info->uc->playback_mode == VJ_PLAYBACK_MODE_TAG ) - type = vj_tag_get_type( info->uc->sample_id ); - - vj_perform_record_sample_frame(info,info->seq->rec_id,type); + vj_perform_record_sample_frame(info,info->seq->rec_id, 0); } else {