diff --git a/veejay-current/veejay-client/src/vj-api.c b/veejay-current/veejay-client/src/vj-api.c index 5ca8caa4..e5212785 100644 --- a/veejay-current/veejay-client/src/vj-api.c +++ b/veejay-current/veejay-client/src/vj-api.c @@ -5121,46 +5121,71 @@ static void reload_editlist_contents() { return; } - char str_nf[4]; + + el_constr *el; - strncpy( str_nf, eltext , sizeof(str_nf)); - sscanf( str_nf, "%04d", &num_files ); + char *tmp = strndup( eltext + offset, 4 ); + if( sscanf( tmp,"%d",&num_files ) != 1 ) { + free(tmp); + g_free(eltext); + return; + } + free(tmp); offset += 4; - int n = 0; - el_constr *el; for( i = 0; i < num_files ; i ++ ) { - int itmp =0; - char *tmp1 = (char*) strndup( eltext+offset, 4 ); - int line_len = 0; - char fourcc[4]; - veejay_memset(fourcc,0,sizeof(fourcc)); - n = sscanf( tmp1, "%04d", &line_len ); // line len - if(line_len>0) - { - offset += 4; - char *line = (char*)strndup( eltext + offset, line_len ); - offset += line_len; - char *tmp = (char*) strndup( line, 3 ); - sscanf(tmp, "%03d",&itmp ); - char *file = strndup( line + 3, itmp ); + int name_len = 0; + tmp = strndup( eltext + offset, 3 ); + if( sscanf( tmp,"%d", &name_len ) != 1 ) { free(tmp); - tmp = (char*) strndup( line + 3 + itmp, 16 ); - int a,b,c; - int n = sscanf(tmp, "%04d%010d%02d", &a,&b,&c); - free(tmp); - if( n == 3 ) - { - strncpy(fourcc, line + 3 + itmp + 16, c ); - el = _el_entry_new( i, file, b, fourcc ); - info->editlist = g_list_append( info->editlist, el ); - } - free(line); - free(file); + g_free(eltext); + return; } - free(tmp1); + offset += 3; + free(tmp); + char *file = strndup( eltext + offset, name_len ); + + offset += name_len; + int iter = 0; + tmp = strndup( eltext + offset, 4 ); + if( sscanf( tmp, "%d", &iter ) != 1 ) { + free(tmp); + g_free(eltext); + return; + } + free(tmp); + offset += 4; + + long num_frames = 0; + tmp = strndup( eltext + offset, 10 ); + if( sscanf(tmp, "%ld", &num_frames ) != 1 ) { + free(tmp); + g_free(eltext); + return; + } + free(tmp); + offset += 10; + + int fourcc_len = 0; + tmp = strndup( eltext + offset, 2 ); + if( sscanf( tmp, "%d", &fourcc_len) != 1 ) { + free(tmp); + g_free(eltext); + return; + } + free(tmp); + offset += fourcc_len; + char *fourcc = strndup( eltext + offset - 1, fourcc_len ); + + el = _el_entry_new( iter, file, num_frames, fourcc ); + info->editlist = g_list_append( info->editlist, el ); + + offset += 2; + + free(file); + free(fourcc); } GtkTreeModel *model = gtk_tree_view_get_model( GTK_TREE_VIEW(tree )); store = GTK_LIST_STORE(model); @@ -5229,7 +5254,6 @@ static void reload_editlist_contents() gtk_tree_view_set_model( GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store)); g_free( eltext ); - } // execute after el change: diff --git a/veejay-current/veejay-server/libel/Makefile.am b/veejay-current/veejay-server/libel/Makefile.am index f01cea4e..fde0c5a4 100644 --- a/veejay-current/veejay-server/libel/Makefile.am +++ b/veejay-current/veejay-server/libel/Makefile.am @@ -18,7 +18,7 @@ INCLUDES += $(FFMPEG_CFLAGS) $(PIXBUF_CFLAGS) $(LIBQUICKTIME_CFLAGS) $(MJPEGTOOL VJEL_LIB_FILE = libel.la noinst_LTLIBRARIES = $(VJEL_LIB_FILE) -libel_la_SOURCES = vj-mmap.c elcache.c avilib.c lav_io.c vj-dv.c rawdv.c pixbuf.c vj-avcodec.c vj-el.c +libel_la_SOURCES = vj-mmap.c elcache.c avilib.c lav_io.c vj-dv.c rawdv.c pixbuf.c vj-avcodec.c avhelper.c vj-el.c EXTRA_DIST = avilib.h elcache.h lav_io.h pixbuf.h \ rawdv.h vj-avcodec.h vj-dv.h vj-el.h vj-mmap.h diff --git a/veejay-current/veejay-server/libel/avilib.c b/veejay-current/veejay-server/libel/avilib.c index b4eda942..fd1630cc 100644 --- a/veejay-current/veejay-server/libel/avilib.c +++ b/veejay-current/veejay-server/libel/avilib.c @@ -36,6 +36,8 @@ #include #endif +#define RUP8(num)(((num)+8)&~8) + #ifndef O_BINARY #define O_BINARY 0 #endif @@ -302,22 +304,19 @@ static int avi_init_super_index(avi_t *AVI, unsigned char *idxtag, avisuperindex veejay_memset (sil->dwReserved, 0, sizeof (sil->dwReserved)); // NR_IXNN_CHUNKS == allow 32 indices which means 32 GB files -- arbitrary - sil->aIndex = vj_malloc (sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (uint32_t)); + sil->aIndex = vj_calloc( RUP8(sil->wLongsPerEntry * NR_IXNN_CHUNKS) * sizeof (uint32_t)); if (!sil->aIndex) { AVI_errno = AVI_ERR_NO_MEM; return -1; } - veejay_memset (sil->aIndex, 0, sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (uint32_t)); - sil->stdindex = vj_malloc (NR_IXNN_CHUNKS * sizeof (avistdindex_chunk *)); + sil->stdindex = vj_calloc(RUP8( NR_IXNN_CHUNKS * sizeof (avistdindex_chunk *))); if (!sil->stdindex) { AVI_errno = AVI_ERR_NO_MEM; return -1; } for (k = 0; k < NR_IXNN_CHUNKS; k++) { - sil->stdindex[k] = vj_malloc (sizeof (avistdindex_chunk)); - veejay_memset(sil->stdindex[k], 0, sizeof (avistdindex_chunk)); - // gets rewritten later + sil->stdindex[k] = vj_calloc (sizeof (avistdindex_chunk)); sil->stdindex[k]->qwBaseOffset = (uint64_t)k * NEW_RIFF_THRES; } @@ -343,7 +342,7 @@ static int avi_add_std_index(avi_t *AVI, unsigned char *idxtag, unsigned char *s //stdil->qwBaseOffset = AVI->video_superindex->aIndex[ cur_std_idx ]->qwOffset; - stdil->aIndex = vj_malloc(stdil->dwSize * sizeof (uint32_t) * stdil->wLongsPerEntry); + stdil->aIndex = vj_calloc(stdil->dwSize * sizeof (uint32_t) * stdil->wLongsPerEntry); if (!stdil->aIndex) { AVI_errno = AVI_ERR_NO_MEM; @@ -1930,17 +1929,21 @@ int AVI_close(avi_t *AVI) if(AVI->track[j].audio_superindex) { // shortcut avisuperindex_chunk *a = AVI->track[j].audio_superindex; - for (k = 0; k < NR_IXNN_CHUNKS; k++) { - if (a->stdindex && a->stdindex[k]) { - if (a->stdindex[k]->aIndex) { - free(a->stdindex[k]->aIndex); - } - free(a->stdindex[k]); - } + if( a ) { + /* if( a->stdindex ) { + for (k = 0; k < NR_IXNN_CHUNKS; k++) { + if (a->stdindex && a->stdindex[k]) { + if (a->stdindex[k]->aIndex) { + free(a->stdindex[k]->aIndex); + } + free(a->stdindex[k]); + } + } + free(a->stdindex); + } */ + if(a->aIndex) free(a->aIndex); + free(a); } - if(a->stdindex) free(a->stdindex); - if(a->aIndex) free(a->aIndex); - free(a); } } @@ -3281,8 +3284,7 @@ long AVI_read_frame(avi_t *AVI, char *vidbuf, int *keyframe) } else { - n = mmap_read( AVI->mmap_region, AVI->video_index[ AVI->video_pos].pos, - n, vidbuf ); + n = mmap_read( AVI->mmap_region, AVI->video_index[ AVI->video_pos].pos, n, vidbuf ); } diff --git a/veejay-current/veejay-server/libel/elcache.c b/veejay-current/veejay-server/libel/elcache.c index d435c56b..3fc0c138 100644 --- a/veejay-current/veejay-server/libel/elcache.c +++ b/veejay-current/veejay-server/libel/elcache.c @@ -58,13 +58,13 @@ static int cache_free_slot(cache_t *v) static long total_mem_used_ = 0; -static void cache_claim_slot(cache_t *v, int free_slot, uint8_t *linbuf, long frame_num,int buf_len, int decoder_id) +static void cache_claim_slot(cache_t *v, int free_slot, uint8_t *linbuf, long frame_num,int buf_len,int format) { // create new node cache_slot_t *data = (cache_slot_t*) vj_malloc(sizeof(cache_slot_t)); data->size = buf_len; data->num = frame_num; - data->fmt = decoder_id; + data->fmt = format; data->buffer = vj_malloc( buf_len ); #ifdef STRICT_CHECKING assert( v->index[free_slot] != frame_num ); @@ -163,7 +163,7 @@ void free_cache(void *cache) v = NULL; } -void cache_frame( void *cache, uint8_t *linbuf, int buflen, long frame_num , int decoder_id) +void cache_frame( void *cache, uint8_t *linbuf, int buflen, long frame_num , int format) { cache_t *v = (cache_t*) cache; #ifdef STRICT_CHECKING @@ -182,10 +182,10 @@ void cache_frame( void *cache, uint8_t *linbuf, int buflen, long frame_num , int #ifdef STRICT_CHECKING assert(slot_num >= 0 ); #endif - cache_claim_slot(v, slot_num, linbuf, frame_num, buflen, decoder_id); + cache_claim_slot(v, slot_num, linbuf, frame_num, buflen, format); } -uint8_t *get_cached_frame( void *cache, long frame_num, int *buf_len, int *decoder_id ) +uint8_t *get_cached_frame( void *cache, long frame_num, int *buf_len, int *format ) { cache_t *v = (cache_t*) cache; int slot = cache_locate_slot( v, frame_num ); @@ -199,7 +199,7 @@ uint8_t *get_cached_frame( void *cache, long frame_num, int *buf_len, int *decod #endif *buf_len = data->size; - *decoder_id = data->fmt; + *format = data->fmt; #ifdef STRICT_CHECKING assert( data->num == frame_num ); #endif diff --git a/veejay-current/veejay-server/libel/elcache.h b/veejay-current/veejay-server/libel/elcache.h index f65caf5c..981cca6f 100644 --- a/veejay-current/veejay-server/libel/elcache.h +++ b/veejay-current/veejay-server/libel/elcache.h @@ -20,8 +20,8 @@ #ifndef ELCACHE_H #define ELCACHE_H -uint8_t *get_cached_frame( void *cache, long frame_num, int *buf_len, int *decoder_id ); -void cache_frame( void *cache, uint8_t *linbuf, int buflen, long frame_num , int decoder_id); +uint8_t *get_cached_frame( void *cache, long frame_num, int *buf_len, int *format ); +void cache_frame( void *cache, uint8_t *linbuf, int buflen, long frame_num , int format); void free_cache(void *cache); void *init_cache( unsigned int n_slots ); void reset_cache(void *cache); diff --git a/veejay-current/veejay-server/libel/lav_io.c b/veejay-current/veejay-server/libel/lav_io.c index 221c9530..b6d048d1 100644 --- a/veejay-current/veejay-server/libel/lav_io.c +++ b/veejay-current/veejay-server/libel/lav_io.c @@ -1835,10 +1835,9 @@ int lav_get_field_size(uint8_t * jpegdata, long jpeglen) return jpeg_padded_len; } -static char error_string[4096]; - const char *lav_strerror(void) { + static char error_string[1024]; switch(internal_error) { @@ -1874,7 +1873,7 @@ const char *lav_strerror(void) return AVI_strerror(); default: /* No or unknown video format */ - sprintf(error_string,"No or unknown video format"); + snprintf(error_string,sizeof(error_string),"No or unknown video format"); return error_string; } } diff --git a/veejay-current/veejay-server/libel/vj-avcodec.c b/veejay-current/veejay-server/libel/vj-avcodec.c index f36885d2..6df4adf8 100644 --- a/veejay-current/veejay-server/libel/vj-avcodec.c +++ b/veejay-current/veejay-server/libel/vj-avcodec.c @@ -117,7 +117,7 @@ uint8_t *vj_avcodec_get_buf( vj_encoder *av ) return av->data[0]; } -static vj_encoder *vj_avcodec_new_encoder( int id, editlist *el, char *filename) +static vj_encoder *vj_avcodec_new_encoder( int id, VJFrame *frame, char *filename) { vj_encoder *e = (vj_encoder*) vj_calloc(sizeof(vj_encoder)); if(!e) return NULL; @@ -127,21 +127,21 @@ static vj_encoder *vj_avcodec_new_encoder( int id, editlist *el, char *filename) #ifdef SUPPORT_READ_DV2 if( id == CODEC_ID_DVVIDEO ) { - if(!is_dv_resolution(el->video_width, el->video_height )) + if(!is_dv_resolution(frame->width, frame->height )) { veejay_msg(VEEJAY_MSG_ERROR,"\tSource video is not in DV resolution"); return NULL; } else { - e->dv = (void*)vj_dv_init_encoder( (void*)el , out_pixel_format); + e->dv = (void*)vj_dv_init_encoder( (void*)frame , out_pixel_format); } } else { #endif - e->data[0] = (uint8_t*) vj_calloc(sizeof(uint8_t) * el->video_width * el->video_height * 3 ); - e->data[1] = e->data[0] + el->video_width * el->video_height; - e->data[2] = e->data[1] + el->video_width * el->video_height; //@ for all pixfmt + e->data[0] = (uint8_t*) vj_calloc(sizeof(uint8_t) * frame->width * frame->height * 3 ); + e->data[1] = e->data[0] + frame->width * frame->height; + e->data[2] = e->data[1] + frame->width * frame->height; //@ for all pixfmt #ifdef SUPPORT_READ_DV2 } #endif @@ -152,9 +152,7 @@ static vj_encoder *vj_avcodec_new_encoder( int id, editlist *el, char *filename) } if( id == 995 || id == 994) { - e->y4m = vj_yuv4mpeg_alloc(el, el->video_width, - el->video_height, - out_pixel_format ); + e->y4m = vj_yuv4mpeg_alloc(frame->width,frame->height,frame->fps, out_pixel_format ); if( !e->y4m) { veejay_msg(0, "Error while trying to setup Y4M stream, abort."); return NULL; @@ -165,7 +163,7 @@ static vj_encoder *vj_avcodec_new_encoder( int id, editlist *el, char *filename) chroma_val = Y4M_CHROMA_420MPEG2; } - if( vj_yuv_stream_start_write( e->y4m, el,filename,chroma_val )== -1 ) + if( vj_yuv_stream_start_write( e->y4m, frame,filename,chroma_val )== -1 ) { veejay_msg(0, "Unable to write header to YUV4MPEG stream"); vj_yuv4mpeg_free( e->y4m ); @@ -204,12 +202,12 @@ static vj_encoder *vj_avcodec_new_encoder( int id, editlist *el, char *filename) e->context = avcodec_alloc_context(); #endif e->context->bit_rate = 2750 * 1024; - e->context->width = el->video_width; - e->context->height = el->video_height; + e->context->width = frame->width; + e->context->height = frame->height; #if LIBAVCODEC_BUILD > 5010 - e->context->time_base = (AVRational) { 1, el->video_fps }; + e->context->time_base = (AVRational) { 1, frame->fps }; #else - e->context->frame_rate = el->video_fps; + e->context->frame_rate = frame->fps; e->context->frame_rate_base = 1; #endif e->context->sample_aspect_ratio.den = 1; @@ -255,30 +253,15 @@ static vj_encoder *vj_avcodec_new_encoder( int id, editlist *el, char *filename) #endif } - e->width = el->video_width; - e->height = el->video_height; + e->width = frame->width; + e->height = frame->height; e->encoder_id = id; - - - switch(pf) { - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUV422P: - e->shift_y = 0; - e->shift_x = 1; - e->len = el->video_width * el->video_height; - e->uv_len = e->len / 2; - e->out_fmt = (pf == PIX_FMT_YUVJ422P ? FMT_422F : FMT_422 ); - break; - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUV420P: - e->shift_y = 1; - e->shift_x = 1; - e->len = el->video_width * el->video_height; - e->uv_len = e->len / 4; - e->out_fmt = (pf == PIX_FMT_YUVJ420P ? FMT_420F : FMT_420 ); - break; - } - + e->shift_y = frame->shift_v; + e->shift_x = frame->shift_h; + e->len = frame->len; + e->uv_len = frame->uv_len; + e->out_fmt = pixfmt_to_vj( pf ); + return e; } void vj_avcodec_close_encoder( vj_encoder *av ) @@ -427,7 +410,7 @@ int vj_avcodec_stop( void *encoder , int fmt) return 1; } -void *vj_avcodec_start( editlist *el, int encoder, char *filename ) +void *vj_avcodec_start( VJFrame *frame, int encoder, char *filename ) { int codec_id = vj_avcodec_find_codec( encoder ); void *ee = NULL; @@ -437,7 +420,7 @@ void *vj_avcodec_start( editlist *el, int encoder, char *filename ) return NULL; } #endif - ee = vj_avcodec_new_encoder( codec_id, el ,filename); + ee = vj_avcodec_new_encoder( codec_id, frame ,filename); if(!ee) { veejay_msg(VEEJAY_MSG_ERROR, "\tFailed to start encoder %x",encoder); diff --git a/veejay-current/veejay-server/libel/vj-avcodec.h b/veejay-current/veejay-server/libel/vj-avcodec.h index 9bb66567..e831c56a 100644 --- a/veejay-current/veejay-server/libel/vj-avcodec.h +++ b/veejay-current/veejay-server/libel/vj-avcodec.h @@ -83,7 +83,7 @@ int yuv420p_to_yuv422p2( uint8_t *sY,uint8_t *sCb, uint8_t *sCr, uint8_t *dst[3 void yuv422p_to_yuv420p3( uint8_t *src, uint8_t *dst[3], int w, int h); -void *vj_avcodec_start( editlist *el, int encoder, char *filename ); +void *vj_avcodec_start( VJFrame *frame, int encoder, char *filename ); int vj_avcodec_stop( void *encoder , int fmt); diff --git a/veejay-current/veejay-server/libel/vj-dv.c b/veejay-current/veejay-server/libel/vj-dv.c index b040ea99..c9af0032 100644 --- a/veejay-current/veejay-server/libel/vj-dv.c +++ b/veejay-current/veejay-server/libel/vj-dv.c @@ -23,7 +23,6 @@ #include #ifdef SUPPORT_READ_DV2 #include -#include #include #include #include @@ -74,20 +73,19 @@ vj_dv_decoder *vj_dv_decoder_init(int quality, int width, int height, int pixel_ static sws_template dv_templ; /* init the dv encoder and encode buffer */ -vj_dv_encoder *vj_dv_init_encoder(void * edl, int pixel_format) +vj_dv_encoder *vj_dv_init_encoder(void * edl, int pixel_format, int isPAL) { - editlist *el = (editlist*) edl; + VJFrame *frame = (VJFrame*) edl; vj_dv_encoder *e = (vj_dv_encoder*) vj_malloc(sizeof(vj_dv_encoder)); if(!e) return NULL; e->encoder = dv_encoder_new(0,0,0); - e->encoder->isPAL = (el->video_norm == 'p' ? 1 : 0); - e->encoder->is16x9 = (el->video_width / el->video_height >= 1.777 ? 1: 0); + e->encoder->isPAL = isPAL; + e->encoder->is16x9 = (frame->width / frame->height >= 1.777 ? 1: 0); e->encoder->vlc_encode_passes = 3; e->encoder->static_qno = 0; e->encoder->force_dct = DV_DCT_AUTO; e->fmt = pixel_format; - e->buffer = (uint8_t*) vj_calloc(sizeof(uint8_t) * - el->video_width * el->video_height * 3 ); + e->buffer = (uint8_t*) vj_calloc(sizeof(uint8_t) * frame->width * frame->height * 3 ); e->dv_video = (uint8_t *) vj_calloc(sizeof(uint8_t) * (e->encoder->isPAL ? @@ -141,10 +139,6 @@ int vj_dv_encode_frame(vj_dv_encoder *encoder, uint8_t *input_buf[3]) yuv_convert_and_scale_packed( encoder->scaler, src,dst ); -// if( encoder->fmt == FMT_422F ) { -// yuy2_scale_pixels_from_yuv( encoder->buffer, w * h ); - // } - dv_encode_full_frame( encoder->encoder, pixels, e_dv_color_yuv,encoder->dv_video); dv_encode_metadata(encoder->dv_video, encoder->encoder->isPAL,encoder->encoder->is16x9, &now, 0); dv_encode_timecode(encoder->dv_video, encoder->encoder->isPAL, 0); @@ -389,12 +383,6 @@ int vj_dv_decode_frame(vj_dv_decoder *d, uint8_t * input_buf, uint8_t * Y, d->decoder->num_dif_seqs ); return 0; } -#ifdef STRICT_CHECKING -// if ( d->decoder->sampling == e_dv_sample_420 ) -// assert( d->fmt == FMT_420 || d->fmt == FMT_420F ); -// if ( d->decoder->sampling == e_dv_sample_422 ) -// assert( d->fmt == FMT_422 || d->fmt == FMT_422F ); -#endif if ( d->decoder->sampling == e_dv_sample_422 || d->decoder->sampling == e_dv_sample_411 ) @@ -412,8 +400,7 @@ int vj_dv_decode_frame(vj_dv_decoder *d, uint8_t * input_buf, uint8_t * Y, //@ this works VJFrame *src = yuv_yuv_template( d->dv_video, NULL,NULL,width,height,PIX_FMT_YUYV422 ); - VJFrame *dst = yuv_yuv_template( Y,Cb,Cr,width,height, - ( d->fmt == FMT_422 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P ) ); + VJFrame *dst = yuv_yuv_template( Y,Cb,Cr,width,height, d->fmt ); yuv_convert_any_ac( src,dst, src->format,dst->format ); free(src); @@ -439,7 +426,7 @@ int vj_dv_decode_frame(vj_dv_decoder *d, uint8_t * input_buf, uint8_t * Y, yuy2toyv16( Y,Cb,Cr, d->dv_video, width ,height ); - if( yuv_use_auto_ccir_jpeg() && fmt == FMT_422F) { + if( yuv_use_auto_ccir_jpeg() && fmt == PIX_FMT_YUVJ422F) { yuv_scale_pixels_from_ycbcr( Y, 16.0f, 235.0f, width * height); yuv_scale_pixels_from_ycbcr( diff --git a/veejay-current/veejay-server/libel/vj-dv.h b/veejay-current/veejay-server/libel/vj-dv.h index 5dd4fa6e..364e0189 100644 --- a/veejay-current/veejay-server/libel/vj-dv.h +++ b/veejay-current/veejay-server/libel/vj-dv.h @@ -43,7 +43,7 @@ typedef struct vj_dv_decoder *vj_dv_decoder_init(int quality,int width, int height, int pixel_format); -vj_dv_encoder *vj_dv_init_encoder(void * el, int pixel_format); +vj_dv_encoder *vj_dv_init_encoder(VJFrame *frame, int pixel_format, int isPAL); void vj_dv_decoder_get_audio(vj_dv_decoder *d, uint8_t *audio_buf); diff --git a/veejay-current/veejay-server/libel/vj-el.c b/veejay-current/veejay-server/libel/vj-el.c index 47c1d50f..c8e4e5cd 100644 --- a/veejay-current/veejay-server/libel/vj-el.c +++ b/veejay-current/veejay-server/libel/vj-el.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ #include #include #include +#define RUP8(num)(((num)+8)&~8) #ifdef SUPPORT_READ_DV2 #include "rawdv.h" @@ -100,17 +102,17 @@ static struct { "jpeg", CODEC_ID_MJPEG }, { "jpeg", CODEC_ID_MJPEG }, { "mjpa", CODEC_ID_MJPEG }, - { "mjpb", CODEC_ID_MJPEG }, { "jfif", CODEC_ID_MJPEG }, { "jfif", CODEC_ID_MJPEG }, { "png", CODEC_ID_PNG }, { "mpng", CODEC_ID_PNG }, #if LIBAVCODEC_BUILD > 4680 - { "sp5x", CODEC_ID_SP5X }, /* sunplus motion jpeg video */ + { "sp5x", CODEC_ID_SP5X }, #endif { "jpgl", CODEC_ID_MJPEG }, { "jpgl", CODEC_ID_MJPEG }, { "dvsd", CODEC_ID_DVVIDEO }, + { "ijpg", CODEC_ID_MJPEG }, { "dvcp", CODEC_ID_DVVIDEO }, { "dv", CODEC_ID_DVVIDEO }, { "dvhd", CODEC_ID_DVVIDEO }, @@ -148,30 +150,13 @@ static struct { "png", CODEC_ID_PNG }, { "mpng", CODEC_ID_PNG }, #if LIBAVCODEC_BUILD > 4680 - { "sp5x", CODEC_ID_SP5X }, /* sunplus motion jpeg video */ + { "sp5x", CODEC_ID_SP5X }, #endif { "jpgl", CODEC_ID_MJPEG }, { "dvsd", CODEC_ID_DVVIDEO}, { "dv", CODEC_ID_DVVIDEO}, { "dvhd", CODEC_ID_DVVIDEO}, { "dvp", CODEC_ID_DVVIDEO}, -// { "mp4v", CODEC_ID_MPEG4 }, -// { "xvid", CODEC_ID_MPEG4 }, -// { "divx", CODEC_ID_MPEG4 }, -// { "dxsd", CODEC_ID_MPEG4 }, -// { "mp4s", CODEC_ID_MPEG4 }, -// { "m4s2", CODEC_ID_MPEG4 }, -// { "fmp4", CODEC_ID_MPEG4 }, -// { "fmp4", CODEC_ID_MPEG4 }, -// { "avc1", CODEC_ID_H264 }, -// { "h264", CODEC_ID_H264 }, -// { "x264", CODEC_ID_H264 }, -// { "davc", CODEC_ID_H264 }, -// { "div3", CODEC_ID_MSMPEG4V3 }, -// { "divx", CODEC_ID_MPEG4 }, -// { "mp43", CODEC_ID_MSMPEG4V3 }, -// { "mp42", CODEC_ID_MSMPEG4V2 }, -// { "mpg4", CODEC_ID_MSMPEG4V1 }, { "yuv", CODEC_ID_YUV420 }, { "iyuv", CODEC_ID_YUV420 }, { "i420", CODEC_ID_YUV420 }, @@ -212,15 +197,14 @@ static struct { { 0 , NULL} }; - typedef struct { - AVCodec *codec; - AVCodecContext *codec_ctx; - AVFormatContext *avformat_ctx; - AVPacket pkt; - int pixfmt; - int codec_id; + AVCodec *codec; + AVCodecContext *codec_ctx; + AVFormatContext *avformat_ctx; + AVPacket pkt; + int pixfmt; + int codec_id; } el_decoder_t; @@ -247,24 +231,9 @@ void vj_el_set_mmap_size( long size ) mmap_size = size; } -void free_av_packet( AVPacket *pkt ) -{ - if( pkt ) { -#if (LIBAVFORMAT_VERSION_MAJOR <= 53) - // av_destruct_packet(pkt); -#else - // if( pkt->destruct ) - // pkt->destruct(pkt); -#endif - pkt->data = NULL; - pkt->size = 0; - } - pkt = NULL; -} - typedef struct { - AVCodec *codec; // veejay supports only 2 yuv formats internally + AVCodec *codec; AVFrame *frame; AVCodecContext *context; uint8_t *tmp_buffer; @@ -278,36 +247,9 @@ typedef struct void *lzo_decoder; } vj_decoder; -static vj_decoder *el_codecs[MAX_CODECS]; - -static int _el_get_codec(int id, int in_pix_fmt ) -{ - int i; - for( i = 0; _supported_codecs[i].name != NULL ; i ++ ) - { - if( _supported_codecs[i].id == id) - { - return i; - } - } - return -1; -} -static int _el_get_codec_id( const char *fourcc ) -{ - int i; - int len = strlen( fourcc ); - for( i = 0; _supported_fourcc[i].name != NULL ; i ++ ) { - if( strncasecmp( fourcc, _supported_fourcc[i].name,len ) == 0 ) { - return _supported_fourcc[i].id; - } - } - veejay_msg(VEEJAY_MSG_DEBUG,"No decoder found for fourcc %s" , fourcc ); - return -1; -} - int vj_el_get_decoder_from_fourcc( const char *fourcc ) { - return _el_get_codec_id( fourcc ); + return avhelper_get_codec_by_name( fourcc ); } static void _el_free_decoder( vj_decoder *d ) @@ -318,16 +260,14 @@ static void _el_free_decoder( vj_decoder *d ) free( d->tmp_buffer ); if(d->deinterlace_buffer[0]) free(d->deinterlace_buffer[0]); - - /* if(d->context) - { - avcodec_close( d->context ); - av_free( d->context ); - d->context = NULL; - } */ - -// if(d->frame) -// free(d->frame); +#ifdef SUPPORT_READ_DV2 + if( d->dv_decoder ) { + vj_dv_free_decoder( d->dv_decoder ); + } +#endif + if(d->frame) { + av_free(d->frame); + } if(d->img) free(d->img); @@ -337,34 +277,6 @@ static void _el_free_decoder( vj_decoder *d ) d = NULL; } #define LARGE_NUM (256*256*256*64) -/* -static int get_buffer(AVCodecContext *context, AVFrame *av_frame){ - vj_decoder *this = (vj_decoder *)context->opaque; - int width = context->width; - int height = context->height; - VJFrame *img = this->img; - avcodec_align_dimensions(context, &width, &height); - - av_frame->opaque = img; - - av_frame->data[0]= img->data[0]; - av_frame->data[1]= img->data[1]; - av_frame->data[2]= img->data[2]; - - av_frame->linesize[0] = img->width; - av_frame->linesize[1] = img->uv_width; - av_frame->linesize[2] = img->uv_width; - - av_frame->age = LARGE_NUM; - - av_frame->type= FF_BUFFER_TYPE_USER; - - return 0; -} -static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){ - VJFrame *img = (VJFrame*)av_frame->opaque; - av_frame->opaque = NULL; -}*/ #if LIBAVCODEC_BUILD > 5400 static int avcodec_decode_video( AVCodecContext *avctx, AVFrame *picture, int *got_picture, uint8_t *data, int pktsize ) { @@ -376,8 +288,11 @@ static int avcodec_decode_video( AVCodecContext *avctx, AVFrame *picture, int *g } #endif - +static int el_pixel_format_org = 1; static int el_pixel_format_ = 1; +static int el_width_ = 0; +static float el_fps_ = 30; +static int el_height_ = 0; static long mem_chunk_ = 0; static int el_switch_jpeg_ = 0; @@ -397,10 +312,12 @@ static int require_same_resolution = 0; void vj_el_init(int pf, int switch_jpeg, int dw, int dh, float fps) { - int i; - for( i = 0; i < MAX_CODECS ;i ++ ) - el_codecs[i] = NULL; - el_pixel_format_ =pf; + el_pixel_format_org = pf; + el_pixel_format_ = get_ffmpeg_pixfmt( pf ); + el_width_ = dw; + el_height_ = dh; + el_fps_ = fps; + #ifdef STRICT_CHECKING assert( pf == FMT_422 || pf == FMT_422F ); #endif @@ -426,6 +343,8 @@ void vj_el_init(int pf, int switch_jpeg, int dw, int dh, float fps) require_same_resolution = 1; } + + veejay_msg(VEEJAY_MSG_DEBUG,"Initialized EDL, processing video in %d x %d", el_width_, el_height_ ); } int vj_el_is_dv(editlist *el) @@ -486,12 +405,6 @@ void vj_el_clear_cache( editlist *el ) void vj_el_deinit() { - int i; - for( i = 0; i < MAX_CODECS ;i ++ ) - { - if( el_codecs[i] ) - _el_free_decoder( el_codecs[i] ); - } } int vj_el_cache_size() @@ -499,6 +412,10 @@ int vj_el_cache_size() return cache_avail_mb(); } +#ifndef GREMLIN_GUARDIAN +#define GREMLIN_GUARDIAN (128*1024)-1 +#endif + vj_decoder *_el_new_decoder( void *ctx, int id , int width, int height, float fps, int pixel_format, int out_fmt, long max_frame_size) { vj_decoder *d = (vj_decoder*) vj_calloc(sizeof(vj_decoder)); @@ -507,7 +424,7 @@ vj_decoder *_el_new_decoder( void *ctx, int id , int width, int height, float fp #ifdef SUPPORT_READ_DV2 if( id == CODEC_ID_DVVIDEO ) - d->dv_decoder = vj_dv_decoder_init(1, width, height, pixel_format ); + d->dv_decoder = vj_dv_decoder_init(1, width, height, out_fmt ); #endif if( id == CODEC_ID_YUVLZO ) @@ -519,54 +436,30 @@ vj_decoder *_el_new_decoder( void *ctx, int id , int width, int height, float fp } else if( ctx ) { - el_decoder_t *x = (el_decoder_t*) ctx; - d->codec = x->codec; - d->context = x->codec_ctx; + d->codec = avhelper_get_codec(ctx); + d->context = avhelper_get_codec_ctx(ctx); d->frame = avcodec_alloc_frame(); d->img = (VJFrame*) vj_calloc(sizeof(VJFrame)); d->img->width = width; d->img->height = height; } - d->tmp_buffer = (uint8_t*) vj_malloc( sizeof(uint8_t) * max_frame_size ); + ssize_t safe_max_frame_size = (max_frame_size < GREMLIN_GUARDIAN) ? 128 * 1024: RUP8(max_frame_size); + d->tmp_buffer = (uint8_t*) vj_malloc( sizeof(uint8_t) * safe_max_frame_size ); d->fmt = id; - return d; + + return d; } -void vj_el_set_image_output_size(editlist *el, int dw, int dh, float fps, int pf) -{ -/* if( el->video_width <= 0 || el->video_height <= 0 ) - lav_set_project( dw,dh, fps, pf ); - else - lav_set_project( - el->video_width, el->video_height, el->video_fps , el_pixel_format_ ); -*/ -} -/* -static int _el_probe_for_pixel_fmt( lav_file_t *fd ) -{ -// int old = lav_video_cmodel( fd ); - - int new = test_video_frame( fd, el_pixel_format_ ); - - switch(new) - { - case FMT_422: - veejay_msg(VEEJAY_MSG_DEBUG,"\tPixel format: YUV Planar 4:2:2 [16-235][16-240]"); - break; - case FMT_422F: - veejay_msg(VEEJAY_MSG_DEBUG,"\tPixel format: YUV Planar 4:2:2 [JPEG full range]"); - break; - } - - return new; -}*/ - int get_ffmpeg_pixfmt( int pf ) { switch( pf ) { + case FMT_420: + return PIX_FMT_YUV420P; + case FMT_420F: + return PIX_FMT_YUVJ420P; case FMT_422: return PIX_FMT_YUV422P; case FMT_422F: @@ -597,167 +490,7 @@ static long get_max_frame_size( lav_file_t *fd ) return (((res)+8)&~8); } - -static void *detect_pixel_format_with_ffmpeg( const char *filename ) -{ - el_decoder_t *x = (el_decoder_t*) vj_calloc( sizeof( el_decoder_t )); - if(!x) { - return NULL; - } - - char errbuf[512]; -#if LIBAVCODEC_BUILD > 5400 - int err = avformat_open_input( &(x->avformat_ctx), filename, NULL, NULL ); -#else - int err = av_open_input_file( &(x->avformat_ctx),filename,NULL,0,NULL ); -#endif - - if(err < 0 ) { - av_strerror( err, errbuf, sizeof(errbuf)); - veejay_msg(VEEJAY_MSG_DEBUG, "%s: %s", filename,errbuf ); - free(x); - return NULL; - } - -#if LIBAVCODEC_BUILD > 5400 - err = avformat_find_stream_info( x->avformat_ctx, NULL ); -#else - err = av_find_stream_info( x->avformat_ctx ); -#endif - -#ifdef STRICT_CHECKING -#if (LIBAVFORMAT_VERSION_MAJOR <= 53) - av_dump_format( x->avformat_ctx,0,filename,0 ); -#endif -#endif - - if( err < 0 ) { - av_strerror( err, errbuf, sizeof(errbuf)); - veejay_msg(VEEJAY_MSG_DEBUG, "%s: %s" ,filename,errbuf ); - } - - if(err < 0 ) { - vj_el_av_close_input_file( x->avformat_ctx ); - free(x); - return NULL; - } - - unsigned int i,j; - unsigned int n = x->avformat_ctx->nb_streams; - int vi = -1; - veejay_msg(VEEJAY_MSG_DEBUG, "FFmpeg: File has %d %s", n, ( n == 1 ? "stream" : "streams") ); - - 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 ) - continue; - - if( x->avformat_ctx->streams[i]->codec->codec_type < CODEC_ID_FIRST_AUDIO ) - { - 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; - } - } -further: - if( !sup_codec ) { - vj_el_av_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 ) - { - vj_el_av_close_input_file( x->avformat_ctx ); - free(x); - return NULL; - } - vi = i; - - veejay_msg(VEEJAY_MSG_DEBUG, "FFmpeg: video stream %d, codec_id %d", vi, x->avformat_ctx->streams[i]->codec->codec_id); - - break; - } - } - - if( vi == -1 ) { - veejay_msg(VEEJAY_MSG_DEBUG, "FFmpeg: No video streams found"); - vj_el_av_close_input_file( x->avformat_ctx ); - free(x); - return NULL; - } - - x->codec_ctx = x->avformat_ctx->streams[vi]->codec; -#if LIBAVCODEC_BUILD > 5400 - if ( avcodec_open2( x->codec_ctx, x->codec, NULL ) < 0 ) -#else - if ( avcodec_open( x->codec_ctx, x->codec ) < 0 ) -#endif - { - free(x); - return NULL; - } - - veejay_memset( &(x->pkt), 0, sizeof(AVPacket)); - AVFrame *f = avcodec_alloc_frame(); - - int got_picture = 0; - while( (av_read_frame(x->avformat_ctx, &(x->pkt)) >= 0 ) ) { - avcodec_decode_video( x->codec_ctx,f,&got_picture, x->pkt.data, x->pkt.size ); - - if( got_picture ) { - break; - } - } - - if(!got_picture) { - veejay_msg(VEEJAY_MSG_ERROR, "FFmpeg: Unable to get whole picture from %s", filename ); - av_free(f); - free_av_packet(&(x->pkt)); - avcodec_close( x->codec_ctx ); - vj_el_av_close_input_file( x->avformat_ctx ); - free(x); - return NULL; - } - - x->pixfmt = x->codec_ctx->pix_fmt; - x->codec_id = x->codec_ctx->codec_id; - - veejay_msg(VEEJAY_MSG_DEBUG,"\tPixel format:\t%s", el_pixfmt_str( x->codec_ctx->pix_fmt ) ); - - free_av_packet(&(x->pkt)); - - av_free(f); - -/* - avcodec_close( codec_ctx ); - vj_el_av_close_input_file( avformat_ctx ); - av_free(f); -*/ - - return (void*) x; -} - -int vj_el_pixfmt_to_veejay(int pix_fmt ) { - int input_pix_fmt = -1; - switch( pix_fmt ) { - case PIX_FMT_YUV420P: input_pix_fmt = FMT_420; break; - case PIX_FMT_YUV422P: input_pix_fmt = FMT_422; break; - case PIX_FMT_YUVJ420P: input_pix_fmt = FMT_420F; break; - case PIX_FMT_YUVJ422P: input_pix_fmt = FMT_422F; break; - } - - return input_pix_fmt; -} - - - -int open_video_file(char *filename, editlist * el, int preserve_pathname, int deinter, int force, char override_norm) +int open_video_file(char *filename, editlist * el, int preserve_pathname, int deinter, int force, char override_norm, int out_format, int width, int height ) { int i, n, nerr; int chroma=0; @@ -805,10 +538,9 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de chroma = el->MJPG_chroma; n = el->num_video_files; - - el->ctx[n] = detect_pixel_format_with_ffmpeg( filename ); - + int pixfmt = -1; + lav_file_t *elfd = lav_open_input_file(filename,mmap_size ); el->lav_fd[n] = NULL; if (elfd == NULL) @@ -820,8 +552,13 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de } + el->ctx[n] = avhelper_get_decoder( filename, out_format, width, height ); + + + if( el->ctx[n] == NULL ) { - if( (pixfmt = test_video_frame( elfd, el_pixel_format_ )) == -1 ) { + pixfmt = test_video_frame( el, n, elfd, el_pixel_format_ ); + if( pixfmt == -1 ) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to determine video format" ); return -1; } @@ -859,37 +596,6 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de chroma = _fc; //FIXME } -// pix_fmt = _el_probe_for_pixel_fmt( elfd ); -#ifdef STRICT_CHECKING - //if( in_pixel_format >= 0 ) - // assert( pix_fmt == in_pixel_format ); -#endif - -/* if(pix_fmt < 0 && in_pixel_format < 0) - { - if(elfd) lav_close( elfd ); - if(realname) free(realname); - return -1; - } - - if( pix_fmt < 0 ) - { - veejay_msg(VEEJAY_MSG_WARNING, "(!) Using pixelformat detected by FFmpeg (fallback)"); - pix_fmt = in_pixel_format; - } */ - - /* - if(el_switch_jpeg_ ) { - switch(pix_fmt) { - case FMT_422F: pix_fmt=FMT_422; break; - case FMT_422: pix_fmt=FMT_422F;break; - } - }*/ - - if( el_switch_jpeg_ ) { - //FIXME: swap - } - el->lav_fd[n] = elfd; el->num_frames[n] = lav_video_frames(el->lav_fd[n]); el->video_file_list[n] = strndup(realname, strlen(realname)); @@ -941,20 +647,11 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de nerr = 0; if (n == 0) { /* First file determines parameters */ - if(el->is_empty) - { /* Dummy determines parameters */ - if(el->video_height != lav_video_height(el->lav_fd[n])) - nerr++; - if(el->video_width != lav_video_width(el->lav_fd[n])) - nerr++; - } - else - { - el->video_height = lav_video_height(el->lav_fd[n]); - el->video_width = lav_video_width(el->lav_fd[n]); - el->video_inter = lav_video_interlacing(el->lav_fd[n]); - el->video_fps = lav_frame_rate(el->lav_fd[n]); - } + el->video_height = lav_video_height(el->lav_fd[n]); + el->video_width = lav_video_width(el->lav_fd[n]); + el->video_inter = lav_video_interlacing(el->lav_fd[n]); + el->video_fps = lav_frame_rate(el->lav_fd[n]); + lav_video_clipaspect(el->lav_fd[n], &el->video_sar_width, &el->video_sar_height); @@ -974,8 +671,7 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de el->video_norm = override_norm; else { - veejay_msg(VEEJAY_MSG_ERROR, - "Invalid video norm - override with -N / --norm"); + veejay_msg(VEEJAY_MSG_ERROR, "Invalid video norm - override with -N / --norm"); nerr++; } } @@ -997,10 +693,14 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de else { if(lav_audio_channels(el->lav_fd[n]) != el->audio_chans || - lav_audio_rate(el->lav_fd[n]) != el->audio_rate || - lav_audio_bits(el->lav_fd[n]) != el->audio_bits ) + lav_audio_rate(el->lav_fd[n]) != el->audio_rate || + lav_audio_bits(el->lav_fd[n]) != el->audio_bits ) { + veejay_msg(VEEJAY_MSG_ERROR,"File %s has different audio properties - cant play that!"); + veejay_msg(VEEJAY_MSG_DEBUG,"Audio rate %ld, source is %ld", el->audio_rate, lav_audio_rate(el->lav_fd[n])); + veejay_msg(VEEJAY_MSG_DEBUG,"Audio bits %d, source is %d", el->audio_bits, lav_audio_bits(el->lav_fd[n])); + veejay_msg(VEEJAY_MSG_DEBUG,"Audio channels %d, source is %d", el->audio_chans, lav_audio_channels(el->lav_fd[n]) ); nerr++; - else + } else el->has_audio = 1; } } else { @@ -1025,20 +725,6 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de veejay_msg(VEEJAY_MSG_ERROR, "File %s: Interlacing is %d should be %d", filename, lav_video_interlacing(el->lav_fd[n]), el->video_inter); - - - if(!el->auto_deinter) - { - if(force) - { - veejay_msg(VEEJAY_MSG_WARNING, "(Force loading video) Auto deinterlacing enabled"); - el->auto_deinter = 1; - } - else - { - nerr++; - } - } } /* give a warning on different fps instead of error , this is better for live performances */ @@ -1069,8 +755,6 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de } - - if (nerr) { if(el->lav_fd[n]) lav_close( el->lav_fd[n] ); @@ -1097,15 +781,14 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de el->video_file_list[n] = NULL; return -1; } - // initialze a decoder if needed - decoder_id = _el_get_codec_id( compr_type ); - veejay_msg(VEEJAY_MSG_DEBUG, "\tCodec %d", decoder_id ); - if(decoder_id > 0 && decoder_id != 0xffff) - { - int c_i = _el_get_codec(decoder_id, el->pixfmt[n] ); - if(c_i == -1) - { - veejay_msg(VEEJAY_MSG_ERROR, "Unsupported codec %s",compr_type); + + if( el->decoders[n] == NULL ) { + long max_frame_size = get_max_frame_size( el->lav_fd[n] ); + decoder_id = avhelper_get_codec_by_name( compr_type ); + el->decoders[n] = + _el_new_decoder( el->ctx[n], decoder_id, el->video_width, el->video_height, el->video_fps, el->pixfmt[ n ],el_pixel_format_, max_frame_size ); + if( el->decoders[n] == NULL ) { + veejay_msg(VEEJAY_MSG_ERROR,"Unsupported video compression type: %s", compr_type ); if( el->lav_fd[n] ) lav_close( el->lav_fd[n] ); el->lav_fd[n] = NULL; @@ -1115,38 +798,6 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de el->video_file_list[n] = NULL; return -1; } - if( el_codecs[c_i] == NULL ) - { - long max_frame_size = get_max_frame_size( el->lav_fd[n] ); - int ff_pf = get_ffmpeg_pixfmt( el_pixel_format_ ); - el_codecs[c_i] = _el_new_decoder( el->ctx[n], decoder_id, el->video_width, el->video_height, el->video_fps, el->pixfmt[ n ],ff_pf, max_frame_size ); - if(!el_codecs[c_i]) - { - veejay_msg(VEEJAY_MSG_ERROR,"Cannot initialize %s codec", compr_type); - if( el->lav_fd[n] ) - lav_close( el->lav_fd[n] ); - el->lav_fd[n] = NULL; - if(realname) free(realname); - if( el->video_file_list[n]) - free(el->video_file_list[n]); - el->video_file_list[n] = NULL; - return -1; - } - - el->max_frame_sizes[n] = max_frame_size; - } - } - - if(decoder_id <= 0) - { - veejay_msg(VEEJAY_MSG_ERROR, "Cannot handle this file: %s", realname ); - if(realname) free(realname); - if( el->video_file_list[n]) free( el->video_file_list[n] ); - if( el->lav_fd[n] ) - lav_close( el->lav_fd[n]); - el->lav_fd[n] = NULL; - el->video_file_list[n] = NULL; - return -1; } if(realname) @@ -1157,10 +808,20 @@ int open_video_file(char *filename, editlist * el, int preserve_pathname, int de el->video_frames = el->num_frames[0]; el->video_frames -= DUMMY_FRAMES; } + el->is_empty = 0; el->has_video = 1; el->num_video_files ++; - return n; + + if( el_width_ == 0 && el_height_ == 0 ) { + el_width_ = el->video_width; + el_height_ = el->video_height; + el_fps_ = el->video_fps; + + veejay_msg(VEEJAY_MSG_WARNING, "Initialized video project settings from first file (%s)" , filename ); + } + + return n; } static int vj_el_dummy_frame( uint8_t *dst[3], editlist *el ,int pix_fmt) @@ -1238,14 +899,9 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) vj_el_dummy_frame( dst, el, el->pixel_format ); return 2; } - sws_template tmpl; - tmpl.flags = 1; int res = 0; uint64_t n; - int decoder_id =0; - int c_i = 0; - vj_decoder *d = NULL; int out_pix_fmt = el->pixel_format; int in_pix_fmt = out_pix_fmt; @@ -1266,20 +922,17 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) uint8_t *in_cache = NULL; if(el->cache) - in_cache = get_cached_frame( el->cache, nframe, &res, &decoder_id ); + in_cache = get_cached_frame( el->cache, nframe, &res, &in_pix_fmt ); + + + int decoder_id = lav_video_compressor_type( el->lav_fd[N_EL_FILE(n)] ); + - el_decoder_t *x = (el_decoder_t*) el->ctx[ N_EL_FILE(n) ]; - if( x != NULL ) { - decoder_id = x->codec_id; - } if(! in_cache ) { res = lav_set_video_position(el->lav_fd[N_EL_FILE(n)], N_EL_FRAME(n)); - if( decoder_id <= 0 ) { - decoder_id = lav_video_compressor_type( el->lav_fd[N_EL_FILE(n)] ); - } - if (res < 0) + if (res < 0) { veejay_msg(VEEJAY_MSG_ERROR,"Error setting video position: %s", lav_strerror()); @@ -1304,22 +957,10 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) return 1; } - c_i = _el_get_codec( decoder_id , in_pix_fmt); - if(c_i >= 0 && c_i < MAX_CODECS && el_codecs[c_i] != NULL) - d = el_codecs[c_i]; - else - { - veejay_msg(VEEJAY_MSG_ERROR, "Choked on decoder %x (%d), slot %d",decoder_id,decoder_id, c_i ); - return -1; - } + vj_decoder *d = (vj_decoder*) el->decoders[ N_EL_FILE(n) ]; if(!in_cache) { - if( d == NULL ) - { - veejay_msg(VEEJAY_MSG_ERROR, "Codec %x was not initialized", decoder_id); - return -1; - } if(lav_filetype( el->lav_fd[N_EL_FILE(n)] ) != 'x') { res = lav_read_frame(el->lav_fd[N_EL_FILE(n)], d->tmp_buffer); @@ -1341,9 +982,9 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) in[0] = data; in[1] = data+el_out_->len; in[2] = data+el_out_->len + (el_out_->len/4); - if( el_pixel_format_ == FMT_422F ) { + if( el_pixel_format_ == PIX_FMT_YUVJ422P ) { yuv_scale_pixels_from_ycbcr( in[0],16.0f,235.0f, el_out_->len ); - yuv_scale_pixels_from_ycbcr( in[1],16.0f,240.0f, el_out_->len/2); + yuv_scale_pixels_from_ycbcr( in[1],16.0f,240.0f, el_out_->len/4); } yuv420to422planar( in , dst, el->video_width,el->video_height ); return 1; @@ -1353,16 +994,16 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) in[0] = data; in[1] = data + el_out_->len; in[2] = data + el_out_->len+(el_out_->len/4); - if( el_pixel_format_ == FMT_422 ) { + if( el_pixel_format_ == PIX_FMT_YUV422P ) { yuv_scale_pixels_from_y( dst[0], el_out_->len ); - yuv_scale_pixels_from_uv( dst[1], el_out_->len/2); + yuv_scale_pixels_from_uv( dst[1], el_out_->len/4); } yuv420to422planar( in , dst, el->video_width,el->video_height ); return 1; break; case CODEC_ID_YUV422: vj_frame_copy( dataplanes,dst,strides ); - if( el_pixel_format_ == FMT_422F ) { + if( el_pixel_format_ == PIX_FMT_YUVJ422P ) { yuv_scale_pixels_from_ycbcr( dst[0],16.0f,235.0f, el_out_->len ); yuv_scale_pixels_from_ycbcr( dst[1],16.0f,240.0f, el_out_->len/2); } @@ -1370,22 +1011,13 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) break; case CODEC_ID_YUV422F: vj_frame_copy( dataplanes, dst, strides ); - if( el_pixel_format_ == FMT_422 ) { + if( el_pixel_format_ == PIX_FMT_YUV422P ) { yuv_scale_pixels_from_y( dst[0], el_out_->len ); yuv_scale_pixels_from_uv( dst[1], el_out_->len/2); } return 1; break; - case CODEC_ID_DVVIDEO: -#ifdef SUPPORT_READ_DV2 - return vj_dv_decode_frame( d->dv_decoder, data, dst[0], dst[1], dst[2], el->video_width,el->video_height, - out_pix_fmt); -#else - return 0; -#endif - break; case CODEC_ID_YUVLZO: - if( ( in_pix_fmt == PIX_FMT_YUVJ420P || in_pix_fmt == PIX_FMT_YUV420P ) ) { inter = lzo_decompress420into422(d->lzo_decoder, data,res,dst, el->video_width,el->video_height ); } @@ -1397,129 +1029,17 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[3]) break; default: - // inter = lav_video_interlacing(el->lav_fd[N_EL_FILE(n)]); - d->img->width = el->video_width; - d->img->uv_width = el->video_width >> 1; - d->img->data[0] = dst[0]; - d->img->data[1] = dst[1]; - d->img->data[2] = dst[2]; - - int decode_len = avcodec_decode_video( - d->context, - d->frame, - &got_picture, - data, - res - ); - if(!got_picture) - { - veejay_msg(0, "Cannot decode frame ,unable to get whole picture"); - return 0; - } - - if( decode_len <= 0 ) - { - veejay_msg(VEEJAY_MSG_ERROR, "Cannot decode frame"); - return 0; - } + return avhelper_decode_video( el->ctx[ N_EL_FILE(n) ], data, res, dst ); - int dst_fmt = get_ffmpeg_pixfmt( el_pixel_format_ ); - int src_fmt = d->context->pix_fmt; - if( el_switch_jpeg_ ) { - switch(src_fmt) { - case PIX_FMT_YUV420P:src_fmt=PIX_FMT_YUVJ420P; break; - case PIX_FMT_YUVJ420P:src_fmt=PIX_FMT_YUV420P; break; - case PIX_FMT_YUV422P:src_fmt=PIX_FMT_YUVJ422P; break; - case PIX_FMT_YUVJ422P:src_fmt=PIX_FMT_YUV422P; break; - } - } - - if(!d->frame->opaque) - { - if( el->auto_deinter && inter != LAV_NOT_INTERLACED) - { - if( d->deinterlace_buffer[0] == NULL ) { - d->deinterlace_buffer[0] = (uint8_t*) vj_malloc(sizeof(uint8_t) * el->video_width * el->video_height * 3); - if(!d->deinterlace_buffer[0]) { if(d) free(d); return 0; } - d->deinterlace_buffer[1] = d->deinterlace_buffer[0] + (el->video_width * el->video_height ); - d->deinterlace_buffer[2] = d->deinterlace_buffer[0] + (2 * el->video_width * el->video_height ); - } - AVPicture pict2; - veejay_memset(&pict2,0,sizeof(AVPicture)); - pict2.data[0] = d->deinterlace_buffer[0]; - pict2.data[1] = d->deinterlace_buffer[1]; - pict2.data[2] = d->deinterlace_buffer[2]; - pict2.linesize[1] = el->video_width >> 1; - pict2.linesize[2] = el->video_width >> 1; - pict2.linesize[0] = el->video_width; - - avpicture_deinterlace( - &pict2, - (const AVPicture*) d->frame, - src_fmt, - el->video_width, - el->video_height); - - VJFrame *src1 = yuv_yuv_template( d->deinterlace_buffer[0], - d->deinterlace_buffer[1], d->deinterlace_buffer[2], - d->frame->width, d->frame->height, - src_fmt ); - VJFrame *dst1 = yuv_yuv_template( dst[0],dst[1],dst[2], - el->video_width, el->video_height, - dst_fmt ); - el->scaler = - yuv_init_cached_swscaler( el->scaler, - src1, - dst1, - &tmpl, - yuv_sws_get_cpu_flags() ); - - - yuv_convert_any3( el->scaler, src1,d->frame->linesize,dst1,src1->format,dst1->format); - - free(src1); - free(dst1); - - } - else - { - VJFrame *src1 = yuv_yuv_template( d->frame->data[0], - d->frame->data[1], d->frame->data[2], - d->frame->width,d->frame->height, - src_fmt ); - VJFrame *dst1 = yuv_yuv_template( dst[0],dst[1],dst[2], - el->video_width,el->video_height, - dst_fmt ); - el->scaler = - yuv_init_cached_swscaler( el->scaler, - src1, - dst1, - &tmpl, - yuv_sws_get_cpu_flags() ); - - yuv_convert_any3( el->scaler, src1,d->frame->linesize,dst1,src1->format,dst1->format); - - free(src1); - free(dst1); - } - } - else - { - dst[0] = d->frame->data[0]; - dst[1] = d->frame->data[1]; - dst[2] = d->frame->data[2]; - } - return 1; break; } - veejay_msg(VEEJAY_MSG_ERROR, "Error decoding frame %ld", nframe); return 0; } -int test_video_frame( lav_file_t *lav,int out_pix_fmt) +int test_video_frame( editlist *el, int n, lav_file_t *lav,int out_pix_fmt) { int in_pix_fmt = 0; @@ -1560,7 +1080,7 @@ int test_video_frame( lav_file_t *lav,int out_pix_fmt) } long max_frame_size = get_max_frame_size( lav ); - vj_decoder *d = _el_new_decoder( + vj_decoder *d = _el_new_decoder( NULL, decoder_id, lav_video_width( lav), @@ -1575,6 +1095,8 @@ int test_video_frame( lav_file_t *lav,int out_pix_fmt) return -1; } + el->decoders[n] = (void*) d; + res = lav_read_frame( lav, d->tmp_buffer); if( res <= 0 ) @@ -1586,7 +1108,6 @@ int test_video_frame( lav_file_t *lav,int out_pix_fmt) int got_picture = 0; int ret = -1; - int len = 0; switch( decoder_id ) { case CODEC_ID_YUV420F: @@ -1623,29 +1144,6 @@ int test_video_frame( lav_file_t *lav,int out_pix_fmt) break; default: - - if( d->context == NULL ) { - veejay_msg(VEEJAY_MSG_ERROR, "Unable to decode whole picture"); - return -1; - } - - len = avcodec_decode_video( - d->context, - d->frame, - &got_picture, - d->tmp_buffer, - res - ); - - if(!got_picture || len <= 0 ) - { - veejay_msg(VEEJAY_MSG_ERROR, "Unable to get whole picture"); - ret = -1; - } - else - { - ret= d->context->pix_fmt; - } break; } @@ -1717,7 +1215,7 @@ int vj_el_init_420_frame(editlist *el, VJFrame *frame) frame->ssm = 0; frame->stride[0] = el->video_width; frame->stride[1] = frame->stride[2] = frame->stride[0]/2; - frame->format = get_ffmpeg_pixfmt(el_pixel_format_); + frame->format = el_pixel_format_; return 1; } @@ -1738,7 +1236,7 @@ int vj_el_init_422_frame(editlist *el, VJFrame *frame) frame->ssm = 0; frame->stride[0] = el->video_width; frame->stride[1] = frame->stride[2] = frame->stride[0]/2; - frame->format = get_ffmpeg_pixfmt( el_pixel_format_ ); + frame->format = el_pixel_format_; return 1; } @@ -1805,7 +1303,7 @@ editlist *vj_el_dummy(int flags, int deinterlace, int chroma, char norm, int wid el->total_frames = el->video_frames - 1; el->video_fps = fps; el->video_inter = LAV_NOT_INTERLACED; - + el->pixel_format = get_ffmpeg_pixfmt(fmt); /* output pixel format */ if( fmt == -1 ) el->pixel_format = el_pixel_format_; @@ -1823,19 +1321,41 @@ editlist *vj_el_dummy(int flags, int deinterlace, int chroma, char norm, int wid return el; } -editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int deinterlace, int force ,char norm , int fmt) +void vj_el_scan_video_file( char *filename, int *dw, int *dh, float *dfps ) +{ + void *tmp = avhelper_get_decoder( filename, PIX_FMT_YUVJ422P, -1, -1 ); + if( tmp ) { + AVCodecContext *c = avhelper_get_codec_ctx( tmp ); + *dw = c->width; + *dh = c->height; + *dfps = (float) c->time_base.den; + + veejay_msg(VEEJAY_MSG_DEBUG, "Using video settings from first loaded video %s: %dx%d@%2.2f", + filename,*dw,*dh,*dfps); + + avhelper_close_decoder(tmp); + } +} + + + +editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int deinterlace, int force,char norm , int out_format, int width, int height) { editlist *el = vj_calloc(sizeof(editlist)); FILE *fd; char line[1024]; - uint64_t index_list[MAX_EDIT_LIST_FILES]; + uint64_t index_list[MAX_EDIT_LIST_FILES]; int num_list_files; long i,nf=0; int n1=0; int n2=0; long nl=0; uint64_t n =0; + + int av_pixfmt = get_ffmpeg_pixfmt( out_format ); + veejay_memset(line,0,sizeof(line)); + if(!el) return NULL; el->has_video = 1; //assume we get it @@ -1930,7 +1450,7 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de line[n - 1] = 0; /* Get rid of \n at end */ index_list[i] = - open_video_file(line, el, flags, deinterlace,force,norm); + open_video_file(line, el, flags, deinterlace,force,norm, av_pixfmt, width, height); if(index_list[i]< 0) { @@ -1938,24 +1458,18 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de return NULL; } - /* el->frame_list = (uint64_t *) realloc(el->frame_list, - (el->video_frames + - el->num_frames[i]) * - sizeof(uint64_t)); + el->frame_list = (uint64_t *) realloc(el->frame_list, (el->video_frames + el->num_frames[n]) * sizeof(uint64_t)); if (el->frame_list==NULL) { veejay_msg(VEEJAY_MSG_ERROR, "Insufficient memory to allocate frame_list"); vj_el_free(el); return NULL; } - - long x = el->num_frames[i] + el->total_frames; - long j; - for (j = el->video_frames; j < x; j++) + + for (i = 0; i < el->num_frames[n]; i++) { - el->frame_list[el->video_frames] = EL_ENTRY(n, j); - el->video_frames++; - }*/ + el->frame_list[el->video_frames++] = EL_ENTRY(n, i); + } } @@ -2007,13 +1521,10 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de /* Not an edit list - should be a ordinary video file */ fclose(fd); - n = open_video_file(filename[nf], el, flags, deinterlace,force,norm); + n = open_video_file(filename[nf], el, flags, deinterlace,force,norm, av_pixfmt, width, height); if(n >= 0 ) { - el->frame_list = (uint64_t *) realloc(el->frame_list, - (el->video_frames + - el->num_frames[n]) * - sizeof(uint64_t)); + el->frame_list = (uint64_t *) realloc(el->frame_list, (el->video_frames + el->num_frames[n]) * sizeof(uint64_t)); if (el->frame_list==NULL) { veejay_msg(VEEJAY_MSG_ERROR, "Insufficient memory to allocate frame_list"); @@ -2066,7 +1577,7 @@ editlist *vj_el_init_with_args(char **filename, int num_files, int flags, int de el->max_frame_size = cur_max_frame_size; /* Pick a pixel format */ - el->pixel_format = el_pixel_format_; + el->pixel_format = el_pixel_format_org; el->total_frames = el->video_frames-1; /* Help for audio positioning */ @@ -2088,39 +1599,30 @@ void vj_el_free(editlist *el) return; int i; - if(el->is_clone) + for ( i = 0; i < el->num_video_files; i ++ ) { - for( i = 0; i < el->num_video_files; i ++ ) + if( el->video_file_list[i]) { + free(el->video_file_list[i]); + el->video_file_list[i] = NULL; + } + + if( el->is_clone ) + continue; + + if( el->ctx[i] ) { + avhelper_close_decoder( el->ctx[i] ); + } + if( el->decoders[i] ) { + _el_free_decoder( el->decoders[i] ); + } + if( el->lav_fd[i] ) { - if( el->video_file_list[i]) { - free(el->video_file_list[i] ); - el->video_file_list[i] = NULL; - } - } - } - else - { - for ( i = 0; i < el->num_video_files; i ++ ) - { - if( el->ctx[i] ) { - el_decoder_t *x = (el_decoder_t*) el->ctx[i]; - avcodec_close( x->codec_ctx ); - vj_el_av_close_input_file( x->avformat_ctx ); - av_free(x->codec_ctx); - free(x); - } - if( el->lav_fd[i] ) - { - lav_close( el->lav_fd[i] ); - el->lav_fd[i] = NULL; - } - if( el->video_file_list[i]) { - free(el->video_file_list[i]); - el->video_file_list[i] = NULL; - } + lav_close( el->lav_fd[i] ); + el->lav_fd[i] = NULL; } } + if( el->cache ) { free_cache( el->cache ); el->cache = NULL; @@ -2129,8 +1631,6 @@ void vj_el_free(editlist *el) free(el->frame_list ); el->frame_list = NULL; } - if( el->scaler ) - yuv_free_swscaler( el->scaler ); free(el); @@ -2290,7 +1790,7 @@ char *vj_el_write_line_ascii( editlist *el, int *bytes_written ) n1 = 0; - est_len = 64 + len; + est_len = 2 * len; #ifdef STRICT_CHECKING dbg_buflen = est_len; @@ -2312,11 +1812,7 @@ char *vj_el_write_line_ascii( editlist *el, int *bytes_written ) strlen(fourcc), fourcc ); -#ifdef STRICT_CHECKING - dbg_buflen -= strlen(filename); - assert( dbg_buflen > 0); -#endif - veejay_strncat ( result, filename, strlen(filename)); + strncat ( result, filename, strlen(filename)); } } @@ -2324,11 +1820,7 @@ char *vj_el_write_line_ascii( editlist *el, int *bytes_written ) char first[128]; char tmpbuf[128]; snprintf(first,sizeof(first), "%016" PRId64 "%016" PRId64 ,oldfile, oldframe); -#ifdef STRICT_CHECKING - dbg_buflen -= strlen(first); - assert( dbg_buflen > 0 ); -#endif - veejay_strncat( result, first, strlen(first) ); + strncat( result, first, strlen(first) ); for (j = n1+1; j <= n2; j++) { @@ -2340,19 +1832,15 @@ char *vj_el_write_line_ascii( editlist *el, int *bytes_written ) oldframe, index[N_EL_FILE(n)], N_EL_FRAME(n) ); -#ifdef STRICT_CHECKING - dbg_buflen -= strlen(tmpbuf); - assert( dbg_buflen > 0 ); -#endif strncat( result, tmpbuf, strlen(tmpbuf) ); } oldfile = index[N_EL_FILE(n)]; oldframe = N_EL_FRAME(n); } - char last_word[32]; + char last_word[64]; snprintf(last_word,sizeof(last_word),"%016" PRId64, oldframe); - veejay_strncat( result, last_word, strlen(last_word) ); + strncat( result, last_word, strlen(last_word) ); int datalen = strlen(result); *bytes_written = datalen; @@ -2492,6 +1980,8 @@ editlist *vj_el_soft_clone(editlist *el) clone->num_frames[i] = el->num_frames[i]; clone->pixfmt[i] =el->pixfmt[i]; } + clone->decoders[i] = el->decoders[i]; + clone->ctx[i] = el->ctx[i]; } return clone; @@ -2502,7 +1992,7 @@ int vj_el_framelist_clone( editlist *src, editlist *dst) if(!src || !dst) return 0; if(dst->frame_list) return 0; - dst->frame_list = (uint64_t*) vj_malloc(sizeof(uint64_t) * src->video_frames ); + dst->frame_list = (uint64_t*) vj_malloc(sizeof(uint64_t) * RUP8(src->video_frames) ); if(!dst->frame_list) return 0; diff --git a/veejay-current/veejay-server/libel/vj-el.h b/veejay-current/veejay-server/libel/vj-el.h index 53f377d8..d86977a9 100644 --- a/veejay-current/veejay-server/libel/vj-el.h +++ b/veejay-current/veejay-server/libel/vj-el.h @@ -60,7 +60,7 @@ typedef struct lav_file_t *(lav_fd[MAX_EDIT_LIST_FILES]); int pixfmt[MAX_EDIT_LIST_FILES]; void *ctx[MAX_EDIT_LIST_FILES]; - + void *decoders[MAX_EDIT_LIST_FILES]; long num_frames[MAX_EDIT_LIST_FILES]; long max_frame_sizes[MAX_EDIT_LIST_FILES]; uint64_t *frame_list; @@ -76,10 +76,11 @@ typedef struct void *scaler; } editlist; -int test_video_frame( lav_file_t *lav,int out_pix_fmt); +int test_video_frame(editlist *el, int n, lav_file_t *lav,int out_pix_fmt); +void vj_el_scan_video_file( char *filename, int *dw, int *dh, float *dfps ); -editlist *vj_el_init_with_args(char **filenames, int n, int flags, int deinter, int force, char norm, int fmt); +editlist *vj_el_init_with_args(char **filenames, int n, int flags, int deinter, int force, char norm, int fmt, int w, int h); int vj_el_cache_size(); @@ -138,9 +139,7 @@ void vj_el_clear_cache( editlist *el ); int get_ffmpeg_pixfmt( int pf ); -void vj_el_set_image_output_size(editlist *el,int w, int h, float fps, int pf); - -int open_video_file(char *filename, editlist * el, int preserve_pathname, int deinter, int force, char override_norm); +int open_video_file(char *filename, editlist * el, int preserve_pathname, int deinter, int force, char override_norm, int w, int h, int fmt); void vj_el_set_caching(int status); diff --git a/veejay-current/veejay-server/libsample/sampleadm.c b/veejay-current/veejay-server/libsample/sampleadm.c index 27d6ffc6..c5ce0370 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.c +++ b/veejay-current/veejay-server/libsample/sampleadm.c @@ -161,16 +161,21 @@ typedef struct int flags; int force; char norm; + int width; + int height; } sample_setting; static sample_setting __sample_project_settings; -void sample_set_project(int fmt, int deinterlace, int flags, int force, char norm ) +void sample_set_project(int fmt, int deinterlace, int flags, int force, char norm, int w, int h ) { __sample_project_settings.fmt = fmt; __sample_project_settings.deinterlace = deinterlace; __sample_project_settings.flags = flags; __sample_project_settings.force = force; __sample_project_settings.norm = norm; + __sample_project_settings.width = w; + __sample_project_settings.height = h; + } void *sample_get_dict( int sample_id ) { @@ -3216,7 +3221,9 @@ int sample_read_edl( sample_info *sample ) __sample_project_settings.deinterlace, __sample_project_settings.force, __sample_project_settings.norm, - __sample_project_settings.fmt ); + __sample_project_settings.fmt, + __sample_project_settings.width, + __sample_project_settings.height); if(sample->edit_list) { diff --git a/veejay-current/veejay-server/libsample/sampleadm.h b/veejay-current/veejay-server/libsample/sampleadm.h index 1416ed7f..ed3e80aa 100644 --- a/veejay-current/veejay-server/libsample/sampleadm.h +++ b/veejay-current/veejay-server/libsample/sampleadm.h @@ -331,7 +331,7 @@ extern void *sample_get_dict( int sample_id ); extern int sample_var( int s1, int *type, int *fader, int *fx, int *rec, int *active ); -extern void sample_set_project(int fmt, int deinterlace, int flags, int force, char norm ); +extern void sample_set_project(int fmt, int deinterlace, int flags, int force, char norm, int w, int h ); extern int sample_video_length( int s1 ); extern int sample_usable_edl( int s1 ); diff --git a/veejay-current/veejay-server/libsamplerec/samplerecord.c b/veejay-current/veejay-server/libsamplerec/samplerecord.c index e16aa85c..20eb2b45 100644 --- a/veejay-current/veejay-server/libsamplerec/samplerecord.c +++ b/veejay-current/veejay-server/libsamplerec/samplerecord.c @@ -124,7 +124,7 @@ int sample_try_filename(int sample_id, char *filename, int format) } -static int sample_start_encoder(sample_info *si, editlist *el, int format, long nframes) +static int sample_start_encoder(sample_info *si, VJFrame *frame, editlist *el, int format, long nframes) { char descr[100]; char cformat = vj_avcodec_find_lav( format ); @@ -134,7 +134,7 @@ static int sample_start_encoder(sample_info *si, editlist *el, int format, long int sample_id = si->sample_id; - si->encoder = vj_avcodec_start( el, format, si->encoder_destination ); + si->encoder = vj_avcodec_start( frame, format, si->encoder_destination ); if(!si->encoder) return -1; @@ -150,30 +150,29 @@ static int sample_start_encoder(sample_info *si, editlist *el, int format, long si->encoder_frames_recorded = 0; } - int tmp = el->video_width * el->video_height; - int tmp1 = (el->video_width/2 ) * el->video_height; + int tmp = frame->len; + int tmp1 = frame->uv_len; - if(format==ENCODER_DVVIDEO) - si->encoder_max_size = ( el->video_height == 480 ? 120000: 144000); - else - switch(format) - { - case ENCODER_YUV420: - case ENCODER_YUV420F: - si->encoder_max_size= 2048 + tmp + (tmp/4) + (tmp/4);break; - case ENCODER_YUV422: - case ENCODER_YUV422F: - case ENCODER_YUV4MPEG: - si->encoder_max_size = 2048 + tmp + tmp1 + tmp1;break; - case ENCODER_LZO: - si->encoder_max_size = (tmp * 3 ); break; - default: - si->encoder_max_size = 8 * ( 16 * 65535 ); - break; - } + switch(format) + { + case ENCODER_YUV420: + case ENCODER_YUV420F: + si->encoder_max_size= 2048 + tmp + (tmp/4) + (tmp/4);break; + case ENCODER_YUV422: + case ENCODER_YUV422F: + case ENCODER_YUV4MPEG: + si->encoder_max_size = 2048 + tmp + tmp1 + tmp1;break; + case ENCODER_LZO: + si->encoder_max_size = (tmp * 3 ); break; + case ENCODER_DVVIDEO: + si->encoder_max_size = ( frame->height == 480 ? 120000: 144000); break; + default: + si->encoder_max_size = 8 * ( 16 * 65535 ); + break; + } - si->encoder_width = el->video_width; - si->encoder_height = el->video_height; + si->encoder_width = frame->width; + si->encoder_height = frame->height; if( sufficient_space( si->encoder_max_size, nframes ) == 0 ) @@ -187,8 +186,7 @@ static int sample_start_encoder(sample_info *si, editlist *el, int format, long if( cformat != 'S' ) { si->encoder_file = (void*)lav_open_output_file(si->encoder_destination,cformat, - el->video_width,el->video_height,el->video_inter, - el->video_fps,el->audio_bits, el->audio_chans, el->audio_rate ); + frame->width,frame->height,0,frame->fps,el->audio_bits, el->audio_chans, el->audio_rate ); if(!si->encoder_file) { @@ -206,8 +204,7 @@ static int sample_start_encoder(sample_info *si, editlist *el, int format, long return 0; } -int sample_init_encoder(int sample_id, char *filename, int format, editlist *el, - long nframes) { +int sample_init_encoder(int sample_id, char *filename, int format, VJFrame *frame, editlist *el, long nframes) { sample_info *si; @@ -227,7 +224,7 @@ int sample_init_encoder(int sample_id, char *filename, int format, editlist *el, return -1; } if(nframes <= 0) return -1; - if(!el) return -1; + if(!el || !frame) return -1; if(si->encoder_active) { veejay_msg(VEEJAY_MSG_ERROR, "Sample is already encoding to [%s]", @@ -235,7 +232,7 @@ int sample_init_encoder(int sample_id, char *filename, int format, editlist *el, return -1; } - if (sample_start_encoder( si , el, format, nframes ) == 0) + if (sample_start_encoder( si , frame, el, format, nframes ) == 0) { return 1; } diff --git a/veejay-current/veejay-server/libsamplerec/samplerecord.h b/veejay-current/veejay-server/libsamplerec/samplerecord.h index 1d003f28..382b37ef 100644 --- a/veejay-current/veejay-server/libsamplerec/samplerecord.h +++ b/veejay-current/veejay-server/libsamplerec/samplerecord.h @@ -21,7 +21,7 @@ #include #include int sample_record_init(int len); -int sample_init_encoder(int sample_id, char *filename, int format, editlist *el,long nframes); +int sample_init_encoder(int sample_id, char *filename, int format, VJFrame *frame,editlist *el, long nframes); int sample_record_frame(int s1, uint8_t *buffer[3], uint8_t *abuff, int audio_size, int pixel_format); int sample_get_encoder_format(int s1); int sample_stop_encoder(int s1) ; diff --git a/veejay-current/veejay-server/libstream/vj-tag.c b/veejay-current/veejay-server/libstream/vj-tag.c index 3a4d138c..d2f6b1fe 100644 --- a/veejay-current/veejay-server/libstream/vj-tag.c +++ b/veejay-current/veejay-server/libstream/vj-tag.c @@ -76,7 +76,7 @@ static int video_driver_ = -1; // V4lUtils static int no_v4l2_threads_ = 0; int _vj_tag_new_net(vj_tag *tag, int stream_nr, int w, int h,int f, char *host, int port, int p, int ty ); -int _vj_tag_new_yuv4mpeg(vj_tag * tag, int stream_nr, editlist * el); +int _vj_tag_new_yuv4mpeg(vj_tag * tag, int stream_nr, int w, int h, float fps); extern void dummy_rgb_apply(VJFrame *frame, int width, int height, int r, int g, int b); extern int sufficient_space(int max_size, int nframes); @@ -425,10 +425,10 @@ int _vj_tag_new_unicap( vj_tag * tag, int stream_nr, int width, int height, int #elif HAVE_V4L2 if( no_v4l2_threads_ ) { vj_tag_input->unicap[stream_nr] = v4l2open( refname, channel, palette,width,height, - _tag_info->edit_list->video_fps,_tag_info->edit_list->video_norm ); + _tag_info->effect_frame1->fps,_tag_info->edit_list->video_norm ); } else { vj_tag_input->unicap[stream_nr] = v4l2_thread_new( refname, channel,palette,width,height, - _tag_info->edit_list->video_fps,_tag_info->edit_list->video_norm ); + _tag_info->effect_frame1->fps,_tag_info->edit_list->video_norm ); } if( !vj_tag_input->unicap[stream_nr] ) { veejay_msg(0, "Unable to open device %d (%s)",device_num, refname ); @@ -444,7 +444,7 @@ int _vj_tag_new_unicap( vj_tag * tag, int stream_nr, int width, int height, int } #ifdef USE_GDK_PIXBUF -int _vj_tag_new_picture( vj_tag *tag, int stream_nr, editlist *el) +int _vj_tag_new_picture( vj_tag *tag, int stream_nr, int width, int height, float fps) { int stop = 0; if(stream_nr < 0 || stream_nr > VJ_TAG_MAX_STREAM_IN) return 0; @@ -462,7 +462,7 @@ int _vj_tag_new_picture( vj_tag *tag, int stream_nr, editlist *el) veejay_msg(VEEJAY_MSG_INFO, "Opened [%s] , %d x %d @ %2.2f fps ", tag->source_name, - el->video_width, el->video_height, el->video_fps ); + width, height, fps ); return 1; } @@ -575,7 +575,7 @@ int vj_tag_cali_write_file( int t1, char *name, editlist *el ) { } -static int cali_read_file( cali_tag_t *p, char *file,editlist *el ) +static int cali_read_file( cali_tag_t *p, char *file,int w, int h ) { FILE *f = fopen( file , "r" ); if( f == NULL ) { @@ -585,8 +585,6 @@ static int cali_read_file( cali_tag_t *p, char *file,editlist *el ) char buf[256]; char *header = fgets( buf, sizeof(buf), f ); - int w = 0; - int h = 0; int len = 0; int uv_len = 0; int offset = 0; @@ -602,12 +600,6 @@ static int cali_read_file( cali_tag_t *p, char *file,editlist *el ) return 0; } - if( w != el->video_width || h != el->video_height ) { - veejay_msg(VEEJAY_MSG_ERROR, "Dimensions do not match, abort."); - fclose(f); - return 0; - } - if( len != (w*h)) { veejay_msg(VEEJAY_MSG_ERROR, "Invalid length for plane Y"); fclose(f); @@ -656,7 +648,7 @@ CALIREADERR: return 0; } -int _vj_tag_new_cali( vj_tag *tag, int stream_nr, editlist *el ) +int _vj_tag_new_cali( vj_tag *tag, int stream_nr, int w, int h ) { if(stream_nr < 0 || stream_nr > VJ_TAG_MAX_STREAM_IN) return 0; @@ -667,7 +659,7 @@ int _vj_tag_new_cali( vj_tag *tag, int stream_nr, editlist *el ) return 0; memset(p, 0, sizeof(cali_tag_t)); - if(!cali_read_file( p, tag->source_name,el ) ) { + if(!cali_read_file( p, tag->source_name,w,h ) ) { veejay_msg(VEEJAY_MSG_ERROR, "Failed to find dark frame '%s'", tag->source_name ); free(p); return 0; @@ -698,17 +690,16 @@ uint8_t *vj_tag_get_cali_data( int t1, int what ) { return NULL; } -int _vj_tag_new_yuv4mpeg(vj_tag * tag, int stream_nr, editlist * el) +int _vj_tag_new_yuv4mpeg(vj_tag * tag, int stream_nr, int w, int h, float fps) { if (stream_nr < 0 || stream_nr > VJ_TAG_MAX_STREAM_IN) return 0; - vj_tag_input->stream[stream_nr] = vj_yuv4mpeg_alloc(el,el->video_width,el->video_height, _tag_info->pixel_format); + vj_tag_input->stream[stream_nr] = vj_yuv4mpeg_alloc(w, h, fps, _tag_info->pixel_format); if(vj_tag_input->stream[stream_nr] == NULL) return 0; - if(vj_yuv_stream_start_read(vj_tag_input->stream[stream_nr],tag->source_name, - el->video_width, el->video_height) != 0) + if(vj_yuv_stream_start_read(vj_tag_input->stream[stream_nr],tag->source_name,w,h ) != 0 ) { veejay_msg(VEEJAY_MSG_ERROR,"Unable to read from %s",tag->source_name); vj_yuv4mpeg_free( vj_tag_input->stream[stream_nr] ); @@ -829,10 +820,12 @@ int vj_tag_new(int type, char *filename, int stream_nr, editlist * el, { int i, j; int palette; - int w = el->video_width; - int h = el->video_height; /* FIXME */ int id = 0; int n; + int w = _tag_info->effect_frame1->width; + int h = _tag_info->effect_frame1->height; + float fps = _tag_info->effect_frame1->fps; + char sourcename[255]; vj_tag *tag; @@ -983,18 +976,18 @@ int _vj_tag_new_unicap( vj_tag * tag, int stream_nr, int width, int height, int #ifdef USE_GDK_PIXBUF case VJ_TAG_TYPE_PICTURE: sprintf(tag->source_name, "%s", filename); - if( _vj_tag_new_picture(tag, stream_nr, el) != 1 ) + if( _vj_tag_new_picture(tag, stream_nr, w, h, fps) != 1 ) return -1; break; #endif case VJ_TAG_TYPE_CALI: sprintf(tag->source_name,"%s",filename); - if(_vj_tag_new_cali( tag,stream_nr,el) != 1 ) + if(_vj_tag_new_cali( tag,stream_nr,w,h) != 1 ) return -1; break; case VJ_TAG_TYPE_YUV4MPEG: sprintf(tag->source_name, "%s", filename); - if (_vj_tag_new_yuv4mpeg(tag, stream_nr, el) != 1) + if (_vj_tag_new_yuv4mpeg(tag, stream_nr, w,h,fps) != 1) { if(tag->source_name) free(tag->source_name); if(tag) free(tag); @@ -1659,7 +1652,7 @@ static int vj_tag_start_encoder(vj_tag *tag, int format, long nframes) char cformat = vj_avcodec_find_lav( format ); int sample_id = tag->id; - tag->encoder = vj_avcodec_start( _tag_info->edit_list , format, tag->encoder_destination ); + tag->encoder = vj_avcodec_start( _tag_info->effect_frame1, format, tag->encoder_destination ); if(!tag->encoder) { veejay_msg(0, "Unable to use selected encoder, please choose another."); @@ -1668,10 +1661,10 @@ static int vj_tag_start_encoder(vj_tag *tag, int format, long nframes) tag->encoder_active = 1; tag->encoder_format = format; - int tmp = _tag_info->edit_list->video_width * _tag_info->edit_list->video_height; + int tmp = _tag_info->effect_frame1->len; if(format==ENCODER_DVVIDEO) - tag->encoder_max_size = ( _tag_info->edit_list->video_height == 480 ? 120000: 144000); + tag->encoder_max_size = ( _tag_info->video_output_height == 480 ? 120000: 144000); else switch(format) { @@ -1711,10 +1704,10 @@ static int vj_tag_start_encoder(vj_tag *tag, int format, long nframes) tag->encoder_file = lav_open_output_file( tag->encoder_destination, cformat, - _tag_info->edit_list->video_width, - _tag_info->edit_list->video_height, - _tag_info->edit_list->video_inter, - _tag_info->edit_list->video_fps, + _tag_info->effect_frame1->width, + _tag_info->effect_frame1->height, + 0, + _tag_info->effect_frame1->fps, 0, 0, 0 @@ -1734,16 +1727,16 @@ static int vj_tag_start_encoder(vj_tag *tag, int format, long nframes) veejay_msg(VEEJAY_MSG_INFO, "Recording to file [%s] %ldx%ld@%2.2f %d/%d/%d >%09ld<", tag->encoder_destination, - _tag_info->edit_list->video_width, - _tag_info->edit_list->video_height, - (float) _tag_info->edit_list->video_fps, + _tag_info->effect_frame1->width, + _tag_info->effect_frame1->height, + (float) _tag_info->effect_frame1->fps, 0,0,0, (long)( tag->encoder_frames_to_record) ); - tag->encoder_width = _tag_info->edit_list->video_width; - tag->encoder_height = _tag_info->edit_list->video_height; + tag->encoder_width = _tag_info->effect_frame1->width; + tag->encoder_height = _tag_info->effect_frame1->height; return 1; } diff --git a/veejay-current/veejay-server/libstream/vj-vloopback.c b/veejay-current/veejay-server/libstream/vj-vloopback.c index 6a0ace08..4b700483 100644 --- a/veejay-current/veejay-server/libstream/vj-vloopback.c +++ b/veejay-current/veejay-server/libstream/vj-vloopback.c @@ -98,7 +98,7 @@ void *vj_vloopback_open(const char *device_name, int norm, int mode, v->fd = open( device_name, O_RDWR ); //, S_IRUSR|S_IWUSR ); if( v->fd <= 0 ) { - veejay_msg(VEEJAY_MSG_ERROR, "Cannot open vloopback device %s: %s", device_name, strerror(errno) ); + veejay_msg(VEEJAY_MSG_ERROR, "Cannot open vloopback device '%s': %s", device_name, strerror(errno) ); return ret; } diff --git a/veejay-current/veejay-server/libstream/vj-yuv4mpeg.c b/veejay-current/veejay-server/libstream/vj-yuv4mpeg.c index 86e70482..7f595eef 100644 --- a/veejay-current/veejay-server/libstream/vj-yuv4mpeg.c +++ b/veejay-current/veejay-server/libstream/vj-yuv4mpeg.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -33,39 +34,8 @@ #ifdef STRICT_CHECKING #include #endif -/* the audio routines are placed here - because its a feature i need. needs to be removed or put elsewhere. -*/ - -#define L_FOURCC(a,b,c,d) ( (d<<24) | ((c&0xff)<<16) | ((b&0xff)<<8) | (a&0xff) ) - -#define L_FOURCC_RIFF L_FOURCC ('R', 'I', 'F', 'F') -#define L_FOURCC_WAVE L_FOURCC ('W', 'A', 'V', 'E') -#define L_FOURCC_FMT L_FOURCC ('f', 'm', 't', ' ') -#define L_FOURCC_DATA L_FOURCC ('d', 'a', 't', 'a') - -typedef struct { - unsigned long rifftag; - unsigned long rifflen; - unsigned long wavetag; - unsigned long fmt_tag; - unsigned long fmt_len; - unsigned short wFormatTag; - unsigned short nChannels; - unsigned long nSamplesPerSec; - unsigned long nAvgBytesPerSec; - unsigned short nBlockAlign; - unsigned short wBitsPerSample; - unsigned long datatag; - unsigned long datalen; -} t_wave_hdr; - -t_wave_hdr *wave_hdr; - -int bytecount = 0; - -vj_yuv *vj_yuv4mpeg_alloc(editlist * el, int w, int h, int out_pixel_format) +vj_yuv *vj_yuv4mpeg_alloc(int w, int h, float fps, int out_pixel_format) { vj_yuv *yuv4mpeg = (vj_yuv *) vj_calloc(sizeof(vj_yuv)); if(!yuv4mpeg) return NULL; @@ -75,21 +45,16 @@ vj_yuv *vj_yuv4mpeg_alloc(editlist * el, int w, int h, int out_pixel_format) y4m_init_stream_info(&(yuv4mpeg->streaminfo)); y4m_init_frame_info(&(yuv4mpeg->frameinfo)); yuv4mpeg->width = w; + yuv4mpeg->format = vj_to_pixfmt(out_pixel_format); yuv4mpeg->height = h; - yuv4mpeg->audio_rate = el->audio_rate; - yuv4mpeg->video_fps = el->video_fps; - yuv4mpeg->has_audio = el->has_audio; - yuv4mpeg->audio_bits = el->audio_bps; - if( out_pixel_format == FMT_422F || out_pixel_format == FMT_420F ) { - yuv4mpeg->is_jpeg = 1; - } else { - yuv4mpeg->is_jpeg = 0; - } - yuv4mpeg->chroma = Y4M_CHROMA_422; //@ default + yuv4mpeg->video_fps = fps; + yuv4mpeg->is_jpeg = vj_is_full_range(out_pixel_format); + yuv4mpeg->chroma = get_chroma_from_pixfmt( yuv4mpeg->format ); yuv4mpeg->scaler = NULL; return yuv4mpeg; } + void vj_yuv4mpeg_free(vj_yuv *v) { if(v) { if( v->scaler ) { @@ -119,8 +84,7 @@ int vj_yuv_stream_start_read_fd( vj_yuv *yuv4mpeg, int fd, int width,int height return vj_yuv_stream_start_read1( yuv4mpeg,fd,width,height ); } -static int vj_yuv_stream_start_read1(vj_yuv * yuv4mpeg, int fd, int width, - int height) +static int vj_yuv_stream_start_read1(vj_yuv * yuv4mpeg, int fd, int width, int height) { int i, w, h; @@ -173,37 +137,33 @@ static int vj_yuv_stream_start_read1(vj_yuv * yuv4mpeg, int fd, int width, return 0; } + + + /* uint8_t *vj_yuv_get_buf( void *v ) { vj_yuv *y = (vj_yuv*)v; return y->buf; }*/ -int vj_yuv_stream_write_header(vj_yuv * yuv4mpeg, editlist * el, int out_chroma) +int vj_yuv_stream_write_header(vj_yuv * yuv4mpeg, VJFrame *frame, int out_chroma) { int i = 0; y4m_si_set_width(&(yuv4mpeg->streaminfo), yuv4mpeg->width); y4m_si_set_height(&(yuv4mpeg->streaminfo), yuv4mpeg->height); y4m_si_set_interlace(&(yuv4mpeg->streaminfo), Y4M_ILACE_NONE); y4m_si_set_chroma( &(yuv4mpeg->streaminfo), out_chroma ); - y4m_si_set_framerate(&(yuv4mpeg->streaminfo), - mpeg_conform_framerate(el->video_fps)); + y4m_si_set_framerate(&(yuv4mpeg->streaminfo), mpeg_conform_framerate(frame->fps)); - yuv4mpeg->chroma = out_chroma; -yuv4mpeg->buf[0] = vj_calloc(sizeof(uint8_t) * yuv4mpeg->width * yuv4mpeg->height * 4 ); - yuv4mpeg->buf[1] = yuv4mpeg->buf[0] + yuv4mpeg->width * yuv4mpeg->height; - yuv4mpeg->buf[2] = yuv4mpeg->buf[1] + yuv4mpeg->width * yuv4mpeg->height; - yuv4mpeg->buf[3] = yuv4mpeg->buf[2] + yuv4mpeg->width * yuv4mpeg->height; - if (!Y4M_RATIO_EQL(yuv4mpeg->sar, y4m_sar_UNKNOWN)) { - yuv4mpeg->sar.n = el->video_sar_width; - yuv4mpeg->sar.d = el->video_sar_height; - y4m_si_set_sampleaspect(&(yuv4mpeg->streaminfo), yuv4mpeg->sar); - } else { - y4m_ratio_t dar2 = y4m_guess_sar(yuv4mpeg->width, - yuv4mpeg->height, - yuv4mpeg->dar); - y4m_si_set_sampleaspect(&(yuv4mpeg->streaminfo), dar2); - } + yuv4mpeg->chroma = out_chroma; + yuv4mpeg->buf[0] = vj_calloc(sizeof(uint8_t) * yuv4mpeg->width * yuv4mpeg->height * 4 ); + yuv4mpeg->buf[1] = yuv4mpeg->buf[0] + yuv4mpeg->width * yuv4mpeg->height; + yuv4mpeg->buf[2] = yuv4mpeg->buf[1] + yuv4mpeg->width * yuv4mpeg->height; + yuv4mpeg->buf[3] = yuv4mpeg->buf[2] + yuv4mpeg->width * yuv4mpeg->height; + y4m_ratio_t dar2 = y4m_guess_sar(yuv4mpeg->width, + yuv4mpeg->height, + yuv4mpeg->dar); + y4m_si_set_sampleaspect(&(yuv4mpeg->streaminfo), dar2); i = y4m_write_stream_header(yuv4mpeg->fd, &(yuv4mpeg->streaminfo)); @@ -211,28 +171,35 @@ yuv4mpeg->buf[0] = vj_calloc(sizeof(uint8_t) * yuv4mpeg->width * yuv4mpeg->heigh if (i != Y4M_OK) return -1; + sws_template sws_tem; + veejay_memset(&sws_tem, 0,sizeof(sws_template)); + sws_tem.flags = yuv_which_scaler(); + + yuv4mpeg->dst = yuv_yuv_template( NULL,NULL,NULL, frame->width,frame->height, get_pixfmt_from_chroma(out_chroma)); + + yuv4mpeg->scaler = yuv_init_swscaler( frame, yuv4mpeg->dst, &sws_tem, yuv_sws_get_cpu_flags()); + + yuv4mpeg->dst->data[0] = yuv4mpeg->buf[0]; + yuv4mpeg->dst->data[1] = yuv4mpeg->buf[1]; + yuv4mpeg->dst->data[2] = yuv4mpeg->buf[2]; + return 0; } -int vj_yuv_stream_open_pipe(vj_yuv *yuv4mpeg, char *filename,editlist *el) +int vj_yuv_stream_open_pipe(vj_yuv *yuv4mpeg, char *filename) { yuv4mpeg->fd = open(filename,O_WRONLY,0600); if(!yuv4mpeg->fd) return 0; return 1; } -int vj_yuv_stream_header_pipe(vj_yuv *yuv4mpeg,editlist *el) +int vj_yuv_stream_header_pipe(vj_yuv *yuv4mpeg,VJFrame *frame) { - yuv4mpeg->has_audio = el->has_audio; - vj_yuv_stream_write_header(yuv4mpeg, el,FMT_420); + vj_yuv_stream_write_header(yuv4mpeg, frame, get_chroma_from_pixfmt(frame->format) ); - //if (el->has_audio) { -// if (!vj_yuv_write_wave_header(el, filename)) -// return 0; - // } return 1; } -int vj_yuv_stream_start_write(vj_yuv * yuv4mpeg,editlist *el, char *filename, int outchroma) +int vj_yuv_stream_start_write(vj_yuv * yuv4mpeg,VJFrame *frame, char *filename, int outchroma) { #ifdef STRICT_CHECKING assert( filename != NULL ); @@ -287,12 +254,12 @@ int vj_yuv_stream_start_write(vj_yuv * yuv4mpeg,editlist *el, char *filename, in } - if( vj_yuv_stream_write_header(yuv4mpeg, el, outchroma) < 0 ) { + if( vj_yuv_stream_write_header(yuv4mpeg, frame, outchroma) < 0 ) { veejay_msg(VEEJAY_MSG_ERROR, "Error while writing y4m header."); return -1; } - yuv4mpeg->has_audio = el->has_audio; + yuv4mpeg->has_audio = 0; return 0; } @@ -302,6 +269,11 @@ void vj_yuv_stream_stop_write(vj_yuv * yuv4mpeg) y4m_fini_stream_info(&(yuv4mpeg->streaminfo)); y4m_fini_frame_info(&(yuv4mpeg->frameinfo)); close(yuv4mpeg->fd); + + if( yuv4mpeg->scaler ) { + yuv_free_swscaler( yuv4mpeg->scaler ); + yuv4mpeg->scaler = NULL; + } } void vj_yuv_stream_stop_read(vj_yuv * yuv4mpeg) @@ -402,30 +374,11 @@ int vj_yuv_get_frame(vj_yuv * yuv4mpeg, uint8_t *dst[3]) } } - int src_fmt; - switch( yuv4mpeg->chroma ) { - case Y4M_CHROMA_420JPEG: - src_fmt = PIX_FMT_YUVJ420P; break; - case Y4M_CHROMA_420MPEG2: - case Y4M_CHROMA_420PALDV: - src_fmt = PIX_FMT_YUV420P; break; - case Y4M_CHROMA_422: - src_fmt = PIX_FMT_YUV422P; break; - case Y4M_CHROMA_444: - src_fmt = PIX_FMT_YUV444P; break; - case Y4M_CHROMA_411: - src_fmt = PIX_FMT_YUV411P; break; - case Y4M_CHROMA_MONO: - src_fmt = PIX_FMT_GRAY8; break; - default: - veejay_msg(0, "Can't handle chroma '%s'", y4m_chroma_keyword( yuv4mpeg->chroma )); - return -1; - break; - } - + int src_fmt = get_pixfmt_from_chroma( yuv4mpeg->chroma ); + VJFrame *srcf = yuv_yuv_template( yuv4mpeg->buf[0], yuv4mpeg->buf[1], yuv4mpeg->buf[2],yuv4mpeg->width,yuv4mpeg->height, src_fmt ); - VJFrame *dstf = yuv_yuv_template( dst[0],dst[1],dst[2], yuv4mpeg->width,yuv4mpeg->height, PIX_FMT_YUV422P ); + VJFrame *dstf = yuv_yuv_template( dst[0],dst[1],dst[2], yuv4mpeg->width,yuv4mpeg->height, yuv4mpeg->format ); if(!yuv4mpeg->scaler) { sws_template sws_tem; @@ -439,61 +392,42 @@ int vj_yuv_get_frame(vj_yuv * yuv4mpeg, uint8_t *dst[3]) } yuv_convert_and_scale( yuv4mpeg->scaler, srcf, dstf ); - free(srcf); free(dstf); - if (yuv4mpeg->is_jpeg == 1 ) { - yuv_scale_pixels_from_ycbcr( dst[0], 16.0f, 235.0f, yuv4mpeg->width * yuv4mpeg->height ); - yuv_scale_pixels_from_ycbcr( dst[1], 16.0f, 240.0f, (yuv4mpeg->width * yuv4mpeg->height) / 2 ); - } return 0; } return -1; } -int vj_yuv_get_aframe(vj_yuv * yuv4mpeg, uint8_t * audio) -{ - return 0; /*un used */ - -} int vj_yuv_put_frame(vj_yuv * vjyuv, uint8_t ** src) { - int i; - if (!vjyuv->fd) { + int i; + if (!vjyuv->fd) { veejay_msg(VEEJAY_MSG_ERROR, "Invalid file descriptor for y4m stream"); return -1; } -//@ assumes caller responsibility for jpeg/ccir: see vj-avcodec.c - if( vjyuv->chroma == Y4M_CHROMA_422 ) { - i = y4m_write_frame(vjyuv->fd, &(vjyuv->streaminfo),&(vjyuv->frameinfo), src); - if (i != Y4M_OK) { - veejay_msg(VEEJAY_MSG_ERROR, "yuv4mpeg: %s", y4m_strerr(i)); - return -1; - } - - return 0; - } - else { - if( vjyuv->chroma == Y4M_CHROMA_420JPEG || vjyuv->chroma == Y4M_CHROMA_420MPEG2 ) { - uint8_t *frame[3] = { src[0], vjyuv->buf[1], vjyuv->buf[2] }; - yuv422to420planar( src, vjyuv->buf, vjyuv->width, vjyuv->height ); - i = y4m_write_frame(vjyuv->fd, &(vjyuv->streaminfo),&(vjyuv->frameinfo),frame); - if (i != Y4M_OK) { - veejay_msg(VEEJAY_MSG_ERROR, "yuv4mpeg: %s", y4m_strerr(i)); - return -1; - } - return 0; - } + + if( vjyuv->scaler ) { + VJFrame *srcf = yuv_yuv_template( src[0], src[1], src[2],vjyuv->width,vjyuv->height,vjyuv->format); + + yuv_convert_and_scale( vjyuv->scaler, srcf, vjyuv->dst ); + i = y4m_write_frame(vjyuv->fd, &(vjyuv->streaminfo),&(vjyuv->frameinfo), vjyuv->dst->data); + + free(srcf); + } else { + i = y4m_write_frame(vjyuv->fd, &(vjyuv->streaminfo),&(vjyuv->frameinfo), src ); } - return -1; -} -int vj_yuv_put_aframe(uint8_t * audio, editlist * el, int len) -{ - int i = 0; - return i; + + + if (i != Y4M_OK) { + veejay_msg(VEEJAY_MSG_ERROR, "yuv4mpeg: %s", y4m_strerr(i)); + return -1; + } + + return 0; } diff --git a/veejay-current/veejay-server/libstream/vj-yuv4mpeg.h b/veejay-current/veejay-server/libstream/vj-yuv4mpeg.h index 41c9f56c..da1e9bcd 100644 --- a/veejay-current/veejay-server/libstream/vj-yuv4mpeg.h +++ b/veejay-current/veejay-server/libstream/vj-yuv4mpeg.h @@ -18,7 +18,6 @@ */ #ifndef VJ_YUV4MPEG_H #define VJ_YUV4MPEG_H -#include #include typedef struct { @@ -35,14 +34,16 @@ typedef struct { int fd; int has_audio; int audio_bits; + int format; float video_fps; long audio_rate; void *scaler; uint8_t *buf[4]; int is_jpeg; + VJFrame *dst; } vj_yuv; -vj_yuv *vj_yuv4mpeg_alloc(editlist * el, int dst_w, int dst_h, int out_pix_fmt); +vj_yuv *vj_yuv4mpeg_alloc(int dst_w, int dst_h,float fps, int out_pix_fmt); uint8_t *vj_yuv_get_buf( void *v ); @@ -53,9 +54,9 @@ int vj_yuv_stream_start_read_fd( vj_yuv *, int fd, int width,int height ); int vj_yuv_stream_start_read(vj_yuv *, char *, int width, int height); -int vj_yuv_stream_write_header(vj_yuv * yuv4mpeg, editlist * el, int outchroma); +int vj_yuv_stream_write_header(vj_yuv * yuv4mpeg, VJFrame *frame, int outchroma); -int vj_yuv_stream_start_write(vj_yuv *,editlist *, char *, int); +int vj_yuv_stream_start_write(vj_yuv *, VJFrame *frame, char *, int); void vj_yuv_stream_stop_read(vj_yuv * yuv4mpeg); @@ -67,11 +68,9 @@ int vj_yuv_put_frame(vj_yuv * vjyuv, uint8_t **); int vj_yuv_get_aframe(vj_yuv * vjyuv, uint8_t * audio); -int vj_yuv_put_aframe(uint8_t * audio, editlist *el, int len); +int vj_yuv_write_wave_header(VJFrame *frame, char *outfile); -int vj_yuv_write_wave_header(editlist * el, char *outfile); +int vj_yuv_stream_open_pipe(vj_yuv *, char *); -int vj_yuv_stream_open_pipe(vj_yuv *, char *, editlist *el); - -int vj_yuv_stream_header_pipe( vj_yuv *, editlist *el ); +int vj_yuv_stream_header_pipe( vj_yuv *, VJFrame *frame); #endif diff --git a/veejay-current/veejay-server/libsubsample/subsample.c b/veejay-current/veejay-server/libsubsample/subsample.c index e1b16eec..1f9c9eff 100644 --- a/veejay-current/veejay-server/libsubsample/subsample.c +++ b/veejay-current/veejay-server/libsubsample/subsample.c @@ -733,8 +733,8 @@ void chroma_supersample(subsample_mode_t mode,VJFrame *frame, uint8_t *ycbcr[] ) tr_422_to_444(ycbcr[2],frame->width,frame->height); break; case SSM_420_422: - ss_420_to_422( ycbcr[1], frame->width, frame->height ); - ss_420_to_422( ycbcr[2], frame->width, frame->height ); + ss_420_to_422( ycbcr[1], frame->width, frame->height ); + ss_420_to_422( ycbcr[2], frame->width, frame->height ); break; default: break; diff --git a/veejay-current/veejay-server/libvje/Makefile.am b/veejay-current/veejay-server/libvje/Makefile.am index 6826eae5..b1f35103 100644 --- a/veejay-current/veejay-server/libvje/Makefile.am +++ b/veejay-current/veejay-server/libvje/Makefile.am @@ -27,7 +27,7 @@ EXTRA_DIST += effects/autoeq.h effects/crosspixel.h effects/mask.h effects/rawva effects/chromium.h effects/flare.h effects/noiseadd.h effects/solarize.h \ effects/colflash.h effects/flip.h effects/noisepencil.h effects/split.h \ effects/colmorphology.h effects/frameborder.h effects/opacityadv.h effects/swirl.h \ - effects/coloradjust.h effects/gamma.h effects/opacity.h effects/iris.h effects/texmap.h \ + effects/coloradjust.h effects/gamma.h effects/opacity.h effects/iris.h \ effects/color.h effects/ghost.h effects/opacitythreshold.h effects/threshold.h \ effects/colorhis.h effects/greyselect.h effects/overclock.h effects/timedistort.h \ effects/colormap.h effects/isolate.h effects/pencilsketch.h effects/tracer.h \ @@ -85,7 +85,7 @@ libvje_la_SOURCES = vj-effect.c vj-effman.c effects/common.c \ effects/ghost.c effects/blob.c effects/radcor.c effects/boids.c effects/nervous.c \ effects/cartonize.c effects/tripplicity.c effects/neighbours.c effects/neighbours2.c\ effects/neighbours3.c effects/neighbours4.c effects/neighbours5.c effects/cutstop.c\ - effects/contourextract.c effects/texmap.c effects/maskstop.c effects/photoplay.c effects/videoplay.c effects/rgbchannel.c \ + effects/contourextract.c effects/maskstop.c effects/photoplay.c effects/videoplay.c effects/rgbchannel.c \ effects/videowall.c effects/flare.c effects/radioactive.c effects/baltantv.c effects/constantblend.c effects/picinpic.c effects/bgsubtract.c effects/cali.c effects/median.c effects/average-blend.c diff --git a/veejay-current/veejay-server/libvje/effects/chameleon.c b/veejay-current/veejay-server/libvje/effects/chameleon.c index c990383d..75f2f36d 100644 --- a/veejay-current/veejay-server/libvje/effects/chameleon.c +++ b/veejay-current/veejay-server/libvje/effects/chameleon.c @@ -67,11 +67,9 @@ static uint8_t *bgimage[3] = { NULL,NULL,NULL}; int chameleon_prepare( uint8_t *map[3], int width, int height ) { if(!bgimage[0]) { - veejay_msg(VEEJAY_MSG_WARNING, "Take a backdrop snapshot!"); return 0; } - //@ copy the iamge int strides[4] = { width * height, width * height, width * height, 0 }; vj_frame_copy( map, bgimage, strides ); @@ -122,6 +120,8 @@ void chameleon_free() for( i = 0; i < 3; i ++ ) { free(bgimage[i]); free(tmpimage[i]); + bgimage[i] = NULL; + tmpimage[i] = NULL; } free(timebuffer); free(sum); diff --git a/veejay-current/veejay-server/libvje/effects/checker.c b/veejay-current/veejay-server/libvje/effects/checker.c deleted file mode 100644 index 100a31ca..00000000 --- a/veejay-current/veejay-server/libvje/effects/checker.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Linux VeeJay - * - * Copyright(C)2007 Niels Elburg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License , or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 , USA. - - */ -#include -#include -#include -#include -#include "motionmap.h" -#include "common.h" -#include "softblur.h" -#include "opacity.h" - -#define HIS_DEFAULT 2 -#define HIS_LEN (8*25) -#define ACT_TOP 4000 -#define MAXCAPBUF 55 - -typedef struct { - int p; - int t; -} boxes_t; - -vj_effect *motionmap_init(int w, int h) -{ - vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect)); - ve->num_params = 3; - - ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */ - ve->limits[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */ - ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */ - ve->limits[0][0] = 0; // motionmap - ve->limits[1][0] = 255; - ve->limits[0][1] = 50; // reverse - ve->limits[1][1] = 10000; - ve->limits[0][2] = 0; - ve->limits[1][2] = 60*25; - /* ve->limits[0][4] = 0; // buffer - ve->limits[1][4] = 255; - ve->limits[0][3] = HIS_DEFAULT; - ve->limits[1][3] = HIS_LEN; */ - ve->defaults[0] = 40; - ve->defaults[1] = ACT_TOP; - ve->defaults[2] = 1; - /* ve->defaults[3] = HIS_DEFAULT; - ve->defaults[4] = 0; */ - ve->description = "Motion Mapping"; - ve->sub_format = 1; - ve->extra_frame = 0; - ve->has_user = 0; - ve->n_out = 2; - ve->param_description = vje_build_param_list( ve->num_params, "Threshold", "Min weight", "Decay" ); - return ve; -} - -static uint8_t *binary_img = NULL; -static uint8_t *original_img = NULL; -static uint8_t *previous_img = NULL; -static uint8_t *large_buf = NULL; -static uint32_t key1_ = 0, key2_ = 0, keyv_ = 0, keyp_ = 0; -static int have_bg = 0; -static int running = 0; -static boxes_t *boxes = NULL; - -int motionmap_prepare( uint8_t *map[3], int w, int h ) -{ - if(!previous_img) - return 0; - vj_frame_copy( map, previous_img, w*h ); - have_bg = 1; - nframe_ = 0; - running = 0; - veejay_msg(2, "Motion Mapping: Snapped background frame"); - return 1; -} - -int motionmap_malloc(int w, int h ) -{ - binary_img = (uint8_t*) vj_malloc(sizeof(uint8_t) * RUP8(w * h * 3) ); - original_img = binary_img + RUP8(w*h); - previous_img = original_img + RUP8(w*h); - large_buf = vj_malloc(sizeof(uint8_t) * RUP8(w*h*3) * (MAXCAPBUF+1)); - if(!large_buf) - { - veejay_msg(0, "Memory allocation error for Motion Mapping. Too large: %ld bytes",(long) ((RUP8(w*h*3)*(MAXCAPBUF+1)))); - return 0; - } - nframe_ = 0; - boxes = (boxes_t*) vj_malloc(sizeof(boxes_t) * 64 * 64 ); - int i ; - for ( i = 0;i < 64*64; i ++ ) { - boxes[i].p = 0; - boxes[i].t = 0; - } - return 1; -} - -void motionmap_free(void) -{ - if(binary_img) - free(binary_img); - if(large_buf) - free(large_buf); - have_bg = 0; - nframe_ = 0; - running = 0; - binary_img = NULL; -} - -#ifndef MIN -#define MIN(a,b) ( (a)>(b) ? (b) : (a) ) -#endif -#ifndef MAX -#define MAX(a,b) ( (a)>(b) ? (a) : (b) ) -#endif - -static void update_bgmask( uint8_t *dst,uint8_t *in, uint8_t *src, int len, int threshold ) -{ - int i; - unsigned int op0,op1; - for( i =0; i < len ; i ++ ) - { - if( abs(in[i] - src[i]) > threshold ) - { - dst[i] = 1; - in[i] = (in[i] + src[i])>>1; - } - else - { - dst[i] = 0; - } - } -} - - -static void put_photo( uint8_t *dst_plane, uint8_t *src_plane, int dst_w, int dst_h, int index , matrix_t matrix, - int box_w, int box_h) -{ - int x,y; - uint8_t *P = dst_plane + (matrix.h*dst_w); - uint8_t *Q = src_plane + (matrix.h*dst_w); - int offset = matrix.w; - - for( y = 0; y < box_h; y ++ ) - { - for( x = 0; x < box_w; x ++ ) - { - *(P+offset+x) = *(Q+offset+x); - } - P += dst_w; - Q += dst_w; - } -} - -void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int param1, int param2 ) -{ - unsigned int i,x,y; - int len = (width * height); - uint8_t *Y = frame->data[0]; - uint8_t *Cb = frame->data[1]; - uint8_t *Cr = frame->data[2]; - int w = frame->width; - int h = frame->height; - - vj_frame_copy1( frame->data[0], original_img, len ); - -// softblur_apply( frame, width,height,0 ); - if(!have_bg) - { - vj_frame_copy1( frame->data[0], previous_img, len ); - have_bg = 1; - nframe_ = 0; - running = 0; - return; - } - else - { - update_bgmask( binary_img, previous_img, frame->data[0], len , threshold); - } - - int x,y,dx,dy; - int sum; - int dst_x, dst_y; - int step_y; - int step_x; - int box_width = photo_list[index]->w; - int box_height = photo_list[index]->h; - int it = 0; - uint8_t *plane = binary_img; - - matrix_f matrix_placement = get_matrix_func(mode); - - - step_x = w / box_width; - step_y = h / box_height; - - for( y = 0 ; y < h ; y += step_y ) - { - for( x = 0; x < w ; x+= step_x ) - { - sum = 0; - for( dy = 0; dy < step_y; dy ++ ) - { - for( dx = 0; dx < step_x; dx++) - { - sum += plane[ ((y+dy)*w+(dx+x)) ]; - } - } - } - - boxes[ it ].p = sum; - it ++; - sum = 0; - } - - - for( y = 0 ; y < it ; y ++ ) - { - if(boxes[it].p > param1) //@ sufficient motion - { - if( boxes[it].t < 5 ) //@ update timer - boxes[it].t = param2; //@ Time stop - - } - if( boxes[it].t > 0 ) - boxes[it].t --; - if( boxes[it].t == 0 ) { - boxes[it].p = 0; - } - } - for ( i = 0; i < num_photos; i ++ ) - { - matrix_t m = matrix_placement(i, size,width,height ); - put_photo( dstY, photo_list[i]->data[0],width,height,i, m); - put_photo( dstU, photo_list[i]->data[1],width,height,i, m); - put_photo( dstV, photo_list[i]->data[2],width,height,i, m); - } - - - -} diff --git a/veejay-current/veejay-server/libvje/effects/motionmap.c b/veejay-current/veejay-server/libvje/effects/motionmap.c index d410fe2c..7808805a 100644 --- a/veejay-current/veejay-server/libvje/effects/motionmap.c +++ b/veejay-current/veejay-server/libvje/effects/motionmap.c @@ -138,6 +138,7 @@ void motionmap_free(void) keyv_ = 0; keyp_ = 0; binary_img = NULL; + previous_img = NULL; } #ifndef MIN diff --git a/veejay-current/veejay-server/libvje/effects/texmap.c b/veejay-current/veejay-server/libvje/effects/texmap.c deleted file mode 100644 index 56c11ad1..00000000 --- a/veejay-current/veejay-server/libvje/effects/texmap.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Linux VeeJay - * - * Copyright(C)2002 Niels Elburg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License , or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 , USA. - */ -#include -#include -#include -#include -#include "diff.h" -#include "common.h" -#include -#include -#include -#include -#include -#include -#include - -#include "softblur.h" -static uint8_t *static_bg = NULL; -static uint32_t *dt_map = NULL; -static void *shrink_ = NULL; -static sws_template template_; -static VJFrame to_shrink_; -static VJFrame shrinked_; -static int dw_, dh_; -static int x_[255]; -static int y_[255]; -static void *proj_[255]; -static int *coord_x = NULL; -static int *coord_y = NULL; - -typedef struct -{ - uint32_t *data; - uint8_t *bitmap; - uint8_t *current; -} texmap_data; - -typedef struct -{ - int x; - int y; -} point_t; - -static point_t **points = NULL; - -extern void *viewport_fx_init_map( int wid, int hei, int x1, int y1, - int x2, int y2, int x3, int y3, int x4, int y4); -extern void viewport_line (uint8_t *plane,int x1, int y1, int x2, int y2, int w, int h, uint8_t col); -extern void viewport_process_dynamic_map( void *data, uint8_t *in[3], uint8_t *out[3], uint32_t *map, int feather ); - -vj_effect *texmap_init(int width, int height) -{ - //int i,j; - vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect)); - ve->num_params = 5; - ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */ - ve->limits[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */ - ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */ - ve->limits[0][0] = 0; - ve->limits[1][0] = 255; - ve->limits[0][1] = 0; /* reverse */ - ve->limits[1][1] = 1; - ve->limits[0][2] = 0; /* show mask */ - ve->limits[1][2] = 4; - ve->limits[0][3] = 1; /* thinning */ - ve->limits[1][3] = 100; - ve->limits[0][4] = 1; /* minimum blob weight */ - ve->limits[1][4] = 5000; - - ve->defaults[0] = 30; - ve->defaults[1] = 0; - ve->defaults[2] = 2; - ve->defaults[3] = 5; - ve->defaults[4] = 200; - - ve->param_description = vje_build_param_list( ve->num_params, "Threshold", "Reverse", "Show mask", "Thinning", "Min blob weight"); - - ve->description = "Map B to A (sub bg, texture map))"; - ve->extra_frame = 1; - ve->sub_format = 1; - ve->has_user = 1; - ve->user_data = NULL; - return ve; -} - -void texmap_destroy(void) -{ - if(static_bg) - free(static_bg); - if(dt_map) - free(dt_map); - static_bg = NULL; - dt_map = NULL; - -} - -#define ru8(num)(((num)+8)&~8) -static int nearest_div(int val ) -{ - int r = val % 8; - while(r--) - val--; - return val; -} -int texmap_malloc(void **d, int width, int height) -{ - texmap_data *my; - *d = (void*) vj_calloc(sizeof(texmap_data)); - my = (texmap_data*) *d; - - dw_ = nearest_div( width / 8 ); - dh_ = nearest_div( height / 8 ); - - my->current = (uint8_t*) vj_calloc( ru8( sizeof(uint8_t) * dw_ * dh_ * 4 ) ); - my->bitmap = (uint8_t*) vj_calloc( ru8(sizeof(uint8_t) * width * height * 2)); - - if(static_bg == NULL) - static_bg = (uint8_t*) vj_calloc( ru8( width + width * height * sizeof(uint8_t)) ); - if(dt_map == NULL ) - dt_map = (uint32_t*) vj_calloc( ru8(width * height * sizeof(uint32_t) + width ) ); - - veejay_memset( &template_, 0, sizeof(sws_template) ); - veejay_memset( proj_, 0, sizeof(proj_) ); - - template_.flags = 1; - - vj_get_yuvgrey_template( &to_shrink_, width, height ); - vj_get_yuvgrey_template( &shrinked_ , dw_, dh_ ); - - shrink_ = yuv_init_swscaler( - &(to_shrink_), - &(shrinked_), - &template_ , - yuv_sws_get_cpu_flags() ); - - points = (point_t**) vj_calloc( sizeof(point_t) * 12000 ); - int i; - for( i = 0; i < 12000;i ++ ) - points[i] = (point_t*) vj_calloc(sizeof(point_t)); - - - veejay_memset( x_, 0, sizeof(x_) ); - veejay_memset( y_, 0, sizeof(y_) ); - - return 1; -} - -void texmap_free(void *d) -{ - if(d) - { - texmap_data *my = (texmap_data*) d; - if(my->current) free(my->current); - if(my->bitmap) free(my->bitmap); - free(d); - } - - if( shrink_ ) - { - yuv_free_swscaler( shrink_ ); - shrink_ = NULL; - } - - int i; - for( i = 0; i < 255; i++ ) - if( proj_[i] ) - viewport_destroy( (void*)proj_[i] ); - - if( points ) - { - for( i = 0; i < 12000; i ++ ) - if( points[i]) free(points[i]); - free(points); - } - - d = NULL; -} - -int texmap_prepare(uint8_t *map[3], int width, int height) -{ - if(!static_bg ) - { - return 0; - } - - vj_frame_copy1( map[0], static_bg, (width*height)); - - VJFrame tmp; - veejay_memset( &tmp, 0, sizeof(VJFrame)); - tmp.data[0] = static_bg; - tmp.width = width; - tmp.height = height; - softblur_apply( &tmp, width,height,0); - - veejay_msg(2, "Map B to A: Snapped background frame"); - return 1; -} - -static void texmap_centroid() -{ - -} - -static int bg_frame_ = 0; - - - -void texmap_apply(void *ed, VJFrame *frame, - VJFrame *frame2, int width, int height, - int threshold, int reverse,int mode, int feather, int min_blob_weight) -{ - - unsigned int i,j,k; - const uint32_t len = frame->len; - uint8_t *Y = frame->data[0]; - uint8_t *Cb = frame->data[1]; - uint8_t *Cr = frame->data[2]; - uint8_t *Y2 = frame2->data[0]; - uint8_t *Cb2 = frame2->data[1]; - uint8_t *Cr2 = frame2->data[2]; - - uint32_t cx[256]; - uint32_t cy[256]; - uint32_t xsize[256]; - uint32_t ysize[256]; - - float sx = (float) width / (float) dw_; - float sy = (float) height / (float) dh_; - float sw = (float) sqrt( sx * sy ); - - int packets = 0; - - veejay_memset( cx,0,sizeof(cx)); - veejay_memset( cy,0,sizeof(cy)); - - veejay_memset( xsize,0,sizeof(xsize)); - veejay_memset( ysize,0,sizeof(ysize)); - - texmap_data *ud = (texmap_data*) ed; - - if( bg_frame_ > 0 && bg_frame_ < 4 ) - { - for( i = 0 ; i < len ; i ++ ) - { - static_bg[i] = (static_bg[i] + Y[i] ) >> 1; - } - bg_frame_ ++; - return; - } - - //@ clear distance transform map - veejay_memset( dt_map, 0 , len * sizeof(uint32_t) ); - - //@ todo: optimize with mmx - binarify( ud->bitmap, static_bg, frame->data[0], threshold, reverse,len ); - - if(mode==1) - { - //@ show difference image in grayscale - vj_frame_copy1( ud->bitmap, Y, len ); - vj_frame_clear1( Cb, 128, len ); - vj_frame_clear1( Cr, 128, len ); - return; - } - - //@ calculate distance map -// veejay_distance_transform( ud->data, width, height, dt_map ); - veejay_distance_transform( ud->bitmap, width, height, dt_map ); - - - if( mode ==3 ) - { - //@ process dt map - for( i = 0; i < len ;i ++ ) - { - if( dt_map[ i ] >= feather ) - { - Y[i] = Y2[i]; - Cb[i] = Cb2[i]; - Cr[i] = Cr2[i]; - } - else - { - Y[i] = 0; - Cb[i] = 128; - Cr[i] = 128; - } - } - return; - } - - to_shrink_.data[0] = ud->bitmap; - shrinked_.data[0] = ud->current; - - uint32_t blobs[255]; - - veejay_memset( blobs, 0, sizeof(blobs) ); - - yuv_convert_and_scale_grey( shrink_, &to_shrink_, &shrinked_ ); - - uint32_t labels = veejay_component_labeling_8(dw_,dh_, shrinked_.data[0], blobs, cx,cy,xsize,ysize, - min_blob_weight); - - - - if (mode == 2 ) - { - //@ show dt map as grayscale image, intensity starts at 128 - for( i = 0; i < len ; i ++ ) - { - if( dt_map[i] == feather ) - Y[i] = 0xff; //@ border white - else if( dt_map[i] > feather ) { - Y[i] = 128 + (dt_map[i] % 128); //grayscale value - } else if ( dt_map[i] == 1 ) { - Y[i] = 0xff; - } else { - Y[i] = 0; //@ black (background) - } - Cb[i] = 128; - Cr[i] = 128; - } - } - - int num_objects = 0; - for( i = 1; i <=labels; i ++ ) - if( blobs[i] ) - num_objects ++; - - //@ Iterate over blob's bounding boxes and extract contours - for( i = 1; i <= labels; i ++ ) - { - if( blobs[i] > 0 ) - { - int nx = cx[i] * sx; - int ny = cy[i] * sy; - int size_x = xsize[i] * sx; - int size_y = ysize[i] * sy * 0.5; - - int x1 = nx - size_x; - int y1 = ny - size_y; - int x2 = nx + size_y; - int y2 = ny + size_y; - - int n_points = 0; - int dx1 = 0, dy1=0; - int center = 0; - - if( x1 < 0 ) x1 = 0; else if ( x1 > width ) x1 = width; - if( x2 < 0 ) x2 = 0; else if ( x2 > width ) x2 = width; - if( y1 < 0 ) y1 = 0; else if ( y1 >= height ) y1 = height -1; - if( y2 < 0 ) y2 = 0; else if ( y2 >= height ) y2 = height -1; - - for( k = y1; k < y2; k ++ ) - { - for( j = x1; j < x2; j ++ ) - { - if( dt_map[ (k* width + j) ] > center ) - { - center = dt_map[ (k*width+j) ]; - dx1 = j; - dy1 = k; - } - if( dt_map[ (k * width + j) ] == feather ) - { - points[n_points]->x = j; //@ produces unsorted list of coordinates - points[n_points]->y = k; - n_points++; - if( n_points >= 10000 ) - { - veejay_msg(0, "Too many points in contour"); - return; - } - } - } - } - } - } - - veejay_memset( Y, 0 , len ); - veejay_memset( Cb, 128, len ); - veejay_memset( Cr, 128, len ); - - for( i = 1; i <= labels; i ++ ) - { - if( blobs[i] > 0 ) - { - int radius = (int) ( 0.5 + sqrt( sw * blobs[i]) ); - int nx = cx[i] * sx; - int ny = cy[i] * sy; - int size_x = xsize[i] * sx; - int size_y = ysize[i] * sy * 0.5; // over size in x axis - - if( mode != 4 && ( abs( nx - x_[i] ) > 10 || abs( ny - y_[i] ) > 10 ) ) - //if( mode!=4 && cx[i] != x_[i] || cy[i] != y_[i] || !proj_[i]) - { - x_[i] = nx; - y_[i] = ny; - - int x1 = nx - size_x; - int y1 = ny - size_y; - int x2 = nx + size_x; - int y2 = ny + size_y; - - if( x1 < 0 ) x1 = 0; else if ( x1 > width ) x1 = width; - if( x2 < 0 ) x2 = 0; else if ( x2 > width ) x2 = width; - if( y1 < 0 ) y1 = 0; else if ( y1 >= height ) y1 = height -1; - if( y2 < 0 ) y2 = 0; else if ( y2 >= height ) y2 = height -1; - - if((void*) proj_[i]) - viewport_destroy( (void*)proj_[i] ); - proj_[i] = (void*)viewport_fx_init_map( width,height, - x1, - y1, - x2, - y1, - x2, - y2, - x1, - y2 ); - if(!proj_[i]) - return; - } - - if( mode == 4 ) - { - viewport_line( Y, nx - size_x, ny - size_y , - nx + size_x, ny - size_y , - width, height, 0xff ); - - viewport_line( Y, nx - size_x, ny - size_y , - nx - size_x, ny + size_y , - width, height, 0xff ); - - viewport_line( Y, nx + size_x, ny - size_y , - nx + size_x, ny + size_y , - width, height, 0xff ); - - viewport_line( Y, nx - size_x, ny + size_y, - nx + size_x, ny + size_y , - width, height, 128 ); - } - else - { - viewport_process_dynamic_map( (void*)proj_[i], frame2->data, frame->data, dt_map, feather ); - packets++; - } - } - } - -} - - - - diff --git a/veejay-current/veejay-server/libvje/effects/texmap.h b/veejay-current/veejay-server/libvje/effects/texmap.h deleted file mode 100644 index 5c9abe7e..00000000 --- a/veejay-current/veejay-server/libvje/effects/texmap.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Linux VeeJay - * - * Copyright(C)2002 Niels Elburg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License , or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 , USA. - */ - -#ifndef TMAPEFFECT_H -#define TMAPEFFECT_H -#include -#include -#include - -vj_effect *texmap_init(int width, int height); -void texmap_free(void *d); -int texmap_malloc(void **c, int w, int h); -int texmap_prepare(uint8_t *map[3], int w, int h); -void texmap_apply(void *d , VJFrame *frame, - VJFrame *frame2, int width, int height, - int th, int reverse, int show, int feather, int blob); -void texmap_destroy(); -#endif diff --git a/veejay-current/veejay-server/libvje/vj-effman.c b/veejay-current/veejay-server/libvje/vj-effman.c index 2dc9ecf9..bd293a5e 100644 --- a/veejay-current/veejay-server/libvje/vj-effman.c +++ b/veejay-current/veejay-server/libvje/vj-effman.c @@ -647,58 +647,30 @@ void vj_effman_apply_video_effect( VJFrame **frames, vjp_kf *todo_info,int *arg, int vj_effect_prepare( VJFrame *frame, int selector) { - int fx_id = 0; + int fx_id = vj_effect_real_to_sequence( selector ); + if( fx_id < 0 || fx_id > MAX_EFFECTS ) + return 0; + switch( selector ) { case VJ_IMAGE_EFFECT_BGSUBTRACT: - fx_id = vj_effect_real_to_sequence( selector ); - if( fx_id >= 0 && vj_effects[fx_id] ) { - return bgsubtract_prepare( frame->data, frame->width,frame->height ); - } + return bgsubtract_prepare( frame->data, frame->width,frame->height ); break; case VJ_IMAGE_EFFECT_CONTOUR: - fx_id = vj_effect_real_to_sequence(selector); - if(fx_id>=0 && vj_effects[fx_id] ) { - return contourextract_prepare(frame->data,frame->width,frame->height ); - } + return contourextract_prepare(frame->data,frame->width,frame->height ); break; case VJ_VIDEO_EFFECT_DIFF: if( !vj_effect_has_cb(selector)) return 0; - fx_id = vj_effect_real_to_sequence( selector ); - if( fx_id >= 0 && vj_effects[fx_id]->user_data != NULL) - { - return diff_prepare( (void*) vj_effects[fx_id]->user_data, frame->data, frame->width, frame->height ); - } + return diff_prepare( (void*) vj_effects[fx_id]->user_data, frame->data, frame->width, frame->height ); break; case VJ_IMAGE_EFFECT_CHAMELEON: - fx_id = vj_effect_real_to_sequence( selector ); - if( fx_id >= 0 && vj_effects[fx_id]) - { - return chameleon_prepare( frame->data, frame->width, frame->height ); - } + return chameleon_prepare( frame->data, frame->width, frame->height ); break; case VJ_IMAGE_EFFECT_MOTIONMAP: - fx_id = vj_effect_real_to_sequence( selector ); - if( fx_id >= 0 && vj_effects[fx_id]) - { - return motionmap_prepare( frame->data, frame->width, frame->height ); - } + return motionmap_prepare( frame->data, frame->width, frame->height ); break; - /* case VJ_VIDEO_EFFECT_TEXMAP: - fx_id = vj_effect_real_to_sequence( selector ); - if( fx_id >= 0 && vj_effects[fx_id] ) - { - return texmap_prepare( frame->data, frame->width, frame->height ); - } - break;*/ case VJ_VIDEO_EFFECT_CHAMBLEND: - fx_id = vj_effect_real_to_sequence( selector ); - if( fx_id >= 0 && vj_effects[fx_id]) - { - return chameleonblend_prepare( frame->data, frame->width, frame->height ); - } - break; - + return chameleonblend_prepare( frame->data, frame->width, frame->height ); default: break; } diff --git a/veejay-current/veejay-server/libyuv/yuvconv.c b/veejay-current/veejay-server/libyuv/yuvconv.c index 7c1e2c85..8540adc5 100644 --- a/veejay-current/veejay-server/libyuv/yuvconv.c +++ b/veejay-current/veejay-server/libyuv/yuvconv.c @@ -33,6 +33,17 @@ #include #include #include + +#define Y4M_CHROMA_420JPEG 0 /* 4:2:0, H/V centered, for JPEG/MPEG-1 */ +#define Y4M_CHROMA_420MPEG2 1 /* 4:2:0, H cosited, for MPEG-2 */ +#define Y4M_CHROMA_420PALDV 2 /* 4:2:0, alternating Cb/Cr, for PAL-DV */ +#define Y4M_CHROMA_444 3 /* 4:4:4, no subsampling, phew. */ +#define Y4M_CHROMA_422 4 /* 4:2:2, H cosited */ +#define Y4M_CHROMA_411 5 /* 4:1:1, H cosited */ +#define Y4M_CHROMA_MONO 6 /* luma plane only */ +#define Y4M_CHROMA_444ALPHA 7 /* 4:4:4 with an alpha channel */ + + /* this routine is the same as frame_YUV422_to_YUV420P , unpack * libdv's 4:2:2-packed into 4:2:0 planar * See http://mjpeg.sourceforge.net/ (MJPEG Tools) (lav-common.c) @@ -200,6 +211,82 @@ int yuv_use_auto_ccir_jpeg() return auto_conversion_ccir_jpeg_; } +int get_chroma_from_pixfmt(int pixfmt) { + int chroma; + switch(pixfmt) { + case PIX_FMT_YUVJ420P: chroma = Y4M_CHROMA_420JPEG; break; + case PIX_FMT_YUV420P: chroma = Y4M_CHROMA_420MPEG2; break; + case PIX_FMT_YUV422P: chroma = Y4M_CHROMA_422; break; + case PIX_FMT_YUV444P: chroma = Y4M_CHROMA_444; break; + case PIX_FMT_YUVJ422P: chroma = Y4M_CHROMA_422; break; //FIXME + case PIX_FMT_YUVJ444P: chroma = Y4M_CHROMA_444; break; //FIXME + case PIX_FMT_YUV411P: chroma = Y4M_CHROMA_411; break; + case PIX_FMT_GRAY8: chroma = PIX_FMT_GRAY8; break; + default: + chroma = Y4M_CHROMA_444; + break; + } + return chroma; +} + +int get_pixfmt_from_chroma(int chroma) { + int src_fmt; + switch( chroma ) { + case Y4M_CHROMA_420JPEG: src_fmt = PIX_FMT_YUVJ420P; break; + case Y4M_CHROMA_420MPEG2: + case Y4M_CHROMA_420PALDV: + src_fmt = PIX_FMT_YUV420P; break; + case Y4M_CHROMA_422: + src_fmt = PIX_FMT_YUV422P; break; + case Y4M_CHROMA_444: + src_fmt = PIX_FMT_YUV444P; break; + case Y4M_CHROMA_411: + src_fmt = PIX_FMT_YUV411P; break; + case Y4M_CHROMA_MONO: + src_fmt = PIX_FMT_GRAY8; break; + default: + src_fmt = -1; + break; + } + return src_fmt; +} + +int vj_to_pixfmt(int fmt) { + int pixfmt; + switch(fmt) { + case FMT_420: pixfmt = PIX_FMT_YUV420P; break; + case FMT_420F: pixfmt = PIX_FMT_YUVJ420P; break; + case FMT_422: pixfmt = PIX_FMT_YUV422P; break; + case FMT_422F: pixfmt = PIX_FMT_YUVJ422P; break; + case FMT_444: pixfmt = PIX_FMT_YUV444P;break; + default: + pixfmt = -1; + break; + } + return pixfmt; +} + +int pixfmt_to_vj(int pixfmt) { + int fmt; + switch(pixfmt) { + case PIX_FMT_YUV420P: fmt = FMT_420; break; + case PIX_FMT_YUVJ420P: fmt = FMT_420F; break; + case PIX_FMT_YUVJ422P: fmt = FMT_422F; break; + case PIX_FMT_YUV422P: fmt = FMT_422; break; + default: fmt = -1; break; + } + return fmt; +} + +int vj_is_full_range(int fmt) { + return ( fmt == FMT_420F || fmt == FMT_422F ) ? 1: 0; +} + +int pixfmt_is_full_range(int pixfmt) { + return ( pixfmt == PIX_FMT_YUVJ420P || pixfmt == PIX_FMT_YUVJ422P || pixfmt == PIX_FMT_YUVJ444P ) ? 1:0; +} + + static int global_scaler_ = SWS_FAST_BILINEAR; static int full_chroma_interpolation_ = 0; int yuv_which_scaler() diff --git a/veejay-current/veejay-server/libyuv/yuvconv.h b/veejay-current/veejay-server/libyuv/yuvconv.h index e40766ae..fcf21a6f 100644 --- a/veejay-current/veejay-server/libyuv/yuvconv.h +++ b/veejay-current/veejay-server/libyuv/yuvconv.h @@ -23,6 +23,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +int get_pixfmt_from_chroma(int chroma); +int get_chroma_from_pixfmt(int pixfmt); +int vj_to_pixfmt(int fmt); +int pixfmt_to_vj(int pixfmt); +int pixfmt_is_full_range(int pixfmt); +int vj_is_full_range(int fmt); // yuv 4:2:2 packed to yuv 4:2:0 planar void vj_yuy2toyv12( uint8_t *y, uint8_t *u, uint8_t *v, uint8_t *in, int w, int h); diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c index 8002b634..21e7061d 100644 --- a/veejay-current/veejay-server/veejay/liblavplayvj.c +++ b/veejay-current/veejay-server/veejay/liblavplayvj.c @@ -593,9 +593,6 @@ int veejay_init_editlist(veejay_t * info) veejay_msg(VEEJAY_MSG_DEBUG, "1.0/Seconds per video Frame = %4.4f", 1.0 / settings->spvf); veejay_msg(VEEJAY_MSG_DEBUG, "1.0/%ld = %g Seconds per audio Frame", el->audio_rate, settings->spas ); - vj_el_set_image_output_size( el, info->dummy->width, info->dummy->height, - info->dummy->fps, info->pixel_format ); - return 0; } @@ -1839,11 +1836,6 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t el = info->edit_list; - if( info->video_output_width <= 0 || info->video_output_height <= 0 ) { - info->video_output_width = el->video_width; - info->video_output_height = el->video_height; - } - if(!vj_mem_threaded_init( info->video_output_width, info->video_output_height ) ) return 0; @@ -1862,12 +1854,12 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t int driver = 1; #endif - if (vj_tag_init(el->video_width, el->video_height, info->pixel_format,driver) != 0) { + if (vj_tag_init(info->video_output_width, info->video_output_height, info->pixel_format,driver) != 0) { veejay_msg(VEEJAY_MSG_ERROR, "Error while initializing Stream Manager"); return -1; } - info->font = vj_font_init( el->video_width,el->video_height,el->video_fps,0 ); + info->font = vj_font_init( info->video_output_width,info->video_output_height,el->video_fps,0 ); if(!info->font) { veejay_msg(VEEJAY_MSG_ERROR, "Error while initializing font system."); @@ -1882,7 +1874,7 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t } else { - info->osd = vj_font_single_init( el->video_width,el->video_height,el->video_fps,info->homedir ); + info->osd = vj_font_single_init( info->video_output_width,info->video_output_height,el->video_fps,info->homedir ); } @@ -1892,23 +1884,23 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t } - sample_init( (el->video_width * el->video_height), info->font ); + sample_init( (info->video_output_width * info->video_output_height), info->font ); sample_set_project( info->pixel_format, info->auto_deinterlace, info->preserve_pathnames, 0, - el->video_norm ); + el->video_norm, + info->video_output_width, + info->video_output_height); int full_range = veejay_set_yuv_range( info ); - if(!vj_el_init_422_frame( el, info->effect_frame1)) return 0; - if(!vj_el_init_422_frame( el, info->effect_frame2)) return 0; info->settings->sample_mode = SSM_422_444; veejay_msg(VEEJAY_MSG_DEBUG, "Internal YUV format is 4:2:2 Planar, %d x %d", - el->video_width, - el->video_height); + info->video_output_width, + info->video_output_height); veejay_msg(VEEJAY_MSG_DEBUG, "FX Frame Info: %d x %d, ssm=%d, format=%d", info->effect_frame1->width,info->effect_frame1->height, info->effect_frame1->ssm, @@ -1934,7 +1926,7 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t if( info->settings->composite ) { int o1 = info->video_output_width * info->video_output_height; - int o2 = el->video_width * el->video_height; + int o2 = info->effect_frame1->len; int comp_mode = 2; if( o2 > o1 ) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to perform viewport rendering when input resolution is larger then output resolution."); @@ -1942,7 +1934,7 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t } info->composite = composite_init( info->video_output_width, info->video_output_height, - el->video_width, el->video_height, + info->video_output_width, info->video_output_height, info->homedir, info->settings->sample_mode, yuv_which_scaler(), @@ -1955,11 +1947,6 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t info->settings->composite = comp_mode; } - if(info->video_output_width <= 0 || info->video_output_height <=0 ) { - info->video_output_width = el->video_width; - info->video_output_height = el->video_height; - } - if(!info->bes_width) info->bes_width = info->video_output_width; if(!info->bes_height) @@ -1975,22 +1962,12 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t veejay_msg(VEEJAY_MSG_INFO, "Initialized %d Image- and Video Effects", vj_effect_max_effects()); - vj_effect_initialize( el->video_width,el->video_height, full_range); - veejay_msg(VEEJAY_MSG_DEBUG, - "BES %d x %d, Video %d x %d , Screen %d x %d", - info->bes_width, - info->bes_height, - el->video_width, - el->video_height, - info->video_output_width, - info->video_output_height); + vj_effect_initialize( info->video_output_width,info->video_output_height,full_range); if(info->dump) vj_effect_dump(); - if( info->settings->action_scheduler.sl && info->settings->action_scheduler.state ) { - if(sample_readFromFile( info->settings->action_scheduler.sl, info->composite, info->seq, info->font, el, &(info->uc->sample_id), &(info->uc->playback_mode) ) ) @@ -2117,9 +2094,9 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t break; case 4: - veejay_msg(VEEJAY_MSG_INFO, "Entering Y4M streaming mode."); - info->y4m = vj_yuv4mpeg_alloc( el, info->video_output_width,info->video_output_height, info->pixel_format ); - if( vj_yuv_stream_start_write( info->y4m, el, info->y4m_file, Y4M_CHROMA_420JPEG ) == -1 ) { + veejay_msg(VEEJAY_MSG_INFO, "Entering Y4M streaming mode (420JPEG)"); + info->y4m = vj_yuv4mpeg_alloc( info->video_output_width,info->video_output_height,info->effect_frame1->fps, info->pixel_format ); + if( vj_yuv_stream_start_write( info->y4m, info->effect_frame1, info->y4m_file, Y4M_CHROMA_420JPEG ) == -1 ) { return -1; } break; @@ -2145,6 +2122,13 @@ int veejay_init(veejay_t * info, int x, int y,char *arg, int def_tags, int gen_t break; + case 6: + veejay_msg(VEEJAY_MSG_INFO, "Entering Y4M streaming mode (422)"); + info->y4m = vj_yuv4mpeg_alloc( info->video_output_width,info->video_output_height,info->effect_frame1->fps, info->pixel_format ); + if( vj_yuv_stream_start_write( info->y4m, info->effect_frame1, info->y4m_file, Y4M_CHROMA_422 ) == -1 ) { + return -1; + } + break; default: veejay_msg(VEEJAY_MSG_ERROR, "Invalid playback mode. Use -O [012345]"); @@ -2298,7 +2282,6 @@ static void veejay_schedule_fifo(veejay_t *info, int pid ) * veejay_playback_cycle() * the playback cycle ******************************************************/ -static double last_tdiff = 0.0; static void veejay_playback_cycle(veejay_t * info) { video_playback_stats stats; @@ -2573,8 +2556,8 @@ static void veejay_playback_cycle(veejay_t * info) static void Welcome(veejay_t *info) { veejay_msg(VEEJAY_MSG_WARNING, "Video project settings: %ldx%ld, Norm: [%s], fps [%2.2f], %s", - info->current_edit_list->video_width, - info->current_edit_list->video_height, + info->video_output_width, + info->video_output_height, info->current_edit_list->video_norm == 'n' ? "NTSC" : "PAL", info->current_edit_list->video_fps, info->current_edit_list->video_inter==0 ? "Not interlaced" : "Interlaced" ); @@ -2860,14 +2843,6 @@ veejay_t *veejay_malloc() if (!(info->uc)) return NULL; - info->effect_frame1 = (VJFrame*) vj_calloc(sizeof(VJFrame)); - if(!info->effect_frame1) - return NULL; - - info->effect_frame2 = (VJFrame*) vj_calloc(sizeof(VJFrame)); - if(!info->effect_frame2) - return NULL; - info->effect_frame_info = (VJFrameInfo*) vj_calloc(sizeof(VJFrameInfo)); if(!info->effect_frame_info) return NULL; @@ -3284,7 +3259,7 @@ int veejay_edit_delete(veejay_t * info, editlist *el, long start, long end) } el->video_frames -= (n2 - n1 + 1); - el->total_frames = el->video_frames - 1; + el->total_frames -= (n2 - n1 + 1); return 1; } @@ -3371,6 +3346,9 @@ int veejay_edit_paste(veejay_t * info, editlist *el, long destination) k++; } el->video_frames += settings->save_list_len; + + el->total_frames += settings->save_list_len -1; + if(el->is_empty) el->is_empty = 0; veejay_increase_frame(info, 0); @@ -3478,7 +3456,7 @@ int veejay_edit_addmovie_sample(veejay_t * info, char *movie, int id ) // create initial edit list for sample (is currently playing) if(!sample_edl) sample_edl = vj_el_init_with_args( files,1,info->preserve_pathnames,info->auto_deinterlace,0, - info->edit_list->video_norm , info->pixel_format); + info->edit_list->video_norm , info->pixel_format, info->video_output_width, info->video_output_height); // if that fails, bye if(!sample_edl) { @@ -3488,12 +3466,6 @@ int veejay_edit_addmovie_sample(veejay_t * info, char *movie, int id ) return -1; } - if( sample_edl->video_width != info->edit_list->video_width || - sample_edl->video_height != info->edit_list->video_height ) - { - veejay_msg(VEEJAY_MSG_WARNING, "Video dimensions do not match!"); - } - // the sample is not there yet,create it if(!sample) { @@ -3528,7 +3500,7 @@ int veejay_edit_addmovie(veejay_t * info, editlist *el, char *movie, long start n = el->num_video_files; int res = open_video_file(movie, el, info->preserve_pathnames, info->auto_deinterlace,1, - info->edit_list->video_norm ); + info->edit_list->video_norm, info->pixel_format, info->video_output_width, info->video_output_height ); if (res < 0) { @@ -3671,9 +3643,15 @@ static int veejay_open_video_files(veejay_t *info, char **files, int num_files, veejay_msg(VEEJAY_MSG_DEBUG,"Dummy Video: %dx%d, chroma %x, framerate %2.2f, norm %s", info->dummy->width,info->dummy->height, info->dummy->chroma,info->dummy->fps, (info->dummy->norm == 'n' ? "NTSC" :"PAL")); + + info->video_output_width = info->dummy->width; + info->video_output_height = info->dummy->height; } else { + int tmp_wid = info->video_output_width; + int tmp_hei = info->video_output_height; + info->edit_list = vj_el_init_with_args( files, @@ -3682,15 +3660,15 @@ static int veejay_open_video_files(veejay_t *info, char **files, int num_files, info->auto_deinterlace, force, override_norm, - info->pixel_format); + info->pixel_format, tmp_wid, tmp_hei); if(!info->edit_list ) return 0; } //@ set current info->current_edit_list = info->edit_list; - info->effect_frame_info->width = info->current_edit_list->video_width; - info->effect_frame_info->height= info->current_edit_list->video_height; + info->effect_frame_info->width = info->video_output_width; + info->effect_frame_info->height= info->video_output_height; if(info->settings->output_fps > 0.0) { @@ -3706,12 +3684,10 @@ static int veejay_open_video_files(veejay_t *info, char **files, int num_files, return 1; } -static void configure_dummy_defaults(veejay_t *info, char override_norm, float fps) +static void configure_dummy_defaults(veejay_t *info, char override_norm, float fps, char **files, int n_files) { info->dummy->width = info->video_output_width; info->dummy->height= info->video_output_height; - - info->dummy->norm = 'p'; if( override_norm == 'n' ) { if(!info->dummy->fps) //@ if not set @@ -3726,7 +3702,7 @@ static void configure_dummy_defaults(veejay_t *info, char override_norm, float f int dw = 720; int dh = (override_norm == 'p' ? 576 : 480); - + float dfps = fps; if( has_env_setting( "VEEJAY_RUN_MODE", "CLASSIC" ) ) { dw = (override_norm == 'p' ? 352 : 360 ); dh = dh / 2; @@ -3735,16 +3711,33 @@ static void configure_dummy_defaults(veejay_t *info, char override_norm, float f veejay_msg(VEEJAY_MSG_DEBUG, "env VEEJAY_RUN_MODE not set to CLASSIC"); } - if( !info->dummy->width ) + if(!info->dummy->active) { + if( n_files > 0 && (info->video_output_width <= 0 || info->video_output_height <= 0 )) { + vj_el_scan_video_file( files[0], &dw, &dh, &dfps ); + + info->video_output_width = dw; + info->video_output_height = dh; + } + } else { + info->video_output_width = dw; + info->video_output_height = dh; + } + + if( info->dummy->width <= 0 ) info->dummy->width = dw; - if( !info->dummy->height) + if( info->dummy->height <= 0) info->dummy->height = dh; - - info->dummy->chroma = CHROMA422; + if( info->dummy->fps <= 0) + info->dummy->height = dfps; + + info->dummy->chroma = get_chroma_from_pixfmt( vj_to_pixfmt( info->pixel_format ) ); + if( info->audio ) { if( !info->dummy->arate) info->dummy->arate = 48000; } + + info->settings->output_fps = dfps; } int veejay_open_files(veejay_t * info, char **files, int num_files, float ofps, int force,int force_pix_fmt, char override_norm, int switch_jpeg) @@ -3769,7 +3762,7 @@ int veejay_open_files(veejay_t * info, char **files, int num_files, float ofps, sprintf(text, "4:2:2 [0-255]"); break; default: - veejay_msg(VEEJAY_MSG_ERROR, "Unknown pixel format set"); + veejay_msg(VEEJAY_MSG_ERROR, "Unsupported pixel format selected"); return 0; } @@ -3785,14 +3778,18 @@ int veejay_open_files(veejay_t * info, char **files, int num_files, float ofps, if(ofps<=0.0f) ofps = 25.0f; - configure_dummy_defaults(info,override_norm, ofps); + configure_dummy_defaults(info,override_norm, ofps,files,num_files); vj_el_init( info->pixel_format, switch_jpeg, info->dummy->width,info->dummy->height, info->dummy->fps ); #ifdef USE_GDK_PIXBUF vj_picture_init( &(info->settings->sws_templ)); #endif - settings->output_fps = ofps; + + info->effect_frame1 = yuv_yuv_template( NULL,NULL,NULL, info->video_output_width, info->video_output_height, vj_to_pixfmt(info->pixel_format) ); + info->effect_frame1->fps = info->settings->output_fps; + info->effect_frame2 = yuv_yuv_template( NULL,NULL,NULL, info->video_output_width, info->video_output_height, vj_to_pixfmt(info->pixel_format) ); + info->effect_frame2->fps = info->settings->output_fps; if(num_files == 0) { diff --git a/veejay-current/veejay-server/veejay/veejay.c b/veejay-current/veejay-server/veejay/veejay.c index a5817905..0b1a4a69 100644 --- a/veejay-current/veejay-server/veejay/veejay.c +++ b/veejay-current/veejay-server/veejay/veejay.c @@ -221,7 +221,7 @@ static void Usage(char *progname) " -c/--synchronization [01]\tSync correction off/on (default on)\n"); fprintf(stderr, - " -O/--output [0..4]\t\tOutput video\n"); + " -O/--output [0..6]\t\tOutput video\n"); #ifdef HAVE_SDL fprintf(stderr, "\t\t\t\t0 = SDL (default)\t\n"); @@ -237,7 +237,14 @@ static void Usage(char *progname) fprintf(stderr, "\t\t\t\t3 = Head less (no video output)\n"); fprintf(stderr, - "\t\t\t\t4 = Y4M Stream\n"); + "\t\t\t\t4 = Y4M Stream 4:2:0 (requires -o )\n"); + + fprintf(stderr, + "\t\t\t\t5 = Vloopback device (requires -o )\n"); + + fprintf(stderr, + "\t\t\t\t6 = Y4M Stream 4:2:2 (requires -o )\n"); + fprintf(stderr, " -o/--output-file [file]\tWrite to file (for use with Y4M Stream)\n"); #ifdef HAVE_SDL @@ -375,7 +382,7 @@ static int set_option(const char *name, char *value) } #endif */ - if( info->video_out < 0 || info->video_out > 5 ) { + if( info->video_out < 0 || info->video_out > 6 ) { fprintf(stderr, "Select a valid output display driver\n"); exit(-1); } diff --git a/veejay-current/veejay-server/veejay/vj-event.c b/veejay-current/veejay-server/veejay/vj-event.c index e289ecab..b008e832 100644 --- a/veejay-current/veejay-server/veejay/vj-event.c +++ b/veejay-current/veejay-server/veejay/vj-event.c @@ -4624,7 +4624,7 @@ void vj_event_sample_rec_start( void *ptr, const char format[], va_list ap) return; } - if( sample_init_encoder( v->uc->sample_id, tmp, format_, v->current_edit_list, args[0]) == 1) + if( sample_init_encoder( v->uc->sample_id, tmp, format_, v->effect_frame1, v->current_edit_list, args[0]) == 1) { video_playback_setup *s = v->settings; s->sample_record_id = v->uc->sample_id; @@ -8766,7 +8766,7 @@ void vj_event_get_cali_image ( void *ptr, const char format[], va_list ap ) } else { char header[128];//FIXME - sprintf( header, "%03d%08d%06d%06d%06d%06d",8+6+6+6+6,len, len, 0, v->current_edit_list->video_width, v->current_edit_list->video_height ); + sprintf( header, "%03d%08d%06d%06d%06d%06d",8+6+6+6+6,len, len, 0, v->video_output_width, v->video_output_height ); SEND_MSG( v, header ); int res = vj_server_send(v->vjs[VEEJAY_PORT_CMD], v->uc->current_link, buf,len); @@ -9342,7 +9342,7 @@ void vj_event_send_editlist ( void *ptr, const char format[], va_list ap ) char *msg = (char*) vj_el_write_line_ascii( el, &b ); - + char *s_print_buf = get_print_buf( b + 8 ); snprintf( s_print_buf, (b+8),"%06d%s", b, msg ); @@ -10294,8 +10294,8 @@ void vj_event_add_subtitle( void *ptr, const char format[], va_list ap ) if( args[3] < 0 || args[4] < 0 || - args[3] >= v->current_edit_list->video_width || - args[4] >= v->current_edit_list->video_height ) + args[3] >= v->video_output_width || + args[4] >= v->video_output_height ) { veejay_msg(VEEJAY_MSG_ERROR, "Invalid XY position"); diff --git a/veejay-current/veejay-server/veejay/vj-misc.c b/veejay-current/veejay-server/veejay/vj-misc.c index 3bd68a8e..c9d08fb8 100644 --- a/veejay-current/veejay-server/veejay/vj-misc.c +++ b/veejay-current/veejay-server/veejay/vj-misc.c @@ -232,14 +232,17 @@ int vj_perform_take_bg(veejay_t *info, VJFrame *frame, int pass) if( pass == 0 ) { if(frame->ssm = 1 ) { n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_CHAMBLEND ); - n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CHAMELEON ); - return 1; + n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CHAMELEON ); + if(n > 0 ) + return 1; } if(frame->ssm == 0) { n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_BGSUBTRACT ); n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_DIFF ); n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_MOTIONMAP ); n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CONTOUR ); + if( n > 0 ) + return 1; } if( frame->ssm == 0 ) @@ -248,17 +251,16 @@ int vj_perform_take_bg(veejay_t *info, VJFrame *frame, int pass) n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_CHAMBLEND ); n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CHAMELEON ); frame->ssm = 1; - return 1; - } - return 0; + return 0; + } + + return (n > 0 ? 0: 1 ); } else { - if(frame->ssm == 0) { n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_BGSUBTRACT ); n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_DIFF ); n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_MOTIONMAP ); n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CONTOUR ); - // n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_TEXMAP); return 0; } } diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c index 3d15e6e2..4c521b80 100644 --- a/veejay-current/veejay-server/veejay/vj-perform.c +++ b/veejay-current/veejay-server/veejay/vj-perform.c @@ -544,8 +544,8 @@ static int vj_perform_verify_rows(veejay_t *info ) return 0; int c,v,has_rows = 0; - const int w = info->current_edit_list->video_width; - const int h = info->current_edit_list->video_height; + const int w = info->video_output_width; + const int h = info->video_output_height; #ifdef STRICT_CHECKING long total_size = 0; #endif @@ -630,8 +630,9 @@ static char ppm_path[1024]; int vj_perform_init(veejay_t * info) { #define PRIMARY_FRAMES 8 - const int w = info->edit_list->video_width; - const int h = info->edit_list->video_height; + const int w = info->video_output_width; + const int h = info->video_output_height; + const long frame_len = RUP8( (((w*h)+w)/7)*8 ); unsigned int c; long total_used = 0; @@ -749,8 +750,6 @@ int vj_perform_init(veejay_t * info) static void vj_perform_close_audio() { - int i; - if( lin_audio_buffer_ ) free(lin_audio_buffer_ ); veejay_memset( audio_buffer, 0, sizeof(uint8_t*) * SAMPLE_MAX_EFFECTS ); @@ -916,14 +915,13 @@ void vj_perform_free(veejay_t * info) int vj_perform_audio_start(veejay_t * info) { - int res; editlist *el = info->edit_list; if (el->has_audio) { #ifdef HAVE_JACK vj_jack_initialize(); - res = vj_jack_init(el); + int res = vj_jack_init(el); if( res <= 0 ) { veejay_msg(0, "Audio playback disabled"); info->audio = NO_AUDIO; @@ -993,8 +991,9 @@ void vj_perform_get_output_frame( uint8_t **frame ) } void vj_perform_get_crop_dimensions(veejay_t *info, int *w, int *h) { - *w = info->current_edit_list->video_width - info->settings->viewport.left - info->settings->viewport.right; - *h = info->current_edit_list->video_height - info->settings->viewport.top - info->settings->viewport.bottom; + *w = info->video_output_width - info->settings->viewport.left - info->settings->viewport.right; + *h = info->video_output_height - info->settings->viewport.top - info->settings->viewport.bottom; + } int vj_perform_get_cropped_frame( veejay_t *info, uint8_t **frame, int crop ) @@ -1005,8 +1004,8 @@ int vj_perform_get_cropped_frame( veejay_t *info, uint8_t **frame, int crop ) veejay_memset( &src, 0, sizeof(VJFrame)); vj_get_yuv_template( &src, - info->current_edit_list->video_width, - info->current_edit_list->video_height, + info->video_output_width, + info->video_output_height, info->pixel_format ); src.data[0] = primary_buffer[0]->Y; @@ -1280,13 +1279,12 @@ int vj_perform_is_ready(veejay_t *info) void vj_perform_get_primary_frame_420p(veejay_t *info, uint8_t **frame ) { - editlist *el = info->current_edit_list; uint8_t *pframe[3]; pframe[0] = primary_buffer[info->out_buf]->Y; pframe[1] = primary_buffer[info->out_buf]->Cb; pframe[2] = primary_buffer[info->out_buf]->Cr; - yuv422to420planar( pframe, temp_buffer, el->video_width,el->video_height ); - veejay_memcpy( pframe[0],frame[0], el->video_width * el->video_height ); + yuv422to420planar( pframe, temp_buffer, info->effect_frame1->width, info->effect_frame1->height ); + veejay_memcpy( pframe[0],frame[0], info->effect_frame1->len ); frame[0] = temp_buffer[0]; frame[1] = temp_buffer[1]; @@ -1695,8 +1693,8 @@ int vj_perform_fill_audio_buffers(veejay_t * info, uint8_t *audio_buf, uint8_t * static void vj_perform_apply_secundary_tag(veejay_t * info, int sample_id, int type, int chain_entry ) { /* second sample */ - int width = info->current_edit_list->video_width; - int height = info->current_edit_list->video_height; + int width = info->video_output_width; + int height = info->video_output_height; int error = 1; int nframe; int len = 0; @@ -1899,7 +1897,7 @@ static int vj_perform_get_frame_( veejay_t *info, int s1, long nframe, uint8_t * const uint32_t N = max_sfd; const uint32_t n1 = cur_sfd; const float frac = 1.0f / (float) N * n1; - const uint32_t len = el->video_width * el->video_height; + const uint32_t len = info->video_output_width * info->video_output_height; vj_frame_slow_threaded( p0_buffer, p1_buffer, img , len, uv_len, frac ); @@ -1931,8 +1929,8 @@ static int vj_perform_get_frame_fx(veejay_t *info, int s1, long nframe, uint8_t static void vj_perform_apply_secundary(veejay_t * info, int sample_id, int type, int chain_entry) { /* second sample */ - int width = info->current_edit_list->video_width; - int height = info->current_edit_list->video_height; + int width = info->video_output_width; + int height = info->video_output_height; int error = 1; int nframe; int len; @@ -2073,7 +2071,7 @@ static int vj_perform_tag_render_chain_entry(veejay_t *info, int chain_entry) frames[0]->data[0] = primary_buffer[0]->Y; frames[0]->data[1] = primary_buffer[0]->Cb; frames[0]->data[2] = primary_buffer[0]->Cr; - frames[0]->format = info->pixel_format; +// frames[0]->format = info->pixel_format; vjp_kf *setup; setup = info->effect_info; setup->ref = info->uc->sample_id; @@ -2098,7 +2096,7 @@ static int vj_perform_tag_render_chain_entry(veejay_t *info, int chain_entry) frames[1]->data[0] = frame_buffer[chain_entry]->Y; frames[1]->data[1] = frame_buffer[chain_entry]->Cb; frames[1]->data[2] = frame_buffer[chain_entry]->Cr; - frames[1]->format = info->pixel_format; + // frames[1]->format = info->pixel_format; frames[1]->ssm = frame_buffer[chain_entry]->ssm; int done = 0; @@ -2694,7 +2692,7 @@ void vj_perform_record_sample_frame(veejay_t *info, int sample) { { veejay_msg(VEEJAY_MSG_DEBUG, "Continue, %d frames left to record", frames_left); if( sample_init_encoder( sample, NULL, - df, info->current_edit_list, frames_left)==-1) + df, info->effect_frame1, info->current_edit_list, frames_left)==-1) { veejay_msg(VEEJAY_MSG_ERROR, "Error while auto splitting "); @@ -2840,9 +2838,7 @@ static int vj_perform_tag_fill_buffer(veejay_t * info) dumb.data[1] = frame[1]; dumb.data[2] = frame[2]; - dummy_apply(&dumb, - info->current_edit_list->video_width, - info->current_edit_list->video_height, VJ_EFFECT_COLOR_BLACK); + dummy_apply(&dumb,info->video_output_width,info->video_output_height,VJ_EFFECT_COLOR_BLACK ); } return 1; } @@ -3389,8 +3385,9 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett vj_perform_take_bg(info,frame,1); info->uc->take_bg = 0; } - - + + if( frame2->data[0] == frame->data[0] ) + frame->ssm = 0; } static void vj_perform_render_font( veejay_t *info, video_playback_setup *settings )