diff -crN cinelerra-4.4/Makefile.orig cinelerra-4.4-ejo/Makefile.orig *** cinelerra-4.4/Makefile.orig Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/Makefile.orig Tue Jan 9 02:09:59 2007 *************** *** 0 **** --- 1,20 ---- + all: + $(MAKE) -f build/Makefile.cinelerra + + install: + $(MAKE) -f build/Makefile.cinelerra install + + clean: + $(MAKE) -f build/Makefile.cinelerra clean + + rebuild: + $(MAKE) -C guicast clean + $(MAKE) -C cinelerra clean + $(MAKE) -C plugins clean + $(MAKE) -C guicast + $(MAKE) -C cinelerra + $(MAKE) -C plugins + + rebuild_install: + $(MAKE) -C cinelerra install + $(MAKE) -C plugins install diff -crN cinelerra-4.4/Makefile.rej cinelerra-4.4-ejo/Makefile.rej *** cinelerra-4.4/Makefile.rej Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/Makefile.rej Fri Dec 28 23:32:34 2012 *************** *** 0 **** --- 1,166 ---- + *** Makefile Fri Feb 17 03:51:06 2012 + --- Makefile Fri Dec 28 23:06:50 2012 + *************** + *** 112,117 **** + $(OBJDIR)/edl.o \ + $(OBJDIR)/edlsession.o \ + $(OBJDIR)/fadeengine.o \ + $(OBJDIR)/file.o \ + $(OBJDIR)/fileavi.o \ + $(OBJDIR)/filebase.o \ + --- 112,118 ---- + $(OBJDIR)/edl.o \ + $(OBJDIR)/edlsession.o \ + $(OBJDIR)/fadeengine.o \ + + $(OBJDIR)/ffmpeg.o \ + $(OBJDIR)/file.o \ + $(OBJDIR)/fileavi.o \ + $(OBJDIR)/filebase.o \ + *************** + *** 135,140 **** + $(OBJDIR)/filetiff.o \ + $(OBJDIR)/filevorbis.o \ + $(OBJDIR)/filexml.o \ + $(OBJDIR)/floatauto.o \ + $(OBJDIR)/floatautos.o \ + $(OBJDIR)/forkwrapper.o \ + --- 136,142 ---- + $(OBJDIR)/filetiff.o \ + $(OBJDIR)/filevorbis.o \ + $(OBJDIR)/filexml.o \ + + $(OBJDIR)/fileyuv.o \ + $(OBJDIR)/floatauto.o \ + $(OBJDIR)/floatautos.o \ + $(OBJDIR)/forkwrapper.o \ + *************** + *** 208,213 **** + $(OBJDIR)/patchgui.o \ + $(OBJDIR)/performanceprefs.o \ + $(OBJDIR)/picture.o \ + $(OBJDIR)/playabletracks.o \ + $(OBJDIR)/playback3d.o \ + $(OBJDIR)/playbackconfig.o \ + --- 210,216 ---- + $(OBJDIR)/patchgui.o \ + $(OBJDIR)/performanceprefs.o \ + $(OBJDIR)/picture.o \ + + $(OBJDIR)/pipe.o \ + $(OBJDIR)/playabletracks.o \ + $(OBJDIR)/playback3d.o \ + $(OBJDIR)/playbackconfig.o \ + *************** + *** 320,325 **** + $(OBJDIR)/vwindow.o \ + $(OBJDIR)/vwindowgui.o \ + $(OBJDIR)/wavecache.o \ + $(OBJDIR)/zoombar.o \ + $(OBJDIR)/zoompanel.o + + --- 323,329 ---- + $(OBJDIR)/vwindow.o \ + $(OBJDIR)/vwindowgui.o \ + $(OBJDIR)/wavecache.o \ + + $(OBJDIR)/yuvstream.o \ + $(OBJDIR)/zoombar.o \ + $(OBJDIR)/zoompanel.o + + *************** + *** 422,428 **** + -I../libmpeg3 \ + -I$(SNDFILE_DIR)/src \ + $(ESOUNDCFLAGS) \ + ! -I$(THEORA_DIR)/include + + + # Speed up linking with this linking sequence + --- 426,436 ---- + -I../libmpeg3 \ + -I$(SNDFILE_DIR)/src \ + $(ESOUNDCFLAGS) \ + ! -I$(THEORA_DIR)/include \ + ! -I../quicktime/thirdparty/ffmpeg-0.6.1 \ + ! -I../quicktime/thirdparty/ffmpeg-0.6.1/libavcodec \ + ! -I../quicktime/thirdparty/ffmpeg-0.6.1/libswscale \ + ! -I../thirdparty/mjpegtools-1.9.0rc3/utils + + + # Speed up linking with this linking sequence + *************** + *** 496,502 **** + # in the main executable. + # Also VFS only overrides the C library when dynamic linking is used. + $(OUTPUT): $(OBJS) $(DCRAW) $(FILEEXR) $(FFMPEG_OBJS) $(FILEFLAC) $(THEME_DATA) $(SNDFILE_LIB) ../guicast/$(OBJDIR)/libguicast.a + ! $(LINKER) `cat $(OBJDIR)/objs` + strip $(OUTPUT) + + $(OBJDIR)/test: + --- 504,510 ---- + # in the main executable. + # Also VFS only overrides the C library when dynamic linking is used. + $(OUTPUT): $(OBJS) $(DCRAW) $(FILEEXR) $(FFMPEG_OBJS) $(FILEFLAC) $(THEME_DATA) $(SNDFILE_LIB) ../guicast/$(OBJDIR)/libguicast.a + ! $(LINKER) `cat $(OBJDIR)/objs` `cat mjpegobjs` + strip $(OUTPUT) + + $(OBJDIR)/test: + *************** + *** 640,645 **** + $(OBJDIR)/edl.o: edl.C + $(OBJDIR)/edlsession.o: edlsession.C + $(OBJDIR)/fadeengine.o: fadeengine.C + $(OBJDIR)/file.o: file.C + $(OBJDIR)/fileac3.o: fileac3.C + $(OBJDIR)/fileavi.o: fileavi.C + --- 648,654 ---- + $(OBJDIR)/edl.o: edl.C + $(OBJDIR)/edlsession.o: edlsession.C + $(OBJDIR)/fadeengine.o: fadeengine.C + + $(OBJDIR)/ffmpeg.o: ffmpeg.C + $(OBJDIR)/file.o: file.C + $(OBJDIR)/fileac3.o: fileac3.C + $(OBJDIR)/fileavi.o: fileavi.C + *************** + *** 666,671 **** + $(OBJDIR)/filetiff.o: filetiff.C + $(OBJDIR)/filevorbis.o: filevorbis.C + $(OBJDIR)/filexml.o: filexml.C + $(OBJDIR)/floatauto.o: floatauto.C + $(OBJDIR)/floatautos.o: floatautos.C + $(OBJDIR)/forkwrapper.o: forkwrapper.C + --- 675,681 ---- + $(OBJDIR)/filetiff.o: filetiff.C + $(OBJDIR)/filevorbis.o: filevorbis.C + $(OBJDIR)/filexml.o: filexml.C + + $(OBJDIR)/fileyuv.o: fileyuv.C + $(OBJDIR)/floatauto.o: floatauto.C + $(OBJDIR)/floatautos.o: floatautos.C + $(OBJDIR)/forkwrapper.o: forkwrapper.C + *************** + *** 741,746 **** + $(OBJDIR)/patchgui.o: patchgui.C + $(OBJDIR)/performanceprefs.o: performanceprefs.C + $(OBJDIR)/picture.o: picture.C + $(OBJDIR)/playabletracks.o: playabletracks.C + $(OBJDIR)/playback3d.o: playback3d.C + $(OBJDIR)/playbackconfig.o: playbackconfig.C + --- 751,757 ---- + $(OBJDIR)/patchgui.o: patchgui.C + $(OBJDIR)/performanceprefs.o: performanceprefs.C + $(OBJDIR)/picture.o: picture.C + + $(OBJDIR)/pipe.o: pipe.C + $(OBJDIR)/playabletracks.o: playabletracks.C + $(OBJDIR)/playback3d.o: playback3d.C + $(OBJDIR)/playbackconfig.o: playbackconfig.C + *************** + *** 867,871 **** + $(OBJDIR)/vwindow.o: vwindow.C + $(OBJDIR)/vwindowgui.o: vwindowgui.C + $(OBJDIR)/wavecache.o: wavecache.C + $(OBJDIR)/zoombar.o: zoombar.C + $(OBJDIR)/zoompanel.o: zoompanel.C + --- 878,883 ---- + $(OBJDIR)/vwindow.o: vwindow.C + $(OBJDIR)/vwindowgui.o: vwindowgui.C + $(OBJDIR)/wavecache.o: wavecache.C + + $(OBJDIR)/yuvstream.o: yuvstream.C + $(OBJDIR)/zoombar.o: zoombar.C + $(OBJDIR)/zoompanel.o: zoompanel.C diff -crN cinelerra-4.4/cinelerra/Makefile cinelerra-4.4-ejo/cinelerra/Makefile *** cinelerra-4.4/cinelerra/Makefile Fri Feb 17 03:51:06 2012 --- cinelerra-4.4-ejo/cinelerra/Makefile Fri Dec 28 23:33:21 2012 *************** *** 112,117 **** --- 112,118 ---- $(OBJDIR)/edl.o \ $(OBJDIR)/edlsession.o \ $(OBJDIR)/fadeengine.o \ + $(OBJDIR)/ffmpeg.o \ $(OBJDIR)/file.o \ $(OBJDIR)/fileavi.o \ $(OBJDIR)/filebase.o \ *************** *** 135,140 **** --- 136,142 ---- $(OBJDIR)/filetiff.o \ $(OBJDIR)/filevorbis.o \ $(OBJDIR)/filexml.o \ + $(OBJDIR)/fileyuv.o \ $(OBJDIR)/floatauto.o \ $(OBJDIR)/floatautos.o \ $(OBJDIR)/forkwrapper.o \ *************** *** 208,213 **** --- 210,216 ---- $(OBJDIR)/patchgui.o \ $(OBJDIR)/performanceprefs.o \ $(OBJDIR)/picture.o \ + $(OBJDIR)/pipe.o \ $(OBJDIR)/playabletracks.o \ $(OBJDIR)/playback3d.o \ $(OBJDIR)/playbackconfig.o \ *************** *** 320,325 **** --- 323,329 ---- $(OBJDIR)/vwindow.o \ $(OBJDIR)/vwindowgui.o \ $(OBJDIR)/wavecache.o \ + $(OBJDIR)/yuvstream.o \ $(OBJDIR)/zoombar.o \ $(OBJDIR)/zoompanel.o *************** *** 422,428 **** -I../libmpeg3 \ -I$(SNDFILE_DIR)/src \ $(ESOUNDCFLAGS) \ ! -I$(THEORA_DIR)/include # Speed up linking with this linking sequence --- 426,436 ---- -I../libmpeg3 \ -I$(SNDFILE_DIR)/src \ $(ESOUNDCFLAGS) \ ! -I$(THEORA_DIR)/include \ ! -I../quicktime/thirdparty/ffmpeg-0.6.1 \ ! -I../quicktime/thirdparty/ffmpeg-0.6.1/libavcodec \ ! -I../quicktime/thirdparty/ffmpeg-0.6.1/libswscale \ ! -I../thirdparty/mjpegtools-1.9.0rc3/utils # Speed up linking with this linking sequence *************** *** 496,502 **** # in the main executable. # Also VFS only overrides the C library when dynamic linking is used. $(OUTPUT): $(OBJS) $(DCRAW) $(FILEEXR) $(FFMPEG_OBJS) $(FILEFLAC) $(THEME_DATA) $(SNDFILE_LIB) ../guicast/$(OBJDIR)/libguicast.a ! $(LINKER) `cat $(OBJDIR)/objs` strip $(OUTPUT) $(OBJDIR)/test: --- 504,510 ---- # in the main executable. # Also VFS only overrides the C library when dynamic linking is used. $(OUTPUT): $(OBJS) $(DCRAW) $(FILEEXR) $(FFMPEG_OBJS) $(FILEFLAC) $(THEME_DATA) $(SNDFILE_LIB) ../guicast/$(OBJDIR)/libguicast.a ! $(LINKER) `cat $(OBJDIR)/objs` `cat mjpegobjs` ../quicktime/thirdparty/ffmpeg-0.6.1/libswscale/libswscale.a strip $(OUTPUT) $(OBJDIR)/test: *************** *** 640,645 **** --- 648,654 ---- $(OBJDIR)/edl.o: edl.C $(OBJDIR)/edlsession.o: edlsession.C $(OBJDIR)/fadeengine.o: fadeengine.C + $(OBJDIR)/ffmpeg.o: ffmpeg.C $(OBJDIR)/file.o: file.C $(OBJDIR)/fileac3.o: fileac3.C $(OBJDIR)/fileavi.o: fileavi.C *************** *** 666,671 **** --- 675,681 ---- $(OBJDIR)/filetiff.o: filetiff.C $(OBJDIR)/filevorbis.o: filevorbis.C $(OBJDIR)/filexml.o: filexml.C + $(OBJDIR)/fileyuv.o: fileyuv.C $(OBJDIR)/floatauto.o: floatauto.C $(OBJDIR)/floatautos.o: floatautos.C $(OBJDIR)/forkwrapper.o: forkwrapper.C *************** *** 741,746 **** --- 751,757 ---- $(OBJDIR)/patchgui.o: patchgui.C $(OBJDIR)/performanceprefs.o: performanceprefs.C $(OBJDIR)/picture.o: picture.C + $(OBJDIR)/pipe.o: pipe.C $(OBJDIR)/playabletracks.o: playabletracks.C $(OBJDIR)/playback3d.o: playback3d.C $(OBJDIR)/playbackconfig.o: playbackconfig.C *************** *** 867,871 **** --- 878,883 ---- $(OBJDIR)/vwindow.o: vwindow.C $(OBJDIR)/vwindowgui.o: vwindowgui.C $(OBJDIR)/wavecache.o: wavecache.C + $(OBJDIR)/yuvstream.o: yuvstream.C $(OBJDIR)/zoombar.o: zoombar.C $(OBJDIR)/zoompanel.o: zoompanel.C diff -crN cinelerra-4.4/cinelerra/asset.C cinelerra-4.4-ejo/cinelerra/asset.C *** cinelerra-4.4/cinelerra/asset.C Thu Dec 29 01:27:19 2011 --- cinelerra-4.4-ejo/cinelerra/asset.C Fri Dec 28 23:32:42 2012 *************** *** 168,173 **** --- 168,177 ---- reset_index(); id = EDL::next_id(); + + pipe[0] = 0; + use_pipe = 0; + return 0; } *************** *** 299,304 **** --- 303,311 ---- tiff_cmodel = asset->tiff_cmodel; tiff_compression = asset->tiff_compression; + + strcpy(pipe, asset->pipe); + use_pipe = asset->use_pipe; } int64_t Asset::get_index_offset(int channel) *************** *** 833,838 **** --- 840,847 ---- exr_compression = GET_DEFAULT("EXR_COMPRESSION", exr_compression); tiff_cmodel = GET_DEFAULT("TIFF_CMODEL", tiff_cmodel); tiff_compression = GET_DEFAULT("TIFF_COMPRESSION", tiff_compression); + use_pipe = GET_DEFAULT("FORMAT_YUV_USE_PIPE", use_pipe); + GET_DEFAULT("FORMAT_YUV_PIPE", pipe); boundaries(); } *************** *** 944,949 **** --- 953,961 ---- UPDATE_DEFAULT("EXR_COMPRESSION", exr_compression); UPDATE_DEFAULT("TIFF_CMODEL", tiff_cmodel); UPDATE_DEFAULT("TIFF_COMPRESSION", tiff_compression); + + UPDATE_DEFAULT("FORMAT_YUV_USE_PIPE", use_pipe); + UPDATE_DEFAULT("FORMAT_YUV_PIPE", pipe); } if(do_bits) diff -crN cinelerra-4.4/cinelerra/asset.h cinelerra-4.4-ejo/cinelerra/asset.h *** cinelerra-4.4/cinelerra/asset.h Thu Dec 29 01:07:44 2011 --- cinelerra-4.4-ejo/cinelerra/asset.h Fri Dec 28 23:32:42 2012 *************** *** 124,130 **** int write_index(FileXML *xml); int update_path(char *new_path); ! // Format of file. An enumeration from file.inc. int format; --- 124,132 ---- int write_index(FileXML *xml); int update_path(char *new_path); ! // Pipe command ! char pipe[BCTEXTLEN]; ! int use_pipe; // Format of file. An enumeration from file.inc. int format; *************** *** 201,208 **** // Set by package render during file creation. -1 means square pixels. double aspect_ratio; ! ! // for jpeg compression int jpeg_quality; --- 203,212 ---- // Set by package render during file creation. -1 means square pixels. double aspect_ratio; ! // for the interlace mode ! int interlace_autofixoption; ! int interlace_mode; ! int interlace_fixmethod; // for jpeg compression int jpeg_quality; diff -crN cinelerra-4.4/cinelerra/ffmpeg.C cinelerra-4.4-ejo/cinelerra/ffmpeg.C *** cinelerra-4.4/cinelerra/ffmpeg.C Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/ffmpeg.C Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,400 ---- + #include + #define HAVE_SWSCALER + + #ifdef HAVE_SWSCALER + extern "C" { + #include + } + #endif + + extern "C" { + #include + } + + #include "filebase.h" + #include "quicktime.h" + #include "ffmpeg.h" + #include "guicast.h" + + + FFMPEG::FFMPEG(Asset *asset) { + this->asset = asset; + codec = 0; + context = 0; + picture = 0; + got_picture = 0; + } + + int FFMPEG::init(char *codec_string) { + + avcodec_init(); + avcodec_register_all(); + + CodecID id = codec_id(codec_string); + codec = avcodec_find_decoder(id); + if (codec == NULL) { + printf("FFMPEG::init no decoder for '%s'", codec_string); + return 1; + } + + context = avcodec_alloc_context(); + + if (avcodec_open(context, codec)) { + printf("FFMPEG::init avcodec_open() failed\n"); + } + + picture = avcodec_alloc_frame(); + + + return 0; + } + + FFMPEG::~FFMPEG() { + avcodec_close(context); + free(context); + free(picture); + } + + + CodecID FFMPEG::codec_id(char *codec_string) { + #define CODEC_IS(x) (! strncmp(codec_string, x, 4)) + + if (CODEC_IS(QUICKTIME_DV) || + CODEC_IS(QUICKTIME_DVSD)) return CODEC_ID_DVVIDEO; + + if (CODEC_IS(QUICKTIME_MP4V) || + CODEC_IS(QUICKTIME_DIVX)) return CODEC_ID_MPEG4; + + return CODEC_ID_NONE; + + #undef CODEC_IS + } + + PixelFormat FFMPEG::color_model_to_pix_fmt(int color_model) { + switch (color_model) + { + case BC_YUV422: + return PIX_FMT_YUYV422; + case BC_RGB888: + return PIX_FMT_RGB24; + case BC_BGR8888: // NOTE: order flipped + return PIX_FMT_RGBA; + case BC_BGR888: + return PIX_FMT_BGR24; + case BC_YUV420P: + return PIX_FMT_YUV420P; + case BC_YUV422P: + return PIX_FMT_YUV422P; + case BC_YUV444P: + return PIX_FMT_YUV444P; + case BC_YUV411P: + return PIX_FMT_YUV411P; + case BC_RGB565: + return PIX_FMT_RGB565; + }; + + return PIX_FMT_NB; + } + + int FFMPEG::pix_fmt_to_color_model(PixelFormat pix_fmt) { + switch (pix_fmt) + { + case PIX_FMT_YUYV422: + return BC_YUV422; + case PIX_FMT_RGB24: + return BC_RGB888; + case PIX_FMT_RGBA: + return BC_BGR8888; + case PIX_FMT_BGR24: + return BC_BGR888; + case PIX_FMT_YUV420P: + return BC_YUV420P; + case PIX_FMT_YUV422P: + return BC_YUV422P; + case PIX_FMT_YUV444P: + return BC_YUV444P; + case PIX_FMT_YUV411P: + return BC_YUV411P; + case PIX_FMT_RGB565: + return BC_RGB565; + }; + + return BC_TRANSPARENCY; + } + + int FFMPEG::init_picture_from_frame(AVPicture *picture, VFrame *frame) { + int cmodel = frame->get_color_model(); + PixelFormat pix_fmt = color_model_to_pix_fmt(cmodel); + + int size = avpicture_fill(picture, frame->get_data(), pix_fmt, + frame->get_w(), frame->get_h()); + + if (size < 0) { + printf("FFMPEG::init_picture failed\n"); + return 1; + } + + if (cmodel_is_planar(frame->get_color_model())) { + // override avpicture_fill() for planar types + picture->data[0] = frame->get_y(); + picture->data[1] = frame->get_u(); + picture->data[2] = frame->get_v(); + } + + return size; + } + + + int FFMPEG::convert_cmodel(VFrame *frame_in, VFrame *frame_out) { + + PixelFormat pix_fmt_in = + color_model_to_pix_fmt(frame_in->get_color_model()); + PixelFormat pix_fmt_out = + color_model_to_pix_fmt(frame_out->get_color_model()); + #ifdef HAVE_SWSCALER + // We need a context for swscale + struct SwsContext *convert_ctx; + #endif + // do conversion within libavcodec if possible + if (pix_fmt_in != PIX_FMT_NB && pix_fmt_out != PIX_FMT_NB) { + // set up a temporary pictures from frame_in and frame_out + AVPicture picture_in, picture_out; + init_picture_from_frame(&picture_in, frame_in); + init_picture_from_frame(&picture_out, frame_out); + int result; + #ifndef HAVE_SWSCALER + result = img_convert(&picture_out, + pix_fmt_out, + &picture_in, + pix_fmt_in, + frame_in->get_w(), + frame_out->get_h()); + if (result) { + printf("FFMPEG::convert_cmodel img_convert() failed\n"); + } + #else + convert_ctx = sws_getContext(frame_in->get_w(), frame_in->get_h(),pix_fmt_in, + frame_out->get_w(),frame_out->get_h(),pix_fmt_out, + SWS_BICUBIC, NULL, NULL, NULL); + + if(convert_ctx == NULL){ + printf("FFMPEG::convert_cmodel : swscale context initialization failed\n"); + return 1; + } + + result = sws_scale(convert_ctx, + picture_in.data, picture_in.linesize, + frame_in->get_w(), frame_in->get_h(), + picture_out.data, picture_out.linesize); + + + sws_freeContext(convert_ctx); + + if(result){ + printf("FFMPEG::convert_cmodel sws_scale() failed\n"); + } + #endif + return result; + } + + + // failing the fast method, use the failsafe cmodel_transfer() + return convert_cmodel_transfer(frame_in, frame_out); + } + + int FFMPEG::convert_cmodel_transfer(VFrame *frame_in, VFrame *frame_out) { + + // WARNING: cmodel_transfer is said to be broken with BC_YUV411P + cmodel_transfer + (// Packed data out + frame_out->get_rows(), + // Packed data in + frame_in->get_rows(), + + // Planar data out + frame_out->get_y(), frame_out->get_u(), frame_out->get_v(), + // Planar data in + frame_in->get_y(), frame_in->get_u(), frame_in->get_v(), + + // Dimensions in + 0, 0, frame_in->get_w(), frame_in->get_h(), + // Dimensions out + 0, 0, frame_out->get_w(), frame_out->get_h(), + + // Color models + frame_in->get_color_model(), frame_out->get_color_model(), + + // Background color + 0, + + // Rowspans (of luma for YUV) + frame_in->get_w(), frame_out->get_w() + + ); + + return 0; + } + + + int FFMPEG::convert_cmodel(AVPicture *picture_in, PixelFormat pix_fmt_in, + int width_in, int height_in, VFrame *frame_out) { + + // set up a temporary picture_out from frame_out + AVPicture picture_out; + init_picture_from_frame(&picture_out, frame_out); + int cmodel_out = frame_out->get_color_model(); + PixelFormat pix_fmt_out = color_model_to_pix_fmt(cmodel_out); + + #ifdef HAVE_SWSCALER + // We need a context for swscale + struct SwsContext *convert_ctx; + #endif + int result; + #ifndef HAVE_SWSCALER + // do conversion within libavcodec if possible + if (pix_fmt_out != PIX_FMT_NB) { + result = img_convert(&picture_out, + pix_fmt_out, + picture_in, + pix_fmt_in, + width_in, + height_in); + if (result) { + printf("FFMPEG::convert_cmodel img_convert() failed\n"); + } + return result; + } + #else + convert_ctx = sws_getContext(width_in, height_in,pix_fmt_in, + frame_out->get_w(),frame_out->get_h(),pix_fmt_out, + SWS_BICUBIC, NULL, NULL, NULL); + + if(convert_ctx == NULL){ + printf("FFMPEG::convert_cmodel : swscale context initialization failed\n"); + return 1; + } + + result = sws_scale(convert_ctx, + picture_in->data, picture_in->linesize, + width_in, height_in, + picture_out.data, picture_out.linesize); + + + sws_freeContext(convert_ctx); + + if(result){ + printf("FFMPEG::convert_cmodel sws_scale() failed\n"); + } + #endif + + // make an intermediate temp frame only if necessary + int cmodel_in = pix_fmt_to_color_model(pix_fmt_in); + if (cmodel_in == BC_TRANSPARENCY) { + if (pix_fmt_in == PIX_FMT_RGBA) { + // avoid infinite recursion if things are broken + printf("FFMPEG::convert_cmodel pix_fmt_in broken!\n"); + return 1; + } + + // NOTE: choose RGBA8888 as a hopefully non-lossy colormodel + VFrame *temp_frame = new VFrame(0, -1, width_in, height_in, + BC_RGBA8888, -1); + if (convert_cmodel(picture_in, pix_fmt_in, + width_in, height_in, temp_frame)) { + delete temp_frame; + return 1; // recursed call will print error message + } + + int result = convert_cmodel(temp_frame, frame_out); + delete temp_frame; + return result; + } + + + // NOTE: no scaling possible in img_convert() so none possible here + if (frame_out->get_w() != width_in || + frame_out->get_h() != height_in) { + printf("scaling from %sx%s to %sx%x not allowed\n", + width_in, height_in, + frame_out->get_w(), frame_out->get_h()); + return 1; + } + + + // if we reach here we know that cmodel_transfer() will work + uint8_t *yuv_in[3] = {0,0,0}; + uint8_t *row_pointers_in[height_in]; + if (cmodel_is_planar(cmodel_in)) { + yuv_in[0] = picture_in->data[0]; + yuv_in[1] = picture_in->data[1]; + yuv_in[2] = picture_in->data[2]; + } + else { + // set row pointers for picture_in + uint8_t *data = picture_in->data[0]; + int bytes_per_line = + cmodel_calculate_pixelsize(cmodel_in) * height_in; + for (int i = 0; i < height_in; i++) { + row_pointers_in[i] = data + i * bytes_per_line; + } + } + + cmodel_transfer + (// Packed data out + frame_out->get_rows(), + // Packed data in + row_pointers_in, + + // Planar data out + frame_out->get_y(), frame_out->get_u(), frame_out->get_v(), + // Planar data in + yuv_in[0], yuv_in[1], yuv_in[2], + + // Dimensions in + 0, 0, width_in, height_in, // NOTE: dimensions are same + // Dimensions out + 0, 0, width_in, height_in, + + // Color model in, color model out + cmodel_in, cmodel_out, + + // Background color + 0, + + // Rowspans in, out (of luma for YUV) + width_in, width_in + + ); + + return 0; + } + + int FFMPEG::decode(uint8_t *data, long data_size, VFrame *frame_out) { + + // NOTE: frame must already have data space allocated + + got_picture = 0; + int length = avcodec_decode_video(context, + picture, + &got_picture, + data, + data_size); + + if (length < 0) { + printf("FFMPEG::decode error decoding frame\n"); + return 1; + } + + if (! got_picture) { + // signal the caller there is no picture yet + return FFMPEG_LATENCY; + } + + int result = convert_cmodel((AVPicture *)picture, + context->pix_fmt, + asset->width, + asset->height, + frame_out); + + return result; + } diff -crN cinelerra-4.4/cinelerra/ffmpeg.h cinelerra-4.4-ejo/cinelerra/ffmpeg.h *** cinelerra-4.4/cinelerra/ffmpeg.h Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/ffmpeg.h Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,43 ---- + #ifndef FFMPEG_H + #define FFMPEG_H + + extern "C" { + #include + } + + #include "asset.h" + #include "guicast.h" + + #define FFMPEG_LATENCY -9 + + class FFMPEG + { + public: + FFMPEG(Asset *asset_in); + ~FFMPEG(); + int init(char *codec_string); + int decode(uint8_t *data, long data_size, VFrame *frame_out); + + static int convert_cmodel(AVPicture *picture_in, PixelFormat pix_fmt, + int width_in, int height_in, + VFrame *frame_out); + static int convert_cmodel(VFrame *frame_in, VFrame *frame_out); + + static int convert_cmodel_transfer(VFrame *frame_in,VFrame *frame_out); + static int init_picture_from_frame(AVPicture *picture, VFrame *frame); + + static CodecID codec_id(char *codec_string); + + private: + static PixelFormat color_model_to_pix_fmt(int color_model); + static int pix_fmt_to_color_model(PixelFormat pix_fmt); + + int got_picture; + Asset *asset; + AVCodec *codec; + AVCodecContext *context; + AVFrame *picture; + }; + + + #endif /* FFMPEG_H */ diff -crN cinelerra-4.4/cinelerra/file.C cinelerra-4.4-ejo/cinelerra/file.C *** cinelerra-4.4/cinelerra/file.C Mon Feb 27 20:21:02 2012 --- cinelerra-4.4-ejo/cinelerra/file.C Fri Dec 28 23:32:42 2012 *************** *** 47,52 **** --- 47,54 ---- #include "filethread.h" #include "filetiff.h" #include "filevorbis.h" + #include "fileyuv.h" + #include "formattools.h" #include "filexml.h" #include "formatwindow.h" #include "framecache.h" *************** *** 151,163 **** } } ! int File::get_options(BC_WindowBase *parent_window, ! ArrayList *plugindb, ! Asset *asset, int audio_options, int video_options, char *locked_compressor) { getting_options = 1; format_completion->lock("File::get_options"); switch(asset->format) --- 153,166 ---- } } ! int File::get_options(FormatTools *format, int audio_options, int video_options, char *locked_compressor) { + BC_WindowBase *parent_window = format->window; + ArrayList *plugindb = format->plugindb; + Asset *asset = format->asset; getting_options = 1; format_completion->lock("File::get_options"); switch(asset->format) *************** *** 231,236 **** --- 234,246 ---- audio_options, video_options); break; + case FILE_YUV: + FileYUV::get_parameters(parent_window, + asset, + format_window, + video_options, + format); + break; case FILE_FLAC: FileFLAC::get_parameters(parent_window, asset, *************** *** 580,585 **** --- 590,602 ---- fclose(stream); file = new FileEXR(this->asset, this); } + else + if(FileYUV::check_sig(this->asset)) + { + // YUV file + fclose(stream); + file = new FileYUV(this->asset, this); + } else if(FileFLAC::check_sig(this->asset, test)) { *************** *** 698,703 **** --- 715,724 ---- file = new FileEXR(this->asset, this); break; + case FILE_YUV: + file = new FileYUV(this->asset, this); + break; + case FILE_FLAC: file = new FileFLAC(this->asset, this); break; *************** *** 2098,2103 **** --- 2119,2126 ---- else if(!strcasecmp(format, _(EXR_LIST_NAME))) return FILE_EXR_LIST; else + if(!strcasecmp(format, _(YUV_NAME))) return FILE_YUV; + else if(!strcasecmp(format, _(FLAC_NAME))) return FILE_FLAC; else if(!strcasecmp(format, _(CR2_NAME))) return FILE_CR2; *************** *** 2192,2197 **** --- 2215,2223 ---- case FILE_EXR_LIST: return _(EXR_LIST_NAME); break; + case FILE_YUV: + return _(YUV_NAME); + break; case FILE_MPEG: return _(MPEG_NAME); break; *************** *** 2368,2373 **** --- 2394,2403 ---- case FILE_EXR_LIST: return FileEXR::get_best_colormodel(asset, driver); break; + + case FILE_YUV: + return FileYUV::get_best_colormodel(asset, driver); + break; case FILE_PNG: case FILE_PNG_LIST: *************** *** 2478,2483 **** --- 2508,2514 ---- case FILE_CR2_LIST: case FILE_EXR: case FILE_EXR_LIST: + case FILE_YUV: case FILE_PNG: case FILE_PNG_LIST: case FILE_TGA: *************** *** 2538,2543 **** --- 2569,2575 ---- case FILE_AVI: return "avi"; case FILE_EXR: return "exr"; case FILE_EXR_LIST: return "exr"; + case FILE_YUV: return "m2v"; case FILE_FLAC: return "flac"; case FILE_JPEG: return "jpg"; case FILE_JPEG_LIST: return "jpg"; diff -crN cinelerra-4.4/cinelerra/file.h cinelerra-4.4-ejo/cinelerra/file.h *** cinelerra-4.4/cinelerra/file.h Sun Sep 4 01:13:28 2011 --- cinelerra-4.4-ejo/cinelerra/file.h Fri Dec 28 23:32:42 2012 *************** *** 37,42 **** --- 37,43 ---- #include "filethread.inc" #include "filexml.inc" #include "formatwindow.inc" + #include "formattools.h" #include "framecache.inc" #include "guicast.h" #include "mutex.inc" *************** *** 60,68 **** // Get attributes for various file formats. // The dither parameter is carried over from recording, where dither is done at the device. ! int get_options(BC_WindowBase *parent_window, ! ArrayList *plugindb, ! Asset *asset, int audio_options, int video_options, char *locked_compressor); --- 61,67 ---- // Get attributes for various file formats. // The dither parameter is carried over from recording, where dither is done at the device. ! int get_options(FormatTools *format, int audio_options, int video_options, char *locked_compressor); diff -crN cinelerra-4.4/cinelerra/file.inc cinelerra-4.4-ejo/cinelerra/file.inc *** cinelerra-4.4/cinelerra/file.inc Sat Dec 10 17:36:10 2011 --- cinelerra-4.4-ejo/cinelerra/file.inc Fri Dec 28 23:32:42 2012 *************** *** 66,71 **** --- 66,72 ---- #define FILE_EXR 26 #define FILE_EXR_LIST 27 #define FILE_CR2 28 + #define FILE_YUV 29 #define FILE_CR2_LIST 35 #define FILE_VORBIS 31 #define FILE_FFMPEG 33 *************** *** 77,82 **** --- 78,116 ---- // For formats supported by plugins, the format number is the plugin number in the // plugin list ORed with 0x8000. + #define FILE_FORMAT_PREFIX(format) ( \ + format == FILE_AIFF ? "AIFF" : \ + format == FILE_AMPEG ? "MPEG" : \ + format == FILE_AC3 ? "AC3" : \ + format == FILE_AU ? "AU" : \ + format == FILE_AVI_ARNE1 ? "AVI_ARNE1" : \ + format == FILE_AVI ? "AVI" : \ + format == FILE_AVI_ARNE2 ? "AVI_ARNE2" : \ + format == FILE_AVI_AVIFILE ? "AVIFILE" : \ + format == FILE_AVI_LAVTOOLS ? "AVI_LAVTOOLS" : \ + format == FILE_GIF ? "GIF" : \ + format == FILE_JPEG ? "JPEG" : \ + format == FILE_JPEG_LIST ? "JPEG_LIST" : \ + format == FILE_MOV ? "MOV" : \ + format == FILE_MPEG ? "MPEG" : \ + format == FILE_PCM ? "PCM" : \ + format == FILE_PLUGIN ? "PLUGIN" : \ + format == FILE_PNG ? "PNG" : \ + format == FILE_PNG_LIST ? "PNG_LIST" : \ + format == FILE_SND ? "SND" : \ + format == FILE_TGA ? "TGA" : \ + format == FILE_TGA_LIST ? "TGA_LIST" : \ + format == FILE_TIFF ? "TIFF" : \ + format == FILE_TIFF_LIST ? "TIFF_LIST" : \ + format == FILE_VMPEG ? "VMPEG" : \ + format == FILE_VORBIS ? "VORBIS" : \ + format == FILE_WAV ? "WAV" : \ + format == FILE_EXR ? "EXR" : \ + format == FILE_EXR_LIST ? "EXR_LIST" : \ + format == FILE_OGG ? "OGG" : \ + format == FILE_YUV ? "YUV" : \ + "UNKNOWN") + #if 0 N_("AC3") N_("Apple/SGI AIFF") *************** *** 139,144 **** --- 173,179 ---- #define CR2_NAME "Raw Camera" #define EXR_NAME "EXR" #define EXR_LIST_NAME "EXR Sequence" + #define YUV_NAME "YUV4MPEG Stream" #define FLAC_NAME "FLAC" #define FFMPEG_NAME "FFMPEG" diff -crN cinelerra-4.4/cinelerra/filejpeg.C cinelerra-4.4-ejo/cinelerra/filejpeg.C *** cinelerra-4.4/cinelerra/filejpeg.C Sat Dec 3 00:43:43 2011 --- cinelerra-4.4-ejo/cinelerra/filejpeg.C Fri Dec 28 23:32:42 2012 *************** *** 31,36 **** --- 31,37 ---- #include "quicktime.h" #include "vframe.h" #include "videodevice.inc" + #include #include diff -crN cinelerra-4.4/cinelerra/filemov.C cinelerra-4.4-ejo/cinelerra/filemov.C *** cinelerra-4.4/cinelerra/filemov.C Mon Nov 7 19:15:44 2011 --- cinelerra-4.4-ejo/cinelerra/filemov.C Fri Dec 28 23:32:42 2012 *************** *** 36,41 **** --- 36,42 ---- #include "videodevice.inc" #include + #include #if 0 N_("MPEG-4") diff -crN cinelerra-4.4/cinelerra/fileogg.C cinelerra-4.4-ejo/cinelerra/fileogg.C *** cinelerra-4.4/cinelerra/fileogg.C Tue Aug 16 23:01:38 2011 --- cinelerra-4.4-ejo/cinelerra/fileogg.C Fri Dec 28 23:32:42 2012 *************** *** 43,48 **** --- 43,49 ---- #include #define READ_SIZE 66000 + #define PACKAGE_STRING "libFlac 1.1.4" /* This code was aspired by ffmpeg2theora */ /* Special thanks for help on this code goes out to j@v2v.cc */ diff -crN cinelerra-4.4/cinelerra/filepng.C cinelerra-4.4-ejo/cinelerra/filepng.C *** cinelerra-4.4/cinelerra/filepng.C Tue Aug 16 23:01:38 2011 --- cinelerra-4.4-ejo/cinelerra/filepng.C Fri Dec 28 23:32:42 2012 *************** *** 29,35 **** #include "vframe.h" #include "videodevice.inc" ! #include FilePNG::FilePNG(Asset *asset, File *file) : FileList(asset, file, "PNGLIST", ".png", FILE_PNG, FILE_PNG_LIST) --- 29,35 ---- #include "vframe.h" #include "videodevice.inc" ! #include FilePNG::FilePNG(Asset *asset, File *file) : FileList(asset, file, "PNGLIST", ".png", FILE_PNG, FILE_PNG_LIST) diff -crN cinelerra-4.4/cinelerra/fileyuv.C cinelerra-4.4-ejo/cinelerra/fileyuv.C *** cinelerra-4.4/cinelerra/fileyuv.C Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/fileyuv.C Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,473 ---- + #include "fileyuv.h" + #include "asset.h" + #include "bchash.h" + #include "edit.h" + #include "file.h" + #include "guicast.h" + #include "guicast.h" + #include "interlacemodes.h" + #include "quicktime.h" + #include "mainerror.h" + #include "mwindow.h" + #include "vframe.h" + + #include + #include + #include + #include + #include + + FileYUV::FileYUV(Asset *asset, File *file) + : FileBase(asset, file) + { + if (asset->format == FILE_UNKNOWN) asset->format = FILE_YUV; + asset->byte_order = 0; // FUTURE: is this always correct? + temp = 0; + ffmpeg = 0; + stream = new YUVStream(); + pipe_latency = 0; + } + + FileYUV::~FileYUV() + { + // NOTE: close_file() is already called + delete stream; + } + + int FileYUV::open_file(int should_read, int should_write) + { + int result; + + if (should_read) + { + result = stream->open_read(asset->path); + if (result) return result; + + // NOTE: no easy way to defer setting video_length + asset->video_length = stream->frame_count; + + asset->width = stream->get_width(); + asset->height = stream->get_height(); + if (asset->width * asset->height <= 0) + { + printf("illegal frame size '%d x %d'\n", asset->width, asset->height); + return 1; + } + + asset->layers = 1; + asset->video_data = 1; + asset->audio_data = 0; + + asset->frame_rate = stream->get_frame_rate(); + asset->aspect_ratio = stream->get_aspect_ratio(); + // asset->interlace_mode = stream->get_interlace(); + asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED; + + return 0; + } + + if (should_write) { + if (asset->use_pipe) { + result = stream->open_write(asset->path, asset->pipe); + } else { + result = stream->open_write(asset->path, NULL); + } + if (result) return result; + + // not sure if we're supposed to send interlace info with each set of frames, (wouldn't know howto!)?? + // stream->set_interlace(asset->interlace_mode); + stream->set_interlace(BC_ILACE_MODE_NOTINTERLACED); + stream->set_width(asset->width); + stream->set_height(asset->height); + stream->set_frame_rate(asset->frame_rate); + stream->set_aspect_ratio(asset->aspect_ratio); + + result = stream->write_header(); + if (result) return result; + + return 0; + } + + // no action given + return 1; + } + + int FileYUV::close_file() { + if (pipe_latency && ffmpeg && stream) { + // deal with last frame still in the pipe + ensure_temp(incoming_asset->width, incoming_asset->height); + if (ffmpeg->decode(NULL, 0, temp) == 0) + { + uint8_t *yuv[3]; + yuv[0] = temp->get_y(); + yuv[1] = temp->get_u(); + yuv[2] = temp->get_v(); + stream->write_frame(yuv); + } + pipe_latency = 0; + } + stream->close_fd(); + if (ffmpeg) delete ffmpeg; + ffmpeg = 0; + return 0; + } + + // NOTE: set_video_position() called every time a frame is read + int FileYUV::set_video_position(int64_t frame_number) { + return stream->seek_frame(frame_number); + } + + int FileYUV::read_frame(VFrame *frame) + { + int result; + VFrame *input = frame; + + // short cut for direct copy routines + if (frame->get_color_model() == BC_COMPRESSED) { + long frame_size = (long) // w*h + w*h/4 + w*h/4 + (stream->get_height() * stream->get_width() * 1.5); + frame->allocate_compressed_data(frame_size); + frame->set_compressed_size(frame_size); + return stream->read_frame_raw(frame->get_data(), frame_size); + } + + + // process through a temp frame if necessary + if (! cmodel_is_planar(frame->get_color_model()) || + (frame->get_w() != stream->get_width()) || + (frame->get_h() != stream->get_height())) + { + ensure_temp(stream->get_width(), stream->get_height()); + input = temp; + } + + uint8_t *yuv[3]; + yuv[0] = input->get_y(); + yuv[1] = input->get_u(); + yuv[2] = input->get_v(); + result = stream->read_frame(yuv); + if (result) return result; + + // transfer from the temp frame to the real one + if (input != frame) + { + FFMPEG::convert_cmodel(input, frame); + } + + return 0; + } + + int FileYUV::write_frames(VFrame ***layers, int len) + { + int result; + + // only one layer supported + VFrame **frames = layers[0]; + VFrame *frame; + + for (int n = 0; n < len; n++) + { + frame = frames[n]; + + // short cut for direct copy routines + if (frame->get_color_model() == BC_COMPRESSED) + { + long frame_size = frame->get_compressed_size(); + if (incoming_asset->format == FILE_YUV) + return stream->write_frame_raw(frame->get_data(), frame_size); + + // decode and write an encoded frame + if (FFMPEG::codec_id(incoming_asset->vcodec) != CODEC_ID_NONE) + { + if (! ffmpeg) + { + ffmpeg = new FFMPEG(incoming_asset); + ffmpeg->init(incoming_asset->vcodec); + } + + ensure_temp(incoming_asset->width, incoming_asset->height); + int result = ffmpeg->decode(frame->get_data(), frame_size, temp); + + // some formats are decoded one frame later + if (result == FFMPEG_LATENCY) + { + // remember to write the last frame + pipe_latency++; + return 0; + } + + if (result) + { + delete ffmpeg; + ffmpeg = 0; + return 1; + } + + + uint8_t *yuv[3]; + yuv[0] = temp->get_y(); + yuv[1] = temp->get_u(); + yuv[2] = temp->get_v(); + return stream->write_frame(yuv); + } + } + + // process through a temp frame only if necessary + if (! cmodel_is_planar(frame->get_color_model()) || + (frame->get_w() != stream->get_width()) || + (frame->get_h() != stream->get_height())) + { + ensure_temp(asset->width, asset->height); + FFMPEG::convert_cmodel(frame, temp); + frame = temp; + } + + uint8_t *yuv[3]; + yuv[0] = frame->get_y(); + yuv[1] = frame->get_u(); + yuv[2] = frame->get_v(); + result = stream->write_frame(yuv); + if (result) return result; + } + + return 0; + } + + + void FileYUV::get_parameters(BC_WindowBase *parent_window, + Asset *asset, + BC_WindowBase* &format_window, + int video_options, + FormatTools *format) + { + if (! video_options) return; + + YUVConfigVideo *config = new YUVConfigVideo(parent_window, asset, format); + format_window = config; + config->create_objects(); + if (config->run_window() == 0) + { + // save the new path and pipe to the asset + strcpy(asset->path, config->path_textbox->get_text()); + strcpy(asset->pipe, config->pipe_textbox->get_text()); + // are we using the pipe (if there is one) + asset->use_pipe = config->pipe_checkbox->get_value(); + // update the path textbox in the render window + format->path_textbox->update(asset->path); + // add the new path and pipe to the defaults list + const char *prefix = FILE_FORMAT_PREFIX(asset->format); + config->path_recent->add_item(prefix, asset->path); + config->pipe_recent->add_item(prefix, asset->pipe); + } + delete config; + } + + int FileYUV::check_sig(Asset *asset) + { + char temp[9]; + FILE *f = fopen(asset->path, "rb"); + + // check for starting with "YUV4MPEG2" + fread(&temp, 9, 1, f); + fclose(f); + if (strncmp(temp, "YUV4MPEG2", 9) == 0) return 1; + + return 0; + } + + // NOTE: this is called on the write stream, not the read stream! + // as such, I have no idea what one is supposed to do with position. + int FileYUV::can_copy_from(Edit *edit, int64_t position) + { + // NOTE: width and height already checked in file.C + + // FUTURE: is the incoming asset already available somewhere? + incoming_asset = edit->asset; + + if (edit->asset->format == FILE_YUV) return 1; + + // if FFMPEG can decode it, we'll accept it + if (FFMPEG::codec_id(edit->asset->vcodec) != CODEC_ID_NONE) return 1; + + incoming_asset = 0; + + return 0; + } + + int FileYUV::get_best_colormodel(Asset *asset, int driver) + { + // FUTURE: is there a reason to try to accept anything else? + return BC_YUV420P; + } + + + int FileYUV::colormodel_supported(int color_model) + { + // we convert internally to any color model proposed + return color_model; + // NOTE: file.C does not convert from YUV, so we have to do it. + } + + + /* + Other member functions used in other file* modules: + + write_compressed_frame(): used for record, so probably not needed + read_compressed_frame(): perhaps never used? + get_video_position: used by record only + reset_parameters(): not sure when used or needed + reset_parameters_derived(): not sure when used or needed + *_audio_*: yuv4mpeg doesn't handle audio + + */ + + + + void FileYUV::ensure_temp(int width, int height) + { + // make sure the temp is correct size and type + if (temp && (temp->get_w() != width || + temp->get_h() != height || + temp->get_color_model() != BC_YUV420P)) + { + delete temp; + temp = 0; + } + + // create a correct temp frame if we don't have one + if (temp == 0) + { + temp = new VFrame(0, -1, width, height, BC_YUV420P, -1); + } + } + + + YUVConfigVideo::YUVConfigVideo(BC_WindowBase *parent_window, Asset *asset, FormatTools *format) + : BC_Window(PROGRAM_NAME ": YUV4MPEG Stream", + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), + 500, + 240) + { + this->parent_window = parent_window; + this->asset = asset; + this->format = format; + this->defaults = format->mwindow->defaults; + } + + YUVConfigVideo::~YUVConfigVideo() + { + delete path_textbox; + delete path_recent; + delete pipe_checkbox; + delete pipe_textbox; + delete pipe_recent; + delete mpeg2enc; + delete ffmpeg; + } + + void YUVConfigVideo::create_objects() + { + BC_Title *bt; + int init_x = 10; + int init_y = 10; + + int x = init_x; + int y = init_y; + + add_subwindow(new BC_Title(init_x, y, _("Output Path:"))); + add_subwindow(path_textbox = new BC_TextBox(init_x + 100, y, 350, 1, asset->path)); + add_subwindow(path_recent = new BC_RecentList("PATH", defaults, path_textbox, 10, init_x + 450, y, path_textbox->get_w(), 100)); + path_recent->load_items(FILE_FORMAT_PREFIX(asset->format)); + + x = init_x; + y += 30; + + add_subwindow(bt = new BC_Title(init_x, y, _("Use Pipe:"))); + add_subwindow(pipe_checkbox = new PipeCheckBox(init_x + bt->get_w(), y, asset->use_pipe)); + add_subwindow(pipe_textbox = new BC_TextBox(init_x + 100, y, 350, 1, asset->pipe)); + add_subwindow(pipe_recent = new BC_RecentList("PIPE", defaults, pipe_textbox, 10, init_x + 450, y, pipe_textbox->get_w(), 100)); + pipe_recent->load_items(FILE_FORMAT_PREFIX(asset->format)); + + pipe_checkbox->textbox = pipe_textbox; + if (!asset->use_pipe) pipe_textbox->disable(); + + x = init_x; + y += 30; + add_subwindow(new BC_Title(x, y, _("Stream Header:"), MEDIUMFONT, RED)); + + x = init_x + 20; + y += 30; + add_subwindow(bt = new BC_Title(x, y, _("Interlacing:"))); + char string[BCTEXTLEN]; + // ilacemode_to_text(string,asset->interlace_mode); + ilacemode_to_text(string,BC_ILACE_MODE_NOTINTERLACED); + add_subwindow(new BC_Title(x + bt->get_w() + 5, y, string, MEDIUMFONT, YELLOW)); + + x = init_x; + y += 30; + add_subwindow(new BC_Title(x, y, _("Pipe Presets:"))); + + x += 130; + add_subwindow(mpeg2enc = new PipePreset(x, y, "mpeg2enc", pipe_textbox, pipe_checkbox)); + // NOTE: the '%' character will be replaced by the current path + // NOTE: to insert a real '%' double it up: '%%' -> '%' + // NOTE: preset items must have a '|' before the actual command + mpeg2enc->add_item(new BC_MenuItem ("(DVD) | mpeg2enc -f 8 -o %")); + mpeg2enc->add_item(new BC_MenuItem ("(VCD) | mpeg2enc -f 2 -o %")); + + x += 180; + add_subwindow(ffmpeg = new PipePreset(x, y, "ffmpeg", pipe_textbox, pipe_checkbox)); + ffmpeg->add_item(new BC_MenuItem("(DVD) | ffmpeg -f yuv4mpegpipe -i - -y -target dvd -ilme -ildct -hq -f mpeg2video %")); + ffmpeg->add_item(new BC_MenuItem("(VCD) | ffmpeg -f yuv4mpegpipe -i - -y -target vcd -hq -f mpeg2video %")); + + add_subwindow(new BC_OKButton(this)); + add_subwindow(new BC_CancelButton(this)); + show_window(); + } + + int YUVConfigVideo::close_event() + { + set_done(0); + return 1; + } + + + PipeCheckBox::PipeCheckBox(int x, int y, int value) + : BC_CheckBox(x, y, value) + { + this->textbox = 0; + } + + int PipeCheckBox::handle_event() + { + if (textbox) + if (get_value()) + textbox->enable(); + else + textbox->disable(); + } + + + PipePreset::PipePreset(int x, int y, char *title, BC_TextBox *textbox, BC_CheckBox *checkbox) + : BC_PopupMenu(x, y, 150, title) + { + this->pipe_textbox = textbox; + this->pipe_checkbox =checkbox; + this->title = title; + } + + int PipePreset::handle_event() + { + char *text = get_text(); + // NOTE: preset items must have a '|' before the actual command + char *pipe = strchr(text, '|'); + // pipe + 1 to skip over the '|' + if (pipe) pipe_textbox->update(pipe + 1); + + pipe_textbox->enable(); + pipe_checkbox->set_value(1, 1); + + // menuitem sets the title after selection but we reset it + set_text(title); + } diff -crN cinelerra-4.4/cinelerra/fileyuv.h cinelerra-4.4-ejo/cinelerra/fileyuv.h *** cinelerra-4.4/cinelerra/fileyuv.h Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/fileyuv.h Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,94 ---- + #ifndef FILEYUV_H + #define FILEYUV_H + + #include "yuvstream.h" + #include "file.inc" + #include "filelist.h" + #include "vframe.inc" + #include "formattools.h" + #include "ffmpeg.h" + + class PipeCheckBox; + class PipePreset; + + class FileYUV : public FileBase + { + public: + FileYUV(Asset *asset, File *file); + ~FileYUV(); + + static void get_parameters(BC_WindowBase *parent_window, + Asset *asset, + BC_WindowBase* &format_window, + int video_options, FormatTools *format); + + int open_file(int rd, int wr); + static int check_sig(Asset *asset); + static int get_best_colormodel(Asset *asset, int driver); + int colormodel_supported(int colormodel); + int read_frame(VFrame *frame); + int write_frames(VFrame ***frame, int len); + int can_copy_from(Edit *edit, int64_t position); + int close_file(); + int set_video_position(int64_t x); + + // below here are local routines not required by interface + void ensure_temp(int width, int height); + + private: + VFrame *temp; + YUVStream *stream; + Asset *incoming_asset; + FFMPEG *ffmpeg; + int pipe_latency; + }; + + + class YUVConfigVideo : public BC_Window + { + public: + YUVConfigVideo(BC_WindowBase *parent_window, Asset *asset, + FormatTools *format); + ~YUVConfigVideo(); + + void create_objects(); + int close_event(); + + BC_WindowBase *parent_window; + Asset *asset; + FormatTools *format; + BC_Hash *defaults; + BC_TextBox *path_textbox; + BC_RecentList *path_recent; + PipeCheckBox *pipe_checkbox; + BC_TextBox *pipe_textbox; + BC_RecentList *pipe_recent; + PipePreset *mpeg2enc; + PipePreset *ffmpeg; + }; + + + class PipeCheckBox : public BC_CheckBox + { + public: + PipeCheckBox(int x, int y, int value); + int handle_event(); + BC_TextBox *textbox; + }; + + + + class PipePreset : public BC_PopupMenu + { + public: + PipePreset(int x, int y, char *title, BC_TextBox *textbox, BC_CheckBox *checkbox); + int handle_event(); + + private: + BC_TextBox *pipe_textbox; + BC_CheckBox *pipe_checkbox; + char *title; + }; + + + #endif diff -crN cinelerra-4.4/cinelerra/formatpopup.C cinelerra-4.4-ejo/cinelerra/formatpopup.C *** cinelerra-4.4/cinelerra/formatpopup.C Wed Jul 23 00:30:59 2008 --- cinelerra-4.4-ejo/cinelerra/formatpopup.C Fri Dec 28 23:32:42 2012 *************** *** 66,71 **** --- 66,72 ---- format_items.append(new BC_ListBoxItem(_(AVI_NAME))); format_items.append(new BC_ListBoxItem(_(EXR_NAME))); format_items.append(new BC_ListBoxItem(_(EXR_LIST_NAME))); + format_items.append(new BC_ListBoxItem(_(YUV_NAME))); format_items.append(new BC_ListBoxItem(_(WAV_NAME))); format_items.append(new BC_ListBoxItem(_(MOV_NAME))); format_items.append(new BC_ListBoxItem(_(AMPEG_NAME))); diff -crN cinelerra-4.4/cinelerra/formattools.C cinelerra-4.4-ejo/cinelerra/formattools.C *** cinelerra-4.4/cinelerra/formattools.C Thu Aug 25 22:57:36 2011 --- cinelerra-4.4-ejo/cinelerra/formattools.C Fri Dec 28 23:32:42 2012 *************** *** 605,613 **** void FormatAThread::run() { ! file->get_options(format->window, ! format->plugindb, ! format->asset, 1, 0, 0); --- 605,611 ---- void FormatAThread::run() { ! file->get_options(format, 1, 0, 0); *************** *** 656,664 **** void FormatVThread::run() { ! file->get_options(format->window, ! format->plugindb, ! format->asset, 0, 1, format->locked_compressor); --- 654,660 ---- void FormatVThread::run() { ! file->get_options(format, 0, 1, format->locked_compressor); diff -crN cinelerra-4.4/cinelerra/mjpegobjs cinelerra-4.4-ejo/cinelerra/mjpegobjs *** cinelerra-4.4/cinelerra/mjpegobjs Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/mjpegobjs Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,17 ---- + ../thirdparty/mjpegtools-1.9.0rc3/utils/cpu_accel.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mjpeg_logging.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/motionsearch.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mpegconsts.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mpegtimecode.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/yuv4mpeg.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/yuv4mpeg_ratio.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/build_sub22_mests.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/build_sub44_mests.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/find_best_one_pel.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/mblock_bsad_mmx.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/mblock_bsumsq_mmx.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/mblock_sad_mmx.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/mblock_sad_mmxe.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/mblock_sub44_sads_x86.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/mblock_sumsq_mmx.o + ../thirdparty/mjpegtools-1.9.0rc3/utils/mmxsse/motion.o diff -crN cinelerra-4.4/cinelerra/pipe.C cinelerra-4.4-ejo/cinelerra/pipe.C *** cinelerra-4.4/cinelerra/pipe.C Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/pipe.C Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,145 ---- + #include + #include + #include + #include + + #include "bchash.h" + #include "file.h" + #include "guicast.h" + #include "interlacemodes.h" + #include "pipe.h" + + extern "C" + { + int pipe_sigpipe_received; + + void pipe_handle_sigpipe(int signum) + { + printf("Received sigpipe\n"); + pipe_sigpipe_received++; + } + } + + Pipe::Pipe(char *command, char *sub_str, char sub_char) + { + this->command = command; + this->sub_str = sub_str; + this->sub_char = sub_char; + + complete[0] = '\0'; + file = NULL; + fd = -1; + + // FUTURE: could probably set to SIG_IGN once things work + signal(SIGPIPE, pipe_handle_sigpipe); + } + + Pipe::~Pipe() + { + close(); + } + + int Pipe::substitute() + { + if (command == NULL) + { + strcpy(complete, ""); + return 0; + } + + if (sub_str == NULL || sub_char == '\0') + { + strcpy(complete, command); + return 0; + } + + int count = 0; + char *c = command; + char *f = complete; + while (*c) + { + // directly copy anything substitution char + if (*c != sub_char) + { + *f++ = *c++; + continue; + } + + // move over the substitution character + c++; + + // two substitution characters in a row is literal + if (*c == sub_char) { + *f++ = *c++; + continue; + } + + // insert the file string at the substitution point + if (f + strlen(sub_str) - complete > sizeof(complete)) + { + printf("Pipe::substitute(): max length exceeded\n"); + return -1; + } + strcpy(f, sub_str); + f += strlen(sub_str); + count++; + } + + return count; + } + + + + int Pipe::open(char *mode) + { + if (file) close(); + + if (mode == NULL) + { + printf("Pipe::open(): no mode given\n"); + return 1; + } + + if (substitute() < 0) + return 1; + + if (complete == NULL || strlen(complete) == 0) + { + printf("Pipe::open(): no pipe to open\n"); + return 1; + } + + printf("trying popen(%s)\n", complete); + file = popen(complete, mode); + if (file != NULL) + { + fd = fileno(file); + return 0; + } + + // NOTE: popen() fails only if fork/exec fails + // there is no immediate way to see if command failed + // As such, one must expect to raise SIGPIPE on failure + printf("Pipe::open(%s,%s) failed: %s\n", + complete, mode, strerror(errno)); + return 1; + } + + int Pipe::open_read() + { + return open("r"); + } + + int Pipe::open_write() + { + return open("w"); + } + + void Pipe::close() + { + if(file){ + pclose(file); + file = 0; + fd = -1; + } + } diff -crN cinelerra-4.4/cinelerra/pipe.h cinelerra-4.4-ejo/cinelerra/pipe.h *** cinelerra-4.4/cinelerra/pipe.h Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/pipe.h Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,32 ---- + #ifndef PIPE_H + #define PIPE_H + + #include + #include "guicast.h" + #include "asset.h" + + extern "C" { + extern int sigpipe_received; + } + + class Pipe { + public: + Pipe(char *command, char *sub_str = 0, char sub_char = '%'); + ~Pipe() ; + int open_read() ; + int open_write() ; + void close() ; + + int fd; + private: + int substitute() ; + int open(char *mode) ; + + char sub_char; + char *sub_str; + char *command; + char complete[BCTEXTLEN]; + FILE *file; + }; + + #endif /* PIPE_H */ diff -crN cinelerra-4.4/cinelerra/vdevicebuz.C cinelerra-4.4-ejo/cinelerra/vdevicebuz.C *** cinelerra-4.4/cinelerra/vdevicebuz.C Mon Jul 25 00:39:58 2011 --- cinelerra-4.4-ejo/cinelerra/vdevicebuz.C Fri Dec 28 23:32:42 2012 *************** *** 53,59 **** #include #include #include ! #define READ_TIMEOUT 5000000 --- 53,59 ---- #include #include #include ! #include #define READ_TIMEOUT 5000000 diff -crN cinelerra-4.4/cinelerra/videodevice.C cinelerra-4.4-ejo/cinelerra/videodevice.C *** cinelerra-4.4/cinelerra/videodevice.C Mon Aug 29 00:14:13 2011 --- cinelerra-4.4-ejo/cinelerra/videodevice.C Fri Dec 28 23:32:42 2012 *************** *** 50,55 **** --- 50,56 ---- #include #include + #include KeepaliveThread::KeepaliveThread(VideoDevice *device) : Thread() diff -crN cinelerra-4.4/cinelerra/yuvstream.C cinelerra-4.4-ejo/cinelerra/yuvstream.C *** cinelerra-4.4/cinelerra/yuvstream.C Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/yuvstream.C Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,286 ---- + #include + #include + #include + + #define MJPEGTOOLS_Y4M_WRITE_FRAME_HEADER__3ARGS 1 + + #include "guicast.h" + #include "pipe.h" + #include "yuvstream.h" + #include "interlacemodes.h" + #include "mainerror.h" + + YUVStream::YUVStream() { + y4m_init_stream_info(&stream_info); + y4m_init_frame_info(&frame_info); + stream_fd = -1; + stream_pipe= 0; + frame_count = 0; + frame_index = 0; + } + + YUVStream::~YUVStream() { + y4m_fini_stream_info(&stream_info); + y4m_fini_frame_info(&frame_info); + if (frame_index) delete frame_index; + close_fd(); + } + + + int YUVStream::open_read(char *path) { + // NOTE: reading from pipes would be very difficult without temp files + stream_fd = open(path, O_RDONLY); + + if (stream_fd < 0) { + printf("Error while opening \"%s\" for reading. \n%m\n", path); + return 1; + } + + int result = read_header(); + if (result != Y4M_OK) { + printf("Bad YUV4MPEG2 header: %s\n", y4m_strerr(result)); + return 1; + } + + // generate index to frame position if not done yet + if (frame_index == 0) { + if (make_index() != 0) { + return 1; + } + } + + return 0; + } + + // NOTE: path is opened as a pipe if contains '|' + int YUVStream::open_write(char *path, char *pipe) { + if (pipe && *pipe) { + // skip over the '|' if present + if (char *p = strchr(path, '|')) { + pipe = p + 1; + } + + stream_pipe = new Pipe(pipe, path); + if (stream_pipe->open_write() == 0) { + stream_fd = stream_pipe->fd; + return 0; + } + return 1; + } + + stream_fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0666); + if (stream_fd > 0) return 0; + + printf("Error while opening \"%s\" for writing. \n%m\n", path); + return 1; + } + + + void YUVStream::close_fd() { + if (stream_pipe) { + stream_pipe->close(); + stream_pipe = 0; + stream_fd = -1; + } + + if (stream_fd >= 0) close(stream_fd); + stream_fd = -1; + } + + int YUVStream::read_frame(uint8_t *yuv[3]) { + int result = y4m_read_frame(stream_fd, &stream_info, + &frame_info, yuv); + if (result != Y4M_OK) { + if (result != Y4M_ERR_EOF) { + printf("read_frame() failed: %s\n", + y4m_strerr(result)); + } + return 1; + } + + return 0; + } + + int YUVStream::read_frame_raw(uint8_t *data, long frame_size) { + #if (MJPEGTOOLS_Y4M_WRITE_FRAME_HEADER__3ARGS) + int result = y4m_read_frame_header(stream_fd, &stream_info, &frame_info); + #else + int result = y4m_read_frame_header(stream_fd, &frame_info); + #endif + if (result != Y4M_OK) { + printf("y4m_read_frame_header() failed: %s\n", + y4m_strerr(result)); + return 1; + } + result = y4m_read(stream_fd, data, frame_size); + if (result != Y4M_OK) { + printf("y4m_read(%d) failed: %s\n", + frame_size, y4m_strerr(result)); + return 1; + } + return 0; + } + + int YUVStream::write_frame(uint8_t *yuv[3]) { + int result = y4m_write_frame(stream_fd, &stream_info, + &frame_info, yuv); + if (result != Y4M_OK) { + printf("write_frame() failed: %s\n", y4m_strerr(result)); + return 1; + } + return 0; + } + int YUVStream::write_frame_raw(uint8_t *data, long frame_size) { + #if (MJPEGTOOLS_Y4M_WRITE_FRAME_HEADER__3ARGS) + int result = y4m_write_frame_header(stream_fd, &stream_info, &frame_info); + #else + int result = y4m_write_frame_header(stream_fd, &frame_info); + #endif + if (result != Y4M_OK) { + printf("y4m_write_frame_header() failed: %s\n", + y4m_strerr(result)); + return 1; + } + result = y4m_write(stream_fd, data, frame_size); + if (result != Y4M_OK) { + printf("y4m_write(%d) failed: %s\n", + frame_size, y4m_strerr(result)); + return 1; + } + return 0; + } + + int YUVStream::make_index() { + off_t position; + uint8_t *yuv[3]; + + // NOTE: make_index() must be called after read_header(). + + // NOTE: storing frame_index locally means it is destroyed too often. + // make_index() will be called 3 times per file. If this + // becomes a performance problem, the index should be cached. + // Storing in 'asset' helps some, but still is done twice. + if (frame_index) delete frame_index; + frame_index = new ArrayList; + + VFrame *frame = new VFrame(0, -1, get_width(), \ + get_height(), BC_YUV420P, -1); + yuv[0] = frame->get_y(); + yuv[1] = frame->get_u(); + yuv[2] = frame->get_v(); + + // note the start of the first frame + position = lseek(stream_fd, 0, SEEK_CUR); + + // reset the frame count + frame_count = 0; + + while (read_frame(yuv) == 0) { + // index is start position of each frame + frame_index->append(position); + position = lseek(stream_fd, 0, SEEK_CUR); + frame_count++; + } + + // rewind to the start of the first frame + lseek(stream_fd, frame_index->values[0], SEEK_SET); + + delete frame; + + return 0; + } + + int YUVStream::seek_frame(int64_t frame_number) { + if (frame_number > frame_count || + frame_number < 0 || + frame_index == 0) { + printf("seek_frame(%d) failed (frame_count=%d)\n", + frame_number, frame_count); + return 1; + } + + off_t position = frame_index->values[frame_number]; + if (position == 0) { + // because of header, position should never be zero + printf("seek_frame(%d): position was zero\n", frame_number); + } + + if (lseek(stream_fd, position, SEEK_SET) < 0) { + printf("lseek(%d) failed: %s\n", position, strerror(errno)); + return 1; + } + + return 0; + } + + int YUVStream::read_header() { + int result = y4m_read_stream_header(stream_fd, &stream_info); + if (result != Y4M_OK) { + printf("y4m_read_stream_header() failed: %s\n", + y4m_strerr(result)); + return 1; + } + return 0; + } + int YUVStream::write_header() { + int result = y4m_write_stream_header(stream_fd, &stream_info); + if (result != Y4M_OK) { + printf("y4m_write_stream_header() failed: %s\n", + y4m_strerr(result)); + return 1; + } + return 0; + } + + int YUVStream::get_interlace() { + return ilace_yuv4mpeg_to_bc(y4m_si_get_interlace(&stream_info)); + } + + void YUVStream::set_interlace(int imode) { + y4m_si_set_interlace(&stream_info, ilace_bc_to_yuv4mpeg(imode)); + } + + int YUVStream::get_width() { + return y4m_si_get_width(&stream_info); + } + void YUVStream::set_width(int width) { + y4m_si_set_width(&stream_info, width); + } + + int YUVStream::get_height() { + return y4m_si_get_height(&stream_info); + } + void YUVStream::set_height(int height) { + y4m_si_set_height(&stream_info, height); + } + + double YUVStream::get_frame_rate() { + y4m_ratio_t ratio = y4m_si_get_framerate(&stream_info); + double frame_rate = (double) ratio.n / (double) ratio.d; + return frame_rate; + } + void YUVStream::set_frame_rate(double frame_rate) { + y4m_ratio_t ratio = mpeg_conform_framerate(frame_rate); + y4m_si_set_framerate(&stream_info, ratio); + } + + // FUTURE: these seem like a mess, possibly because I don't + // properly understand "display aspect" vs "pixel aspect" + double YUVStream::get_aspect_ratio() { + y4m_ratio_t sar = y4m_si_get_sampleaspect(&stream_info); + mpeg_aspect_code_t code = + mpeg_guess_mpeg_aspect_code(2, sar, + get_width(), + get_height()); + y4m_ratio_t aspect_ratio = mpeg_framerate(code); + if (aspect_ratio.d == 0) return 0; + return (double) aspect_ratio.n / (double) aspect_ratio.d; + } + void YUVStream::set_aspect_ratio(double aspect_ratio) { + y4m_ratio_t ratio; + ratio.n = (int)(aspect_ratio * 10000); + ratio.d = 10000; + y4m_ratio_t sar = y4m_guess_sar(get_width(), get_height(), + ratio); + y4m_si_set_sampleaspect(&stream_info, sar); + } diff -crN cinelerra-4.4/cinelerra/yuvstream.h cinelerra-4.4-ejo/cinelerra/yuvstream.h *** cinelerra-4.4/cinelerra/yuvstream.h Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/cinelerra/yuvstream.h Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,57 ---- + #include + + #include "guicast.h" + #include "pipe.h" + + #ifndef HAVE_STDINT_H + #define HAVE_STDINT_H + #endif /* HAVE_STDINT_H */ + + #include + #include + + class YUVStream { + public: + YUVStream(); + ~YUVStream(); + + int open_read(char *path); + int open_write(char *path, char *pipe); + void close_fd(); + + int read_frame(uint8_t *yuv[3]); + int read_frame_raw(uint8_t *data, long frame_size); + + int write_frame(uint8_t *yuv[3]); + int write_frame_raw(uint8_t *data, long frame_size); + + int make_index(); + int seek_frame(int64_t frame_number); + + int read_header(); + int write_header(); + + int get_interlace(); + void set_interlace(int width); + + int get_width(); + void set_width(int width); + + int get_height(); + void set_height(int height); + + double get_frame_rate(); + void set_frame_rate(double frame_rate); + + double get_aspect_ratio(); + void set_aspect_ratio(double aspect_ratio); + + int64_t frame_count; + + int stream_fd; // used for files + private: + y4m_stream_info_t stream_info; + y4m_frame_info_t frame_info; + Pipe *stream_pipe; // used for pipes + ArrayList *frame_index; + }; diff -crN cinelerra-4.4/guicast/Makefile cinelerra-4.4-ejo/guicast/Makefile *** cinelerra-4.4/guicast/Makefile Sat Aug 13 02:15:44 2011 --- cinelerra-4.4-ejo/guicast/Makefile Fri Dec 28 23:32:42 2012 *************** *** 63,68 **** --- 63,69 ---- $(OBJDIR)/bcpot.o \ $(OBJDIR)/bcprogress.o \ $(OBJDIR)/bcprogressbox.o \ + $(OBJDIR)/bcrecentlist.o \ $(OBJDIR)/bcrename.o \ $(OBJDIR)/bcrepeater.o \ $(OBJDIR)/bcresources.o \ *************** *** 228,233 **** --- 229,235 ---- $(OBJDIR)/bcpot.o: bcpot.C $(OBJDIR)/bcprogress.o: bcprogress.C $(OBJDIR)/bcprogressbox.o: bcprogressbox.C + $(OBJDIR)/bcrecentlist.o: bcrecentlist.C $(OBJDIR)/bcrename.o: bcrename.C $(OBJDIR)/bcrepeater.o: bcrepeater.C $(OBJDIR)/bcresources.o: bcresources.C diff -crN cinelerra-4.4/guicast/bcrecentlist.C cinelerra-4.4-ejo/guicast/bcrecentlist.C *** cinelerra-4.4/guicast/bcrecentlist.C Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/guicast/bcrecentlist.C Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,112 ---- + #include + + #include "bchash.h" + #include "bctextbox.h" + #include "bclistbox.h" + #include "bclistboxitem.h" + #include "bcrecentlist.h" + + // NOTE: textbox can be NULL if no textbox is associated + BC_RecentList::BC_RecentList(const char *type, BC_Hash *defaults, + BC_TextBox *textbox, int max, + int x, int y, int w, int h) + : BC_ListBox(x, y, w, h, LISTBOX_TEXT, 0, 0, 0, 1, 0, 1) + { + this->type = type; + this->defaults = defaults; + this->textbox = textbox; + set_tooltip("Choose from recently used"); + } + + BC_RecentList::BC_RecentList(const char *type, BC_Hash *defaults, + BC_TextBox *textbox) + : BC_ListBox(textbox->get_x() + textbox->get_w(), textbox->get_y(), + textbox->get_w(), RECENT_POPUP_HEIGHT, + LISTBOX_TEXT, 0, 0, 0, 1, 0, 1) + { + this->type = type; + this->defaults = defaults; + this->textbox = textbox; + set_tooltip("Choose from recently used"); + } + + BC_RecentList::BC_RecentList(const char *type, BC_Hash *defaults) + : BC_ListBox(-1, -1, -1, -1, LISTBOX_TEXT, 0, 0, 0, 1, 0, 1) + { + this->type = type; + this->defaults = defaults; + this->textbox = NULL; + } + + BC_RecentList::~BC_RecentList() { + items.remove_all_objects(); + } + + int BC_RecentList::handle_event() { + BC_ListBoxItem *item = get_selection(0, 0); + if (item < 0) return 0; + char *text = item->get_text(); + if (text && textbox) { + // change the text in the textbox + textbox->update(text); + // tell the textbox to deal with it + textbox->handle_event(); + } + return 0; + } + + + int BC_RecentList::load_items(const char *prefix) { + + if (! prefix) prefix = "ANY"; + + if (items.total > 0) { + items.remove_all_objects(); + } + + int count; + for (count = 0; count < RECENT_MAX_ITEMS; count++) { + char save[BCTEXTLEN]; + char text[BCTEXTLEN]; + sprintf(save, "RECENT_%s_%s_%d", prefix, type, count); + sprintf(text, ""); + defaults->get(save, text); + if (strlen(text) == 0) break; + items.append(new BC_ListBoxItem(text)); + } + + // only update if we are part of a window + if (textbox) update(&items, 0, 0, 1); + + return count; + } + + + int BC_RecentList::add_item(const char *prefix, char *text) { + + if (! prefix) prefix = "ANY"; + + // remove an old item if it matches the new text + for (int i = 0; i < items.total; i++) { + BC_ListBoxItem *item = items.values[i]; + if (strcmp(text, item->get_text()) == 0) { + items.remove_object(item); + } + } + + // make a new item and put it at the top of the list + items.insert(new BC_ListBoxItem(text), 0); + + // save up to maximum items of the list for future use + int count; + for (count = 0; + count < RECENT_MAX_ITEMS && count < items.total; + count++) { + BC_ListBoxItem *item = items.values[count]; + char save[BCTEXTLEN]; + sprintf(save, "RECENT_%s_%s_%d", prefix, type, count); + defaults->update(save, item->get_text()); + } + + return count; + } diff -crN cinelerra-4.4/guicast/bcrecentlist.h cinelerra-4.4-ejo/guicast/bcrecentlist.h *** cinelerra-4.4/guicast/bcrecentlist.h Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/guicast/bcrecentlist.h Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,38 ---- + #ifndef BCRECENTLIST_H + #define BCRECENTLIST_H + + #include "bchash.inc" + #include "bclistbox.h" + #include "bctextbox.inc" + + // Maintain a list of text items (up to 'max') from session to session. + // List automatically saved to Cinelerra_rc as 'RECENT_prefix_0', etc. + // Item value is written to 'text_box' when item is selected (if textbox set) + + #define RECENT_MAX_ITEMS 10 + #define RECENT_POPUP_HEIGHT 100 + + class BC_RecentList : public BC_ListBox + { + public: + BC_RecentList(const char *type, BC_Hash *defaults, + BC_TextBox *textbox, int max, + int x, int y, int w, int h); + BC_RecentList(const char *type, BC_Hash *defaults); + BC_RecentList(const char *type, BC_Hash *defaults, + BC_TextBox *textbox); + + ~BC_RecentList(); + + int handle_event(); + int load_items(const char *prefix = NULL); + int add_item(const char *prefix, char *text); + + ArrayList items; + private: + const char *type; + BC_TextBox *textbox; + BC_Hash *defaults; + }; + + #endif /* BCRECENTLIST_H */ diff -crN cinelerra-4.4/guicast/guicast.h cinelerra-4.4-ejo/guicast/guicast.h *** cinelerra-4.4/guicast/guicast.h Wed Jul 23 00:32:14 2008 --- cinelerra-4.4-ejo/guicast/guicast.h Fri Dec 28 23:32:42 2012 *************** *** 41,46 **** --- 41,47 ---- #include "bcpopupmenu.h" #include "bcpot.h" #include "bcprogress.h" + #include "bcrecentlist.h" #include "bcresources.h" #include "bcscrollbar.h" #include "bcslider.h" diff -crN cinelerra-4.4/mpeg2enc/cpu_accel.h cinelerra-4.4-ejo/mpeg2enc/cpu_accel.h *** cinelerra-4.4/mpeg2enc/cpu_accel.h Tue Jan 9 02:08:56 2007 --- cinelerra-4.4-ejo/mpeg2enc/cpu_accel.h Fri Dec 28 23:32:42 2012 *************** *** 26,29 **** --- 26,30 ---- #define ACCEL_X86_3DNOW 0x40000000 #define ACCEL_X86_MMXEXT 0x20000000 + #define cpu_accel cpu_accel_old int cpu_accel (void); diff -crN cinelerra-4.4/quicktime/Makefile cinelerra-4.4-ejo/quicktime/Makefile *** cinelerra-4.4/quicktime/Makefile Tue Mar 20 02:02:02 2012 --- cinelerra-4.4-ejo/quicktime/Makefile Fri Dec 28 23:32:42 2012 *************** *** 140,145 **** --- 140,146 ---- $(OBJDIR)/graphics.o \ $(OBJDIR)/hdlr.o \ $(OBJDIR)/ima4.o \ + $(OBJDIR)/interlacemodes.o \ $(OBJDIR)/jpeg.o \ $(OBJDIR)/libdv.o \ $(OBJDIR)/libmjpeg.o \ *************** *** 404,410 **** $(OBJDIR)/qtinfo.o \ $(OBJDIR)/rechunk.o \ $(OBJS): ! $(CC) -c `cat $(OBJDIR)/c_flags` $(subst $(OBJDIR)/,, $*.c) -o $*.o $(OBJDIR)/mts2mp4.o: $(CC) -c `cat $(OBJDIR)/c_flags` $(FFMPEG_INCLUDE) $(subst $(OBJDIR)/,, $*.c) -o $*.o --- 405,413 ---- $(OBJDIR)/qtinfo.o \ $(OBJDIR)/rechunk.o \ $(OBJS): ! $(CC) -c `cat $(OBJDIR)/c_flags` \ ! -I../thirdparty/mjpegtools-1.9.0rc3/utils \ ! $(subst $(OBJDIR)/,, $*.c) -o $*.o $(OBJDIR)/mts2mp4.o: $(CC) -c `cat $(OBJDIR)/c_flags` $(FFMPEG_INCLUDE) $(subst $(OBJDIR)/,, $*.c) -o $*.o *************** *** 482,487 **** --- 485,491 ---- $(OBJDIR)/graphics.o: graphics.c $(OBJDIR)/hdlr.o: hdlr.c $(OBJDIR)/ima4.o: ima4.c + $(OBJDIR)/interlacemodes.o: interlacemodes.c $(OBJDIR)/jpeg.o: jpeg.c $(OBJDIR)/libdv.o: libdv.c $(OBJDIR)/libmjpeg.o: libmjpeg.c diff -crN cinelerra-4.4/quicktime/interlacemodes.c cinelerra-4.4-ejo/quicktime/interlacemodes.c *** cinelerra-4.4/quicktime/interlacemodes.c Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/quicktime/interlacemodes.c Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,214 ---- + /* + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + #include + #include + #include + + #ifndef HAVE_STDINT_H + #define HAVE_STDINT_H + #endif /* HAVE_STDINT_H */ + + #include + + #include "interlacemodes.h" + + // AUTO FIX METHOD ==================== + + void ilaceautofixoption_to_text(char *string, int autofixoption) + { + switch(autofixoption) + { + case BC_ILACE_AUTOFIXOPTION_AUTO: strcpy(string, BC_ILACE_AUTOFIXOPTION_AUTO_T); break; + case BC_ILACE_AUTOFIXOPTION_MANUAL: strcpy(string, BC_ILACE_AUTOFIXOPTION_MANUAL_T); break; + default: strcpy(string, BC_ILACE_UNKNOWN_T); break; + } + } + + int ilaceautofixoption_from_text(char *text, int thedefault) + { + if(!strcasecmp(text, BC_ILACE_AUTOFIXOPTION_AUTO_T)) return BC_ILACE_AUTOFIXOPTION_AUTO; + if(!strcasecmp(text, BC_ILACE_AUTOFIXOPTION_MANUAL_T)) return BC_ILACE_AUTOFIXOPTION_MANUAL; + return thedefault; + } + + // INTERLACE MODE ==================== + + void ilacemode_to_text(char *string, int ilacemode) + { + switch(ilacemode) + { + case BC_ILACE_MODE_UNDETECTED: strcpy(string, BC_ILACE_MODE_UNDETECTED_T); break; + case BC_ILACE_MODE_TOP_FIRST: strcpy(string, BC_ILACE_MODE_TOP_FIRST_T); break; + case BC_ILACE_MODE_BOTTOM_FIRST: strcpy(string, BC_ILACE_MODE_BOTTOM_FIRST_T); break; + case BC_ILACE_MODE_NOTINTERLACED: strcpy(string, BC_ILACE_MODE_NOTINTERLACED_T); break; + default: strcpy(string, BC_ILACE_UNKNOWN_T); break; + } + } + + int ilacemode_from_text(char *text, int thedefault) + { + if(!strcasecmp(text, BC_ILACE_MODE_UNDETECTED_T)) return BC_ILACE_MODE_UNDETECTED; + if(!strcasecmp(text, BC_ILACE_MODE_TOP_FIRST_T)) return BC_ILACE_MODE_TOP_FIRST; + if(!strcasecmp(text, BC_ILACE_MODE_BOTTOM_FIRST_T)) return BC_ILACE_MODE_BOTTOM_FIRST; + if(!strcasecmp(text, BC_ILACE_MODE_NOTINTERLACED_T)) return BC_ILACE_MODE_NOTINTERLACED; + return thedefault; + } + + void ilacemode_to_xmltext(char *string, int ilacemode) + { + switch(ilacemode) + { + case BC_ILACE_MODE_UNDETECTED: strcpy(string, BC_ILACE_MODE_UNDETECTED_XMLT); break; + case BC_ILACE_MODE_TOP_FIRST: strcpy(string, BC_ILACE_MODE_TOP_FIRST_XMLT); break; + case BC_ILACE_MODE_BOTTOM_FIRST: strcpy(string, BC_ILACE_MODE_BOTTOM_FIRST_XMLT); break; + case BC_ILACE_MODE_NOTINTERLACED: strcpy(string, BC_ILACE_MODE_NOTINTERLACED_XMLT); break; + default: strcpy(string, BC_ILACE_UNKNOWN_T); break; + } + } + + int ilacemode_from_xmltext(char *text, int thedefault) + { + if(!text) return thedefault; + if(!strcasecmp(text, BC_ILACE_MODE_UNDETECTED_XMLT)) return BC_ILACE_MODE_UNDETECTED; + if(!strcasecmp(text, BC_ILACE_MODE_TOP_FIRST_XMLT)) return BC_ILACE_MODE_TOP_FIRST; + if(!strcasecmp(text, BC_ILACE_MODE_BOTTOM_FIRST_XMLT)) return BC_ILACE_MODE_BOTTOM_FIRST; + if(!strcasecmp(text, BC_ILACE_MODE_NOTINTERLACED_XMLT)) return BC_ILACE_MODE_NOTINTERLACED; + return thedefault; + } + + // INTERLACE FIX METHOD ==================== + + void ilacefixmethod_to_text(char *string, int fixmethod) + { + switch(fixmethod) + { + case BC_ILACE_FIXMETHOD_NONE: strcpy(string, BC_ILACE_FIXMETHOD_NONE_T); break; + case BC_ILACE_FIXMETHOD_UPONE: strcpy(string, BC_ILACE_FIXMETHOD_UPONE_T); break; + case BC_ILACE_FIXMETHOD_DOWNONE: strcpy(string, BC_ILACE_FIXMETHOD_DOWNONE_T); break; + default: strcpy(string, BC_ILACE_UNKNOWN_T); break; + } + } + + int ilacefixmethod_from_text(char *text, int thedefault) + { + if(!strcasecmp(text, BC_ILACE_FIXMETHOD_NONE_T)) return BC_ILACE_FIXMETHOD_NONE; + if(!strcasecmp(text, BC_ILACE_FIXMETHOD_UPONE_T)) return BC_ILACE_FIXMETHOD_UPONE; + if(!strcasecmp(text, BC_ILACE_FIXMETHOD_DOWNONE_T)) return BC_ILACE_FIXMETHOD_DOWNONE; + return thedefault; + } + + void ilacefixmethod_to_xmltext(char *string, int fixmethod) + { + switch(fixmethod) + { + case BC_ILACE_FIXMETHOD_NONE: strcpy(string, BC_ILACE_FIXMETHOD_NONE_XMLT); break; + case BC_ILACE_FIXMETHOD_UPONE: strcpy(string, BC_ILACE_FIXMETHOD_UPONE_XMLT); break; + case BC_ILACE_FIXMETHOD_DOWNONE: strcpy(string, BC_ILACE_FIXMETHOD_DOWNONE_XMLT); break; + default: strcpy(string, BC_ILACE_UNKNOWN_T); break; + } + } + + int ilacefixmethod_from_xmltext(char *text, int thedefault) + { + if(!strcasecmp(text, BC_ILACE_FIXMETHOD_NONE_XMLT)) return BC_ILACE_FIXMETHOD_NONE; + if(!strcasecmp(text, BC_ILACE_FIXMETHOD_UPONE_XMLT)) return BC_ILACE_FIXMETHOD_UPONE; + if(!strcasecmp(text, BC_ILACE_FIXMETHOD_DOWNONE_XMLT)) return BC_ILACE_FIXMETHOD_DOWNONE; + return thedefault; + } + + int ilaceautofixmethod(int projectmode, int assetmode) + { + if (projectmode == assetmode) + return BC_ILACE_FIXMETHOD_NONE; + + if ( + (projectmode == BC_ILACE_MODE_BOTTOM_FIRST && assetmode == BC_ILACE_MODE_TOP_FIRST ) + || + (projectmode == BC_ILACE_MODE_TOP_FIRST && assetmode == BC_ILACE_MODE_BOTTOM_FIRST) + ) + return BC_ILACE_FIXDEFAULT; + + // still to implement anything else... + return BC_ILACE_FIXMETHOD_NONE; + } + + int ilaceautofixmethod2(int projectilacemode, int assetautofixoption, int assetilacemode, int assetfixmethod) + { + if (assetautofixoption == BC_ILACE_AUTOFIXOPTION_AUTO) + return (ilaceautofixmethod(projectilacemode, assetilacemode)); + else + return (assetfixmethod); + } + + int ilace_bc_to_yuv4mpeg(int ilacemode) + { + switch (ilacemode) + { + case BC_ILACE_MODE_UNDETECTED: + return(Y4M_UNKNOWN); + break; + case BC_ILACE_MODE_TOP_FIRST: + return(Y4M_ILACE_TOP_FIRST); + break; + case BC_ILACE_MODE_BOTTOM_FIRST: + return(Y4M_ILACE_BOTTOM_FIRST); + break; + case BC_ILACE_MODE_NOTINTERLACED: + return(Y4M_ILACE_NONE); + break; + } + } + + int ilace_yuv4mpeg_to_bc(int ilacemode) + { + switch (ilacemode) + { + case Y4M_UNKNOWN: + return (BC_ILACE_MODE_UNDETECTED); + break; + case Y4M_ILACE_NONE: + return (BC_ILACE_MODE_NOTINTERLACED); + break; + case Y4M_ILACE_TOP_FIRST: + return (BC_ILACE_MODE_TOP_FIRST); + break; + case Y4M_ILACE_BOTTOM_FIRST: + return (BC_ILACE_MODE_BOTTOM_FIRST); + break; + // case Y4M_ILACE_MIXED: + // return (BC_ILACE_MODE_UNDETECTED); // fixme!! + // break; + default: + return (BC_ILACE_MODE_UNDETECTED); + } + } + + + void ilace_yuv4mpeg_mode_to_text(char *string, int ilacemode) + { + switch(ilacemode) + { + case Y4M_UNKNOWN: strcpy(string, BC_ILACE_Y4M_UKNOWN_T); break; + case Y4M_ILACE_NONE: strcpy(string, BC_ILACE_Y4M_NONE_T); break; + case Y4M_ILACE_TOP_FIRST: strcpy(string, BC_ILACE_Y4M_TOP_FIRST_T); break; + case Y4M_ILACE_BOTTOM_FIRST: strcpy(string, BC_ILACE_Y4M_BOTTOM_FIRST_T); break; + // case Y4M_ILACE_MIXED: strcpy(string, BC_ILACE_Y4M_MIXED_T); break; + + default: strcpy(string, BC_ILACE_UNKNOWN_T); break; + } + } diff -crN cinelerra-4.4/quicktime/interlacemodes.h cinelerra-4.4-ejo/quicktime/interlacemodes.h *** cinelerra-4.4/quicktime/interlacemodes.h Wed Dec 31 19:00:00 1969 --- cinelerra-4.4-ejo/quicktime/interlacemodes.h Fri Dec 28 23:32:42 2012 *************** *** 0 **** --- 1,100 ---- + /* + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + #ifndef INTERLACEMODES_H + #define INTERLACEMODES_H + + #define BC_ILACE_UNKNOWN_T "Error!" + + //Interlace Automatic fixing options + #define BC_ILACE_AUTOFIXOPTION_MANUAL 0 + #define BC_ILACE_AUTOFIXOPTION_MANUAL_T "Manual compensation using selection" + #define BC_ILACE_AUTOFIXOPTION_AUTO 1 + #define BC_ILACE_AUTOFIXOPTION_AUTO_T "Automatic compensation using modes" + //Note: Do not change what the numbers mean as this will make backward-compatability have erroraneous settings. + + //Interlace Modes + #define BC_ILACE_MODE_UNDETECTED 0 + #define BC_ILACE_MODE_UNDETECTED_XMLT "UNKNOWN" + #define BC_ILACE_MODE_UNDETECTED_T "Unknown" + #define BC_ILACE_MODE_TOP_FIRST 1 + #define BC_ILACE_MODE_TOP_FIRST_XMLT "TOP_FIELD_FIRST" + #define BC_ILACE_MODE_TOP_FIRST_T "Top Fields First" + #define BC_ILACE_MODE_BOTTOM_FIRST 2 + #define BC_ILACE_MODE_BOTTOM_FIRST_XMLT "BOTTOM_FIELD_FIRST" + #define BC_ILACE_MODE_BOTTOM_FIRST_T "Bottom Fields First" + #define BC_ILACE_MODE_NOTINTERLACED 3 + #define BC_ILACE_MODE_NOTINTERLACED_XMLT "NOTINTERLACED" + #define BC_ILACE_MODE_NOTINTERLACED_T "Not Interlaced" + + #define BC_ILACE_ASSET_MODEDEFAULT BC_ILACE_MODE_UNDETECTED + #define BC_ILACE_PROJECT_MODEDEFAULT BC_ILACE_MODE_NOTINTERLACED_T + //Note: Do not change what the numbers mean as this will make backward-compatability have erroraneous settings. + + //Interlace Compensation Methods + #define BC_ILACE_FIXMETHOD_NONE 0 + #define BC_ILACE_FIXMETHOD_NONE_XMLT "DO_NOTHING" + #define BC_ILACE_FIXMETHOD_NONE_T "Do Nothing" + #define BC_ILACE_FIXMETHOD_UPONE 1 + #define BC_ILACE_FIXMETHOD_UPONE_XMLT "SHIFT_UPONE" + #define BC_ILACE_FIXMETHOD_UPONE_T "Shift Up 1 pixel" + #define BC_ILACE_FIXMETHOD_DOWNONE 2 + #define BC_ILACE_FIXMETHOD_DOWNONE_XMLT "SHIFT_DOWNONE" + #define BC_ILACE_FIXMETHOD_DOWNONE_T "Shift Down 1 pixel" + + // the following is for project/asset having odd/even, or even/odd + #define BC_ILACE_FIXDEFAULT BC_ILACE_FIXMETHOD_UPONE + //Note: Do not change what the numbers mean as this will make backward-compatability have erroraneous settings. + + // Refer to (descriptions were cut-and-pasted!) + #define BC_ILACE_Y4M_UKNOWN_T "unknown" + #define BC_ILACE_Y4M_NONE_T "non-interlaced, progressive frame" + #define BC_ILACE_Y4M_TOP_FIRST_T "interlaced, top-field first" + #define BC_ILACE_Y4M_BOTTOM_FIRST_T "interlaced, bottom-field first" + #define BC_ILACE_Y4M_MIXED_T "mixed, \"refer to frame header\"" + + #ifdef __cplusplus + extern "C" { + #endif + + void ilaceautofixoption_to_text(char *string, int autofixoption); + int ilaceautofixoption_from_text(char *text, int thedefault); + + void ilacemode_to_text(char *string, int ilacemode); + int ilacemode_from_text(char *text, int thedefault); + void ilacemode_to_xmltext(char *string, int ilacemode); + int ilacemode_from_xmltext(char *text, int thedefault); + + void ilacefixmethod_to_text(char *string, int fixmethod); + int ilacefixmethod_from_text(char *text, int thedefault); + void ilacefixmethod_to_xmltext(char *string, int fixmethod); + int ilacefixmethod_from_xmltext(char *text, int thedefault); + + + int ilaceautofixmethod(int projectilacemode, int assetilacemode); + int ilaceautofixmethod2(int projectilacemode, int assetautofixoption, int assetilacemode, int assetfixmethod); + + int ilace_bc_to_yuv4mpeg(int ilacemode); + int ilace_yuv4mpeg_to_bc(int ilacemode); + + void ilace_yuv4mpeg_mode_to_text(char *string, int ilacemode); + + #ifdef __cplusplus + } + #endif + + #endif // INTERLACEMODES_H