From efc8fa7dc7ddcdeaa9398e09d81975a6ccf526fc Mon Sep 17 00:00:00 2001 From: Good Guy Date: Mon, 22 Jan 2018 18:29:12 -0700 Subject: [PATCH] add fileppm, fix renderfarm/brender deadlock, fix audio meters, add gbrp + cin_pix_fmt, ffmpeg plugin opengl bug fix, scaleratio add handle_opengl --- cinelerra-5.1/cinelerra/Makefile | 2 + cinelerra-5.1/cinelerra/amodule.C | 36 +-- cinelerra-5.1/cinelerra/amodule.h | 6 +- cinelerra-5.1/cinelerra/arender.C | 99 ++------ cinelerra-5.1/cinelerra/arender.h | 21 +- cinelerra-5.1/cinelerra/assetpopup.C | 18 +- cinelerra-5.1/cinelerra/assetpopup.inc | 2 + cinelerra-5.1/cinelerra/commonrender.C | 2 +- cinelerra-5.1/cinelerra/ffmpeg.C | 25 +- cinelerra-5.1/cinelerra/file.C | 31 +++ cinelerra-5.1/cinelerra/file.inc | 6 + cinelerra-5.1/cinelerra/fileppm.C | 224 ++++++++++++++++++ cinelerra-5.1/cinelerra/fileppm.h | 69 ++++++ cinelerra-5.1/cinelerra/fileppm.inc | 8 + cinelerra-5.1/cinelerra/formatpopup.C | 26 +- cinelerra-5.1/cinelerra/mainerror.C | 10 +- cinelerra-5.1/cinelerra/mainerror.h | 25 +- cinelerra-5.1/cinelerra/meterhistory.C | 78 ++++++ cinelerra-5.1/cinelerra/meterhistory.h | 24 ++ cinelerra-5.1/cinelerra/pluginfclient.C | 2 +- cinelerra-5.1/cinelerra/preferencesthread.C | 5 +- cinelerra-5.1/cinelerra/renderengine.C | 34 ++- cinelerra-5.1/cinelerra/virtualaconsole.C | 27 +-- cinelerra-5.1/cinelerra/virtualanode.C | 25 +- cinelerra-5.1/guicast/bccmdl.py | 33 ++- cinelerra-5.1/guicast/bccmodels.C | 58 +++-- cinelerra-5.1/guicast/bccmodels.h | 1 + cinelerra-5.1/guicast/bcwindowbase.C | 4 + cinelerra-5.1/guicast/test4.C | 6 +- cinelerra-5.1/guicast/vframe.C | 13 + cinelerra-5.1/guicast/xfer.C | 6 + cinelerra-5.1/guicast/xfer.h | 40 ++-- cinelerra-5.1/plugins/scaleratio/scaleratio.C | 27 +++ cinelerra-5.1/plugins/scaleratio/scaleratio.h | 2 +- .../plugins/scaleratio/scaleratiowin.C | 2 +- 35 files changed, 725 insertions(+), 272 deletions(-) create mode 100644 cinelerra-5.1/cinelerra/fileppm.C create mode 100644 cinelerra-5.1/cinelerra/fileppm.h create mode 100644 cinelerra-5.1/cinelerra/fileppm.inc create mode 100644 cinelerra-5.1/cinelerra/meterhistory.C create mode 100644 cinelerra-5.1/cinelerra/meterhistory.h diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile index a825fbc3..22bbdb23 100644 --- a/cinelerra-5.1/cinelerra/Makefile +++ b/cinelerra-5.1/cinelerra/Makefile @@ -116,6 +116,7 @@ OBJS = \ $(OBJDIR)/file.o \ $(OBJDIR)/fileogg.o \ $(OBJDIR)/filepng.o \ + $(OBJDIR)/fileppm.o \ $(OBJDIR)/filescene.o \ $(OBJDIR)/filesndfile.o \ $(OBJDIR)/filetga.o \ @@ -184,6 +185,7 @@ OBJS = \ $(OBJDIR)/menueffects.o \ $(OBJDIR)/menutransitionlength.o \ $(OBJDIR)/menuveffects.o \ + $(OBJDIR)/meterhistory.o \ $(OBJDIR)/meterpanel.o \ $(OBJDIR)/module.o \ $(OBJDIR)/mtimebar.o \ diff --git a/cinelerra-5.1/cinelerra/amodule.C b/cinelerra-5.1/cinelerra/amodule.C index 6ade03dd..aee3f5f0 100644 --- a/cinelerra-5.1/cinelerra/amodule.C +++ b/cinelerra-5.1/cinelerra/amodule.C @@ -150,11 +150,10 @@ AModule::AModule(RenderEngine *renderengine, data_type = TRACK_AUDIO; transition_temp = 0; speed_temp = 0; - level_history = 0; - current_level = 0; bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS); bzero(prev_head, SPEED_OVERLAP * sizeof(double)); bzero(prev_tail, SPEED_OVERLAP * sizeof(double)); + meter_history = new MeterHistory(); nested_allocation = 0; resample = 0; asset = 0; @@ -166,22 +165,11 @@ AModule::AModule(RenderEngine *renderengine, AModule::~AModule() { - if(transition_temp) delete transition_temp; - if(speed_temp) delete speed_temp; - if(level_history) - { - delete [] level_history; - delete [] level_samples; - } - + delete transition_temp; + delete speed_temp; + delete meter_history; for(int i = 0; i < MAX_CHANNELS; i++) - { - if(nested_output[i]) - { - delete nested_output[i]; - } - } - + delete nested_output[i]; delete resample; } @@ -195,17 +183,9 @@ void AModule::create_objects() { Module::create_objects(); // Not needed in pluginarray - if(commonrender) - { - level_history = new double[((ARender*)commonrender)->total_peaks]; - level_samples = new int64_t[((ARender*)commonrender)->total_peaks]; - current_level = 0; - - for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++) - { - level_history[i] = 0; - level_samples[i] = -1; - } + if( commonrender ) { + meter_history->init(1, ((ARender*)commonrender)->total_peaks); + meter_history->reset_channel(0); } } diff --git a/cinelerra-5.1/cinelerra/amodule.h b/cinelerra-5.1/cinelerra/amodule.h index d7bf72e1..6781d38c 100644 --- a/cinelerra-5.1/cinelerra/amodule.h +++ b/cinelerra-5.1/cinelerra/amodule.h @@ -40,6 +40,7 @@ class AModuleReset; #include "filexml.inc" #include "floatautos.inc" #include "maxchannels.h" +#include "meterhistory.h" #include "module.h" #include "resample.h" #include "samples.inc" @@ -102,10 +103,7 @@ public: FloatAutos* get_pan_automation(int channel); // get pan automation FloatAutos* get_fade_automation(); // get the fade automation for this module - - double *level_history; - int64_t *level_samples; - int current_level; + MeterHistory *meter_history; // Temporary buffer for rendering transitions Samples *transition_temp; diff --git a/cinelerra-5.1/cinelerra/arender.C b/cinelerra-5.1/cinelerra/arender.C index bbfe5906..7737f5d2 100644 --- a/cinelerra-5.1/cinelerra/arender.C +++ b/cinelerra-5.1/cinelerra/arender.C @@ -48,27 +48,20 @@ ARender::ARender(RenderEngine *renderengine) : CommonRender(renderengine) { // Clear output buffers - for(int i = 0; i < MAXCHANNELS; i++) - { + for( int i=0; i 0) - return total_peaks; - else - { + if( !total_peaks ) { meter_render_fragment = renderengine->fragment_len; + int tracking_fragment = renderengine->get_edl()->session->sample_rate / TRACKING_RATE; // This number and the timer in tracking.C determine the rate - while(meter_render_fragment > - renderengine->get_edl()->session->sample_rate / TRACKING_RATE) - meter_render_fragment /= 2; - total_peaks = 16 * - renderengine->fragment_len / - meter_render_fragment; - return total_peaks; + while( meter_render_fragment > tracking_fragment ) meter_render_fragment /= 2; + total_peaks = 16 * renderengine->fragment_len / meter_render_fragment; } + return total_peaks; } int ARender::init_meters() { // not providing enough peaks results in peaks that are ahead of the sound - if(level_samples) delete [] level_samples; - calculate_history_size(); - level_samples = new int64_t[total_peaks]; - - for(int i = 0; i < MAXCHANNELS;i++) - { - current_level[i] = 0; - if(buffer[i] && !level_history[i]) - level_history[i] = new double[total_peaks]; - } - - for(int i = 0; i < total_peaks; i++) - { - level_samples[i] = -1; - } - - for(int j = 0; j < MAXCHANNELS; j++) - { - if(buffer[j]) - for(int i = 0; i < total_peaks; i++) - level_history[j][i] = 0; + meter_history->init(MAXCHANNELS, calculate_history_size()); + for( int i=0; ireset_channel(i); } return 0; } void ARender::allocate_buffers(int samples) { - for(int i = 0; i < MAXCHANNELS; i++) - { + for( int i=0; i= renderengine->get_edl()->session->audio_channels ) { + delete buffer[i]; buffer[i] = 0; } - if(i < renderengine->get_edl()->session->audio_channels) - { + if( !buffer[i] && i < renderengine->get_edl()->session->audio_channels ) { buffer[i] = new Samples(samples); buffer_allocated[i] = samples; - audio_out[i] = buffer[i]; } + audio_out[i] = buffer[i]; } } @@ -246,26 +212,6 @@ int ARender::process_buffer(int64_t input_len, int64_t input_position) return result; } -int ARender::get_history_number(int64_t *table, int64_t position) -{ -// Get the entry closest to position - int result = 0; - int64_t min_difference = 0x7fffffff; - for(int i = 0; i < total_peaks; i++) - { - -//printf("%jd ", table[i]); - if(labs(table[i] - position) < min_difference) - { - min_difference = labs(table[i] - position); - result = i; - } - } -//printf("\n"); -//printf("ARender::get_history_number %jd %d\n", position, result); - return result; -} - void ARender::send_last_buffer() { if( renderengine->audio ) @@ -358,12 +304,3 @@ if(debug) printf("ARender::run %d\n", __LINE__); stop_plugins(); } - -int ARender::get_next_peak(int current_peak) -{ - current_peak++; - if(current_peak >= total_peaks) current_peak = 0; - return current_peak; -} - - diff --git a/cinelerra-5.1/cinelerra/arender.h b/cinelerra-5.1/cinelerra/arender.h index bfcf7b1a..a867e865 100644 --- a/cinelerra-5.1/cinelerra/arender.h +++ b/cinelerra-5.1/cinelerra/arender.h @@ -25,6 +25,7 @@ #include "atrack.inc" #include "commonrender.h" #include "maxchannels.h" +#include "meterhistory.h" #include "samples.inc" class ARender : public CommonRender @@ -66,9 +67,12 @@ public: // Calculate number of samples in each meter fragment and how many // meter fragments to buffer. + int init_meters(); int calculate_history_size(); -// Get subscript of history entry corresponding to sample - int get_history_number(int64_t *table, int64_t position); + int total_peaks; + MeterHistory *meter_history; +// samples to use for one meter update. Must be multiple of fragment_len + int64_t meter_render_fragment; int64_t tounits(double position, int round); double fromunits(int64_t position); @@ -79,19 +83,6 @@ public: Samples *buffer[MAXCHANNELS]; // allocated buffer sizes for nested EDL rendering int buffer_allocated[MAXCHANNELS]; -// information for meters - int get_next_peak(int current_peak); - int init_meters(); -// samples to use for one meter update. Must be multiple of fragment_len - int64_t meter_render_fragment; -// Level history of output buffers - double *level_history[MAXCHANNELS]; -// sample position of each level - int64_t *level_samples; -// total entries in level_history - int total_peaks; -// Next level to store value in - int current_level[MAXCHANNELS]; // Make VirtualAConsole block before the first buffer until video is ready int first_buffer; }; diff --git a/cinelerra-5.1/cinelerra/assetpopup.C b/cinelerra-5.1/cinelerra/assetpopup.C index cd3c703b..d39aaa13 100644 --- a/cinelerra-5.1/cinelerra/assetpopup.C +++ b/cinelerra-5.1/cinelerra/assetpopup.C @@ -430,12 +430,14 @@ void AssetListMenu::create_objects() snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("png"), SNAPSHOT_PNG)); snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("jpeg"), SNAPSHOT_JPEG)); snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("tiff"), SNAPSHOT_TIFF)); + snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("ppm"), SNAPSHOT_PPM)); GrabshotSubMenu *grabshot_submenu; add_item(asset_grabshot = new AssetGrabshot(mwindow, this)); asset_grabshot->add_submenu(grabshot_submenu = new GrabshotSubMenu(asset_grabshot)); grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("png"), GRABSHOT_PNG)); grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("jpeg"), GRABSHOT_JPEG)); grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("tiff"), GRABSHOT_TIFF)); + grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("ppm"), GRABSHOT_PPM)); update_titles(shots_displayed = 1); } @@ -747,7 +749,7 @@ int SnapshotMenuItem::handle_event() Preferences *preferences = mwindow->preferences; char filename[BCTEXTLEN]; - static const char *exts[] = { "png", "jpg", "tif" }; + static const char *exts[] = { "png", "jpg", "tif", "ppm" }; time_t tt; time(&tt); struct tm tm; localtime_r(&tt,&tm); snprintf(filename,sizeof(filename),"%s/%s_%04d%02d%02d-%02d%02d%02d.%s", @@ -772,6 +774,9 @@ int SnapshotMenuItem::handle_event() asset->tiff_cmodel = 0; asset->tiff_compression = 0; break; + case SNAPSHOT_PPM: + asset->format = FILE_PPM; + break; } asset->width = fw; asset->height = fh; @@ -964,7 +969,7 @@ int GrabshotPopup::grab_event(XEvent *event) MWindow *mwindow = grab_thread->mwindow; Preferences *preferences = mwindow->preferences; char filename[BCTEXTLEN]; - static const char *exts[] = { "png", "jpg", "tif" }; + static const char *exts[] = { "png", "jpg", "tif", "ppm" }; time_t tt; time(&tt); struct tm tm; localtime_r(&tt,&tm); snprintf(filename,sizeof(filename),"%s/%s_%04d%02d%02d-%02d%02d%02d.%s", @@ -974,19 +979,22 @@ int GrabshotPopup::grab_event(XEvent *event) Asset *asset = new Asset(filename); switch( mode ) { - case SNAPSHOT_PNG: + case GRABSHOT_PNG: asset->format = FILE_PNG; asset->png_use_alpha = 1; break; - case SNAPSHOT_JPEG: + case GRABSHOT_JPEG: asset->format = FILE_JPEG; asset->jpeg_quality = 90; break; - case SNAPSHOT_TIFF: + case GRABSHOT_TIFF: asset->format = FILE_TIFF; asset->tiff_cmodel = 0; asset->tiff_compression = 0; break; + case GRABSHOT_PPM: + asset->format = FILE_PPM; + break; } // no odd dimensions int rw = get_root_w(0), rh = get_root_h(0); diff --git a/cinelerra-5.1/cinelerra/assetpopup.inc b/cinelerra-5.1/cinelerra/assetpopup.inc index ed37dc4e..a4e77eb1 100644 --- a/cinelerra-5.1/cinelerra/assetpopup.inc +++ b/cinelerra-5.1/cinelerra/assetpopup.inc @@ -25,10 +25,12 @@ #define SNAPSHOT_PNG 0 #define SNAPSHOT_JPEG 1 #define SNAPSHOT_TIFF 2 +#define SNAPSHOT_PPM 3 #define GRABSHOT_PNG 0 #define GRABSHOT_JPEG 1 #define GRABSHOT_TIFF 2 +#define GRABSHOT_PPM 3 class AssetPopup; class AssetPopupInfo; diff --git a/cinelerra-5.1/cinelerra/commonrender.C b/cinelerra-5.1/cinelerra/commonrender.C index 32358c06..856858e5 100644 --- a/cinelerra-5.1/cinelerra/commonrender.C +++ b/cinelerra-5.1/cinelerra/commonrender.C @@ -127,7 +127,7 @@ void CommonRender::create_modules() { for(module = 0; module < total_modules; module++) { - modules[module]->create_objects(); + modules[module]->Module::create_objects(); } } } diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 0d3fe73a..9f87bc18 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -484,7 +484,7 @@ int FFStream::encode_frame(AVFrame *frame) ret = write_packet(opkt); if( ret < 0 ) break; ++pkts; - if( stats_fp ) { + if( frame && stats_fp ) { ret = write_stats_file(); if( ret < 0 ) break; } @@ -1047,6 +1047,7 @@ AVPixelFormat FFVideoConvert::color_model_to_pix_fmt(int color_model) case BC_RGB161616: return AV_PIX_FMT_RGB48LE; case BC_RGBA16161616: return AV_PIX_FMT_RGBA64LE; case BC_AYUV16161616: return AV_PIX_FMT_AYUV64LE; + case BC_GBRP: return AV_PIX_FMT_GBRP; default: break; } @@ -1072,6 +1073,7 @@ int FFVideoConvert::pix_fmt_to_color_model(AVPixelFormat pix_fmt) case AV_PIX_FMT_RGB48LE: return BC_RGB161616; case AV_PIX_FMT_RGBA64LE: return BC_RGBA16161616; case AV_PIX_FMT_AYUV64LE: return BC_AYUV16161616; + case AV_PIX_FMT_GBRP: return BC_GBRP; default: break; } @@ -2066,12 +2068,27 @@ int FFMPEG::open_encoder(const char *type, const char *spec) vstrm_index.append(ffidx(vidx, 0)); vid->avctx = ctx; ffvideo.append(vid); fst = vid; vid->width = asset->width; - ctx->width = (vid->width+3) & ~3; vid->height = asset->height; - ctx->height = (vid->height+3) & ~3; vid->frame_rate = asset->frame_rate; + AVPixelFormat pix_fmt = codec->pix_fmts ? + codec->pix_fmts[0] : AV_PIX_FMT_YUV420P; + AVDictionaryEntry *tag = av_dict_get(sopts, "cin_pix_fmt", NULL, 0); + if( tag != 0 ) { + int avfmt = av_get_pix_fmt(tag->value); + if( avfmt < 0 ) { + eprintf(_("cin_pix_fmt unknown = %s\n"), tag->value); + ret = 1; + break; + } + pix_fmt = (AVPixelFormat)avfmt; + } + ctx->pix_fmt = pix_fmt; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int mask_w = (1<log2_chroma_w)-1; + if( mask_w > 0 ) ctx->width = (vid->width+mask_w) & ~mask_w; + int mask_h = (1<log2_chroma_h)-1; + if( mask_h > 0 ) ctx->height = (vid->height+mask_h) & ~mask_h; ctx->sample_aspect_ratio = to_sample_aspect_ratio(asset); - ctx->pix_fmt = codec->pix_fmts ? codec->pix_fmts[0] : AV_PIX_FMT_YUV420P; AVRational frame_rate = check_frame_rate(codec, vid->frame_rate); if( !frame_rate.num || !frame_rate.den ) { eprintf(_("check_frame_rate failed %s\n"), filename); diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C index bc1a6290..67b731de 100644 --- a/cinelerra-5.1/cinelerra/file.C +++ b/cinelerra-5.1/cinelerra/file.C @@ -54,6 +54,7 @@ #undef HAVE_STDLIB_H // automake conflict #include "fileogg.h" #include "filepng.h" +#include "fileppm.h" #include "filescene.h" #include "filesndfile.h" #include "filetga.h" @@ -167,6 +168,7 @@ int File::get_options(FormatTools *format, //ArrayList *plugindb = format->plugindb; Asset *asset = format->asset; + format_window = 0; getting_options = 1; format_completion->lock("File::get_options"); switch( asset->format ) { @@ -221,6 +223,11 @@ int File::get_options(FormatTools *format, FilePNG::get_parameters(parent_window, asset, format_window, audio_options, video_options); break; + case FILE_PPM: + case FILE_PPM_LIST: + FilePPM::get_parameters(parent_window, asset, format_window, + audio_options, video_options); + break; case FILE_TGA: case FILE_TGA_LIST: FileTGA::get_parameters(parent_window, asset, format_window, @@ -336,6 +343,7 @@ const char *File::default_probes[] = { #endif "SndFile", "PNG", + "PPM", "JPEG", "GIF", #ifdef HAVE_OPENEXR @@ -400,6 +408,11 @@ int File::probe() file = new FilePNG(this->asset, this); return FILE_OK; } + if( !strcmp(pref->name,"PPM") ) { // PPM file + if( !FilePPM::check_sig(this->asset) ) continue; + file = new FilePPM(this->asset, this); + return FILE_OK; + } if( !strcmp(pref->name,"JPEG") ) { // JPEG file if( !FileJPEG::check_sig(this->asset) ) continue; file = new FileJPEG(this->asset, this); @@ -513,6 +526,11 @@ int File::open_file(Preferences *preferences, file = new FilePNG(this->asset, this); break; + case FILE_PPM: + case FILE_PPM_LIST: + file = new FilePPM(this->asset, this); + break; + case FILE_JPEG: case FILE_JPEG_LIST: file = new FileJPEG(this->asset, this); @@ -1204,6 +1222,8 @@ int File::strtoformat(const char *format) if( !strcasecmp(format, _(SND_NAME)) ) return FILE_SND; if( !strcasecmp(format, _(PNG_NAME)) ) return FILE_PNG; if( !strcasecmp(format, _(PNG_LIST_NAME)) ) return FILE_PNG_LIST; + if( !strcasecmp(format, _(PPM_NAME)) ) return FILE_PPM; + if( !strcasecmp(format, _(PPM_LIST_NAME)) ) return FILE_PPM_LIST; if( !strcasecmp(format, _(TIFF_NAME)) ) return FILE_TIFF; if( !strcasecmp(format, _(TIFF_LIST_NAME)) ) return FILE_TIFF_LIST; if( !strcasecmp(format, _(JPEG_NAME)) ) return FILE_JPEG; @@ -1240,6 +1260,8 @@ const char* File::formattostr(int format) case FILE_SND: return _(SND_NAME); case FILE_PNG: return _(PNG_NAME); case FILE_PNG_LIST: return _(PNG_LIST_NAME); + case FILE_PPM: return _(PPM_NAME); + case FILE_PPM_LIST: return _(PPM_LIST_NAME); case FILE_JPEG: return _(JPEG_NAME); case FILE_JPEG_LIST: return _(JPEG_LIST_NAME); case FILE_CR2: return _(CR2_NAME); @@ -1338,6 +1360,8 @@ int File::get_best_colormodel(Asset *asset, int driver) #endif case FILE_PNG: case FILE_PNG_LIST: return FilePNG::get_best_colormodel(asset, driver); + case FILE_PPM: + case FILE_PPM_LIST: return FilePPM::get_best_colormodel(asset, driver); case FILE_TGA: case FILE_TGA_LIST: return FileTGA::get_best_colormodel(asset, driver); case FILE_CR2: @@ -1390,6 +1414,8 @@ int File::renders_video(int format) case FILE_EXR_LIST: case FILE_PNG: case FILE_PNG_LIST: + case FILE_PPM: + case FILE_PPM_LIST: case FILE_TGA: case FILE_TGA_LIST: case FILE_TIFF: @@ -1440,6 +1466,7 @@ int File::is_image_render(int format) case FILE_EXR: case FILE_JPEG: case FILE_PNG: + case FILE_PPM: case FILE_TGA: case FILE_TIFF: return 1; @@ -1466,6 +1493,8 @@ const char* File::get_tag(int format) case FILE_PCM: return "pcm"; case FILE_PNG: return "png"; case FILE_PNG_LIST: return "png"; + case FILE_PPM: return "ppm"; + case FILE_PPM_LIST: return "ppm"; case FILE_TGA: return "tga"; case FILE_TGA_LIST: return "tga"; case FILE_TIFF: return "tif"; @@ -1484,6 +1513,7 @@ const char* File::get_prefix(int format) case FILE_PCM: return "PCM"; case FILE_WAV: return "WAV"; case FILE_PNG: return "PNG"; + case FILE_PPM: return "PPM"; case FILE_JPEG: return "JPEG"; case FILE_TIFF: return "TIFF"; case FILE_GIF: return "GIF"; @@ -1499,6 +1529,7 @@ const char* File::get_prefix(int format) case FILE_RAWDV: return "RAWDV"; case FILE_TIFF_LIST: return "TIFF_LIST"; case FILE_PNG_LIST: return "PNG_LIST"; + case FILE_PPM_LIST: return "PPM_LIST"; case FILE_AC3: return "AC3"; case FILE_EXR: return "EXR"; case FILE_EXR_LIST: return "EXR_LIST"; diff --git a/cinelerra-5.1/cinelerra/file.inc b/cinelerra-5.1/cinelerra/file.inc index b14162e3..8bcda4eb 100644 --- a/cinelerra-5.1/cinelerra/file.inc +++ b/cinelerra-5.1/cinelerra/file.inc @@ -89,6 +89,8 @@ #define FILE_CR2_LIST 35 #define FILE_GIF_LIST 36 #define FILE_DB 37 +#define FILE_PPM 38 +#define FILE_PPM_LIST 39 // For formats supported by plugins, the format number is the plugin number in the // plugin list ORed with 0x8000. @@ -114,6 +116,8 @@ N_("OGG Theora/Vorbis") N_("OGG Vorbis") // For decoding only N_("PNG") N_("PNG Sequence") +N_("PPM") +N_("PPM Sequence") N_("Raw DV") N_("Raw PCM") N_("Sun/NeXT AU") @@ -146,6 +150,8 @@ N_("Unknown sound") #define PCM_NAME "Raw PCM" #define PNG_LIST_NAME "PNG Sequence" #define PNG_NAME "PNG" +#define PPM_LIST_NAME "PPM Sequence" +#define PPM_NAME "PPM" #define RAWDV_NAME "Raw DV" #define SCENE_NAME "Text To Movie" #define SND_NAME "Unknown sound" diff --git a/cinelerra-5.1/cinelerra/fileppm.C b/cinelerra-5.1/cinelerra/fileppm.C new file mode 100644 index 00000000..ac991aa4 --- /dev/null +++ b/cinelerra-5.1/cinelerra/fileppm.C @@ -0,0 +1,224 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * 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 "asset.h" +#include "bccmodels.h" +#include "file.h" +#include "fileppm.h" +#include "interlacemodes.h" +#include "mainerror.h" + +#include +#include + + +FilePPM::FilePPM(Asset *asset, File *file) + : FileList(asset, file, "PPMLIST", ".ppm", FILE_PPM, FILE_PPM_LIST) +{ + reset(); + if( asset->format == FILE_UNKNOWN ) + asset->format = FILE_PPM; +} + +FilePPM::~FilePPM() +{ + close_file(); +} + +void FilePPM::reset() +{ +} + +int FilePPM::check_sig(Asset *asset) +{ + FILE *stream = fopen(asset->path, "r"); + if( stream ) { + char test[10]; + (void)fread(test, 10, 1, stream); + fclose(stream); + if( !strncmp("PPMLIST",test,6) ) return 1; + if( !strncmp("P6\n",test,3) ) return 1; + } + return 0; +} + +int FilePPM::check_frame_header(FILE *fp) +{ + char text[BCSTRLEN]; + if( !fgets(text, sizeof(text), fp) ) return 1; + if( strcmp("P6\n",text) ) return 1; + int ch = getc(fp); + while( ch == '#' ) { while( (ch=getc(fp))>=0 && ch!='\n' ); } + ungetc(ch,fp); + int w, h; + if( !fgets(text, sizeof(text), fp) || + sscanf(text, "%d %d\n", &w, &h) != 2 ) return 1; + if( !fgets(text, sizeof(text), fp) || + sscanf(text, "%d\n", &ch) != 1 || ch != 255 ) return 1; + + asset->width = w; asset->height = h; + asset->interlace_mode = ILACE_MODE_NOTINTERLACED; + return 0; +} + +int FilePPM::read_frame_header(char *path) +{ + int ret = 1; + FILE *fp = fopen(path, "r"); + if( fp ) { + ret = check_frame_header(fp); + fclose(fp); + } + return ret; +} + +int FilePPM::read_ppm(FILE *fp, VFrame *frame) +{ + int ch; + char text[BCSTRLEN]; + if( !fgets(text, sizeof(text), fp) ) return 1; + if( strcmp("P6\n",text) ) { + printf("FilePPM::read_ppm: header err\n"); + return 1; + } + while( (ch=getc(fp)) == '#' ) { while( (ch=getc(fp))>=0 && ch!='\n' ); } + ungetc(ch,fp); + int w, h; + if( !fgets(text, sizeof(text), fp) || + sscanf(text, "%d %d\n", &w, &h) != 2 ) { + printf("FilePPM::read_ppm: geom err\n"); + return 1; + } + if( w != frame->get_w() || h != frame->get_h() ) { + printf("FilePPM::read_ppm: geom mismatch\n"); + return 1; + } + if( !fgets(text, sizeof(text), fp) || + sscanf(text, "%d\n", &ch) != 1 || ch != 255 ) { + printf("FilePPM::read_ppm: mask err\n"); + return 1; + } + + unsigned char **rows = frame->get_rows(); + int bpl = 3*w; + for( int y=0; yfile = file; + temp_frame = 0; +} +PPMUnit::~PPMUnit() +{ + delete temp_frame; +} + +FrameWriterUnit* FilePPM::new_writer_unit(FrameWriter *writer) +{ + return new PPMUnit(this, writer); +} + +int FilePPM::write_frame(VFrame *frame, VFrame *output, + FrameWriterUnit *frame_writer_unit) +{ + int w = asset->width, h = asset->height; + char prefix[BCTEXTLEN]; + int pfx = sprintf(prefix, "P6\n%d %d\n%d\n", w, h, 255); + int bpl = 3*w, image_length = h*bpl, total_length = pfx + image_length; + if( output->get_compressed_allocated() < total_length ) { + int new_length = total_length + 255; + output->allocate_compressed_data(new_length); + } + unsigned char *dp = output->get_data(), *bp = dp; + memcpy(dp, prefix, pfx); dp += pfx; + unsigned char *rows[h+1], **rp = rows; + for( int y=h; --y>=0; dp+=bpl ) *rp++ = dp; + BC_CModels::transfer(rows, frame->get_rows(), + 0, 0, 0, frame->get_y(), frame->get_u(), frame->get_v(), + 0, 0, frame->get_w(), frame->get_h(), 0, 0, w, h, + frame->get_color_model(), BC_RGB888, 0, + frame->get_bytes_per_line(), bpl); + + output->set_compressed_size(dp - bp); + return 0; +} + +int FilePPM::colormodel_supported(int colormodel) +{ + return BC_RGB888; +} + +int FilePPM::get_best_colormodel(Asset *asset, int driver) +{ + return BC_RGB888; +} + +PPMConfigVideo::PPMConfigVideo(BC_WindowBase *gui, Asset *asset) + : BC_Window(_(PROGRAM_NAME ": Video Compression"), + gui->get_abs_cursor_x(1), gui->get_abs_cursor_y(1), 200, 100) +{ + this->gui = gui; + this->asset = asset; + lock_window("PPMConfigVideo::create_objects()"); + int x = 10, y = 10; + add_subwindow(new BC_Title(x, y, _("PPM, RGB raw only"))); + add_subwindow(new BC_OKButton(this)); + show_window(1); + unlock_window(); +} + +void FilePPM::get_parameters(BC_WindowBase *parent_window, Asset *asset, + BC_WindowBase* &format_window, int audio_options, int video_options) +{ + if(video_options) { + PPMConfigVideo *window = new PPMConfigVideo(parent_window, asset); + format_window = window; + window->run_window(); + delete window; + } +} + +int FilePPM::use_path() +{ + return 1; +} diff --git a/cinelerra-5.1/cinelerra/fileppm.h b/cinelerra-5.1/cinelerra/fileppm.h new file mode 100644 index 00000000..05f145d1 --- /dev/null +++ b/cinelerra-5.1/cinelerra/fileppm.h @@ -0,0 +1,69 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * 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 FILEPPM_H +#define FILEPPM_H + +#include "filelist.h" +#include "fileppm.inc" + +class FilePPM : public FileList +{ +public: + FilePPM(Asset *asset, File *file); + ~FilePPM(); + + void reset(); + static int check_sig(Asset *asset); + int read_ppm(FILE *fp, VFrame *frame); + int use_path(); + + int read_frame(VFrame *frame, char *path); + int colormodel_supported(int colormodel); + static int get_best_colormodel(Asset *asset, int driver); + int check_frame_header(FILE *fp); + int read_frame_header(char *path); + int write_frame(VFrame *frame, VFrame *output, FrameWriterUnit *unit); + FrameWriterUnit* new_writer_unit(FrameWriter *writer); + static void get_parameters(BC_WindowBase *parent_window, Asset *asset, + BC_WindowBase* &format_window, int audio_options, int video_options); +}; + +class PPMConfigVideo : public BC_Window +{ +public: + PPMConfigVideo(BC_WindowBase *gui, Asset *asset); + + BC_WindowBase *gui; + Asset *asset; +}; + +class PPMUnit : public FrameWriterUnit +{ +public: + PPMUnit(FilePPM *file, FrameWriter *writer); + ~PPMUnit(); + + FilePPM *file; + VFrame *temp_frame; +}; + +#endif diff --git a/cinelerra-5.1/cinelerra/fileppm.inc b/cinelerra-5.1/cinelerra/fileppm.inc new file mode 100644 index 00000000..e2e38201 --- /dev/null +++ b/cinelerra-5.1/cinelerra/fileppm.inc @@ -0,0 +1,8 @@ +#ifndef __FILEPPM_INC__ +#define __FILEPPM_INC__ + +class FilePPM; +class PPMConfigVideo; +class PPMUnit; + +#endif diff --git a/cinelerra-5.1/cinelerra/formatpopup.C b/cinelerra-5.1/cinelerra/formatpopup.C index 03e94dd9..8977e55b 100644 --- a/cinelerra-5.1/cinelerra/formatpopup.C +++ b/cinelerra-5.1/cinelerra/formatpopup.C @@ -54,9 +54,10 @@ void FormatPopup::create_objects() post_item(FILE_AIFF); post_item(FILE_AU); post_item(FILE_FLAC); - post_item(FILE_JPEG); } + if(!use_brender) + post_item(FILE_JPEG); post_item(FILE_JPEG_LIST); if(!use_brender) { @@ -71,24 +72,21 @@ void FormatPopup::create_objects() post_item(FILE_VORBIS); post_item(FILE_OGG); post_item(FILE_PCM); - post_item(FILE_PNG); } - format_items.append(new BC_ListBoxItem(_(PNG_LIST_NAME))); - if(!use_brender) - { - format_items.append(new BC_ListBoxItem(_(TGA_NAME))); - } - - format_items.append(new BC_ListBoxItem(_(TGA_LIST_NAME))); - + post_item(FILE_PNG); + post_item(FILE_PNG_LIST); if(!use_brender) - { - format_items.append(new BC_ListBoxItem(_(TIFF_NAME))); - } + post_item(FILE_PPM); + post_item(FILE_PPM_LIST); + if(!use_brender) + post_item(FILE_TGA); + post_item(FILE_TGA_LIST); + if(!use_brender) + post_item(FILE_TIFF); + post_item(FILE_TIFF_LIST); - format_items.append(new BC_ListBoxItem(_(TIFF_LIST_NAME))); update(&format_items, 0, 0, 1); } diff --git a/cinelerra-5.1/cinelerra/mainerror.C b/cinelerra-5.1/cinelerra/mainerror.C index 4dc01aec..eec7f8a1 100644 --- a/cinelerra-5.1/cinelerra/mainerror.C +++ b/cinelerra-5.1/cinelerra/mainerror.C @@ -193,13 +193,9 @@ void MainError::show_error_local(const char *string) void MainError::show_error(const char *string) { - if( main_error ) - main_error->show_error_local(string); - else { - printf("%s", string); - if( string[strlen(string) - 1] != '\n' ) - printf("\n"); - } + if( main_error ) main_error->show_error_local(string); + int len = strlen(string); + printf("%s%s", string, len>0 && string[len-1] == '\n' ? "" : "\n"); } diff --git a/cinelerra-5.1/cinelerra/mainerror.h b/cinelerra-5.1/cinelerra/mainerror.h index e5e5d4fb..766f1e66 100644 --- a/cinelerra-5.1/cinelerra/mainerror.h +++ b/cinelerra-5.1/cinelerra/mainerror.h @@ -33,17 +33,6 @@ // Once created, it accumulates errors in a listbox until it's closed. -// Macro to enable the simplest possible error output -//#define eprintf(format, ...) {char error_string[1024]; sprintf(sprintf(error_string, "%s: " format, __PRETTY_FUNCTION__, ## __VA_ARGS__); MainError::show_error(error_string); } -// We have to use longer version if we want to gettext error messages - -#define eprintf(...) do { \ - char err_msg[1024], *ep = err_msg; \ - ep += sprintf(ep, "%s:\n", __PRETTY_FUNCTION__); \ - sprintf(ep, __VA_ARGS__); (volatile void)MainError::show_error(err_msg); \ -} while(0) - - class MainErrorGUI : public BC_Window { public: @@ -98,6 +87,20 @@ private: }; +// format text to error dialog listbox +static inline void eprint1(const char *func, const char *fmt, ...) +{ + char err_msg[1024], *cp = err_msg, *ep = cp + sizeof(err_msg)-1; + va_list va; + va_start(va, fmt); + cp += snprintf(cp, ep-cp, "%s:\n", func); + cp += vsnprintf(cp, ep-cp, fmt, va); + *cp = 0; + va_end(va); + MainError::show_error(err_msg); \ +} + +#define eprintf(s...) eprint1(__PRETTY_FUNCTION__, s) #endif diff --git a/cinelerra-5.1/cinelerra/meterhistory.C b/cinelerra-5.1/cinelerra/meterhistory.C new file mode 100644 index 00000000..d7fa168e --- /dev/null +++ b/cinelerra-5.1/cinelerra/meterhistory.C @@ -0,0 +1,78 @@ +#include "meterhistory.h" + +#include + +MeterHistory::MeterHistory() +{ + size = 0; + channels = 0; + current_peak = 0; + samples = 0; + values = 0; +} +MeterHistory::~MeterHistory() +{ + init(0, 0); +} + +void MeterHistory::init(int chs, int sz) +{ + if( size != sz ) { + delete [] samples; samples = 0; + size = 0; + } + if( !samples && sz > 0 ) { + samples = new int64_t[size = sz]; + for( int i=0; i 0 ) { + current_peak = new int[channels = chs]; + for( int i=0; i= size ) peak_idx = 0; + current_peak[ch] = peak_idx; +} + +double MeterHistory::get_peak(int ch, int idx) +{ + return idx>=0 ? values[ch][idx] : 0; +} + +int MeterHistory::get_nearest(int64_t pos, int64_t tolerance) +{ + int result = -1; + if( size > 0 ) { + int64_t best = tolerance; + for( int i=0; i= tolerance || diff >= best ) continue; + best = diff; result = i; + } + } + return result; +} + diff --git a/cinelerra-5.1/cinelerra/meterhistory.h b/cinelerra-5.1/cinelerra/meterhistory.h new file mode 100644 index 00000000..1f61109c --- /dev/null +++ b/cinelerra-5.1/cinelerra/meterhistory.h @@ -0,0 +1,24 @@ +#ifndef __METERHISTORY_H__ +#define __METERHISTORY_H__ + +#include + +class MeterHistory +{ +public: + MeterHistory(); + ~MeterHistory(); + + int size, channels; + int *current_peak; + int64_t *samples; + double **values; + + void init(int chs, int sz); + void reset_channel(int ch); + void set_peak(int ch, double peak, int64_t pos); + double get_peak(int ch, int idx); + int get_nearest(int64_t pos, int64_t tolerance); +}; + +#endif diff --git a/cinelerra-5.1/cinelerra/pluginfclient.C b/cinelerra-5.1/cinelerra/pluginfclient.C index 2a35e96c..bb821d34 100644 --- a/cinelerra-5.1/cinelerra/pluginfclient.C +++ b/cinelerra-5.1/cinelerra/pluginfclient.C @@ -939,7 +939,7 @@ int PluginFVClient::process_buffer(VFrame **frames, int64_t position, double fra ret = av_buffersink_get_frame(fsink, frame); if( ret >= 0 || ret != AVERROR(EAGAIN) ) break; if( !fsrc ) { ret = AVERROR(EIO); break; } - read_frame(vframe, 0, filter_position++, frame_rate, get_use_opengl()); + read_frame(vframe, 0, filter_position++, frame_rate, 0); frame->format = pix_fmt; frame->width = width; frame->height = height; diff --git a/cinelerra-5.1/cinelerra/preferencesthread.C b/cinelerra-5.1/cinelerra/preferencesthread.C index b25075b8..bf921724 100644 --- a/cinelerra-5.1/cinelerra/preferencesthread.C +++ b/cinelerra-5.1/cinelerra/preferencesthread.C @@ -225,6 +225,10 @@ int PreferencesThread::apply_settings() mwindow->gui->unlock_window(); redraw_overlays = 1; } + PreferencesWindow *window = (PreferencesWindow*)get_gui(); + if( window ) window->unlock_window(); + mwindow->init_brender(); + if( window ) window->lock_window("PreferencesThread::apply_settings 5"); if( strcmp(preferences->theme, mwindow->preferences->theme) != 0 ) mwindow->restart_status = -1; // reload, need new bcresources @@ -233,7 +237,6 @@ int PreferencesThread::apply_settings() mwindow->edl->copy_session(edl, 1); mwindow->preferences->copy_from(preferences); - mwindow->init_brender(); BC_Signals::set_catch_segv(mwindow->preferences->trap_sigsegv); BC_Signals::set_catch_intr(mwindow->preferences->trap_sigintr); diff --git a/cinelerra-5.1/cinelerra/renderengine.C b/cinelerra-5.1/cinelerra/renderengine.C index f5c0754a..6bba1270 100644 --- a/cinelerra-5.1/cinelerra/renderengine.C +++ b/cinelerra-5.1/cinelerra/renderengine.C @@ -27,6 +27,7 @@ #include "condition.h" #include "edl.h" #include "edlsession.h" +#include "meterhistory.h" #include "mutex.h" #include "mwindow.h" #include "playbackengine.h" @@ -468,36 +469,31 @@ int RenderEngine::close_output() void RenderEngine::get_output_levels(double *levels, int64_t position) { - if(do_audio) - { - int history_entry = arender->get_history_number(arender->level_samples, - position); - for(int i = 0; i < MAXCHANNELS; i++) - { - if(arender->audio_out[i]) - levels[i] = arender->level_history[i][history_entry]; + if( do_audio ) { + MeterHistory *meter_history = arender->meter_history; + int64_t tolerance = 4*arender->meter_render_fragment; + int pos = meter_history->get_nearest(position, tolerance); + for( int i=0; iaudio_out[i] ) continue; + levels[i] = meter_history->get_peak(i, pos); } } } void RenderEngine::get_module_levels(ArrayList *module_levels, int64_t position) { - if(do_audio) - { - for(int i = 0; i < arender->total_modules; i++) - { -//printf("RenderEngine::get_module_levels %p %p\n", ((AModule*)arender->modules[i]), ((AModule*)arender->modules[i])->level_samples); - int history_entry = arender->get_history_number(((AModule*)arender->modules[i])->level_samples, position); - - module_levels->append(((AModule*)arender->modules[i])->level_history[history_entry]); + if( do_audio ) { + int64_t tolerance = 4*arender->meter_render_fragment; + for( int i=0; itotal_modules; ++i ) { + AModule *amodule = (AModule *)arender->modules[i]; + MeterHistory *meter_history = amodule->meter_history; + int pos = meter_history->get_nearest(position, tolerance); + module_levels->append(meter_history->get_peak(0, pos)); } } } - - - void RenderEngine::run() { render_active->lock("RenderEngine::run"); diff --git a/cinelerra-5.1/cinelerra/virtualaconsole.C b/cinelerra-5.1/cinelerra/virtualaconsole.C index f4d07bbf..02a86dcf 100644 --- a/cinelerra-5.1/cinelerra/virtualaconsole.C +++ b/cinelerra-5.1/cinelerra/virtualaconsole.C @@ -163,30 +163,23 @@ if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__); meter_render_end = len; double peak = 0; - - for( ; j < meter_render_end; j++) - { + while( j < meter_render_end ) { // Level history comes before clipping to get over status - double *sample = ¤t_buffer[j]; - - - if(fabs(*sample) > peak) peak = fabs(*sample); + double *sample = ¤t_buffer[j++]; + if( fabs(*sample) > peak ) peak = fabs(*sample); // Make the output device clip it // if(*sample > 1) *sample = 1; // else // if(*sample < -1) *sample = -1; } - - if(renderengine->command->realtime) - { - arender->level_history[i][arender->current_level[i]] = peak; - arender->level_samples[arender->current_level[i]] = - renderengine->command->get_direction() == PLAY_REVERSE ? + if( renderengine->command->realtime ) { + int direction = renderengine->command->get_direction(); + int64_t pos = direction == PLAY_REVERSE ? start_position - j : - start_position + j; - arender->current_level[i] = arender->get_next_peak(arender->current_level[i]); - } + start_position + j ; + arender->meter_history->set_peak(i, peak, pos); + } } } } @@ -247,7 +240,7 @@ if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__); if(renderengine->command->get_speed() < 1) { // number of samples to skip - int interpolate_len = (int)(1.0 / renderengine->command->get_speed()); + int interpolate_len = (int)(1.0 / renderengine->command->get_speed()); real_output_len = len * interpolate_len; for(in = len - 1, out = real_output_len - 1; in >= 0; ) diff --git a/cinelerra-5.1/cinelerra/virtualanode.C b/cinelerra-5.1/cinelerra/virtualanode.C index 62cb5965..a1ad5235 100644 --- a/cinelerra-5.1/cinelerra/virtualanode.C +++ b/cinelerra-5.1/cinelerra/virtualanode.C @@ -281,8 +281,6 @@ if(debug) printf("VirtualANode::render_as_module %d\n", __LINE__); // Scan fragment in meter sized fragments for(int i = 0; i < len; ) { - int current_level = ((AModule*)real_module)->current_level; - double peak = 0; meter_render_start = i; meter_render_end = i + meter_render_fragment; if(meter_render_end > len) @@ -290,25 +288,20 @@ if(debug) printf("VirtualANode::render_as_module %d\n", __LINE__); // Number of samples into the fragment this meter sized fragment is, // normalized to project sample rate. int64_t meter_render_start_project = meter_render_start * - project_sample_rate / - sample_rate; + project_sample_rate / sample_rate; // Scan meter sized fragment - double *output_samples = output_temp->get_data(); - for( ; i < meter_render_end; i++) - { - double sample = fabs(output_samples[i]); - if(sample > peak) peak = sample; + double peak = 0, *output_samples = output_temp->get_data(); + while( i < meter_render_end ) { + double sample = fabs(output_samples[i++]); + if( sample > peak ) peak = sample; } - ((AModule*)real_module)->level_history[current_level] = - peak; - ((AModule*)real_module)->level_samples[current_level] = - (direction == PLAY_FORWARD) ? + MeterHistory *meter_history = ((AModule*)real_module)->meter_history; + int64_t pos = (direction == PLAY_FORWARD) ? (start_position_project + meter_render_start_project) : - (start_position_project - meter_render_start_project); - ((AModule*)real_module)->current_level = - arender->get_next_peak(current_level); + (start_position_project - meter_render_start_project) ; + meter_history->set_peak(0, peak, pos); } } if(debug) printf("VirtualANode::render_as_module %d\n", __LINE__); diff --git a/cinelerra-5.1/guicast/bccmdl.py b/cinelerra-5.1/guicast/bccmdl.py index 3f7709cc..4c184bd0 100755 --- a/cinelerra-5.1/guicast/bccmdl.py +++ b/cinelerra-5.1/guicast/bccmdl.py @@ -325,6 +325,22 @@ base = { }, }, + "gbrp": { + "i8": { + "r": " int g = *gip++, b = *bip++, r = *rip++;", + "w": " *gop++ = g; *bop++ = b; *rop++ = r;", + }, + "i16": { + "r": " int ig = *gip++, g = (ig<<8) | ig, ib = *bip++, b = (ib<<8) | ib," + + " ir = *rip++, r = (ir<<8) | ir;", + "w": " *gop++ = g >> 8; *bop++ = b >> 8; *rop++ = r >> 8;", + }, + "fp": { + "r": " float g = *gip++/255.f, b = *bip++/255.f, r = *rip++/255.f;", + "w": " *gop++ = clp(256,g); *bop++ = clp(256,b); *rop++ = clp(256,r);", + }, + }, + "grey8": { "i8": { "r": " int32_t y = *inp++, u = 0x80, v = 0x80;", @@ -488,6 +504,7 @@ add_cmodel(34, "bc_yuv420pi", "i8", "yuv420pi") add_cmodel(36, "bc_grey8", "i8", "grey8") add_cmodel(37, "bc_grey16", "i16", "grey16") +add_cmodel(38, "bc_gbrp", "i8", "gbrp") specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency") @@ -522,17 +539,17 @@ def is_rgb(nm): "bc_bgr888", "bc_bgr8888", "bc_rgb888", "bc_rgba8888", \ "bc_argb8888", "bc_abgr8888", "bc_rgb", "bc_rgb161616", \ "bc_rgba16161616", "bc_rgb_float", "bc_rgba_float", \ - "bc_rgb_floatp", "bc_rgba_floatp", ] + "bc_rgb_floatp", "bc_rgba_floatp", "bc_gbrp", ] def is_yuv(nm): return nm in [ "bc_yuv888", "bc_yuva8888", "bc_yuv161616", \ "bc_yuva16161616", "bc_ayuv16161616", "bc_yuv422", "bc_uvy422", "bc_yuv101010", \ "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", \ - "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", "bc_grey8", "bc_grey16" ] + "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", "bc_grey8", "bc_grey16", ] def is_planar(nm): return nm in [ "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", "bc_yuv444p", \ - "bc_yuv411p", "bc_yuv410p", "bc_rgb_floatp", "bc_rgba_floatp", ] + "bc_yuv411p", "bc_yuv410p", "bc_rgb_floatp", "bc_rgba_floatp", "bc_gbrp", ] def is_float(nm): return nm in ["bc_rgb_float", "bc_rgba_float", "bc_rgb_floatp", "bc_rgba_floatp", ] @@ -553,10 +570,14 @@ def gen_xfer_fn(fr_cmdl, to_cmdl): # xfr fn body print "{" # loops / pointer preload - in_cmdl = fr_cmdl[3:] if is_planar(fr_cmdl) else "flat"; - out_cmdl = to_cmdl[3:] if is_planar(to_cmdl) else "flat"; + in_xfer = "flat" if not is_planar(fr_cmdl) else \ + fr_cmdl[3:] if is_yuv(fr_cmdl) else \ + "rgbp" if not has_alpha(fr_cmdl) else "rgbap" + out_xfer = "flat" if not is_planar(to_cmdl) else \ + to_cmdl[3:] if is_yuv(to_cmdl) else \ + "rgbp" if not has_alpha(to_cmdl) else "rgbap" print " xfer_%s_row_out(%s) xfer_%s_row_in(%s)" % \ - (out_cmdl, ctype[otyp], in_cmdl, ctype[ityp],) + (out_xfer, ctype[otyp], in_xfer, ctype[ityp],) # load inp if( is_float(to_cmdl) and is_yuv(fr_cmdl) ): for ic in layout[fr_cmdl]: print "%s" % (base[ic][ityp]['r']), diff --git a/cinelerra-5.1/guicast/bccmodels.C b/cinelerra-5.1/guicast/bccmodels.C index dc5c2af1..5d3da1ec 100644 --- a/cinelerra-5.1/guicast/bccmodels.C +++ b/cinelerra-5.1/guicast/bccmodels.C @@ -29,10 +29,12 @@ int BC_CModels::is_planar(int colormodel) case BC_YUV420PI: case BC_YUV422P: case BC_YUV444P: + case BC_GBRP: case BC_YUV411P: case BC_YUV410P: case BC_RGB_FLOATP: - case BC_RGBA_FLOATP: return 1; + case BC_RGBA_FLOATP: + return 1; } return 0; } @@ -40,26 +42,39 @@ int BC_CModels::is_planar(int colormodel) int BC_CModels::components(int colormodel) { switch(colormodel) { - case BC_A8: return 1; - case BC_A16: return 1; - case BC_A_FLOAT: return 1; - case BC_RGB888: return 3; - case BC_RGBA8888: return 4; - case BC_RGB161616: return 3; - case BC_RGBA16161616: return 4; - case BC_YUV888: return 3; - case BC_YUVA8888: return 4; - case BC_YUV161616: return 3; - case BC_YUVA16161616: return 4; - case BC_AYUV16161616: return 4; - case BC_YUV101010: return 3; - case BC_RGB_FLOAT: return 3; - case BC_RGBA_FLOAT: return 4; - case BC_RGB_FLOATP: return 3; - case BC_RGBA_FLOATP: return 4; - case BC_GREY8: return 1; - case BC_GREY16: return 1; + case BC_RGB8: + case BC_RGB565: + case BC_BGR565: + case BC_BGR888: + case BC_RGB888: + case BC_RGB161616: + case BC_RGB_FLOAT: + case BC_BGR8888: + case BC_YUV888: + case BC_YUV161616: + case BC_UVY422: + case BC_YUV422: + case BC_YUV101010: + case BC_VYU888: + return 3; + case BC_RGBA8888: + case BC_ARGB8888: + case BC_ABGR8888: + case BC_RGBA16161616: + case BC_RGBA_FLOAT: + case BC_YUVA8888: + case BC_YUVA16161616: + case BC_UYVA8888: + case BC_AYUV16161616: + return 4; + case BC_A8: + case BC_A16: + case BC_A_FLOAT: + case BC_GREY8: + case BC_GREY16: + return 1; } +// planar, compressed, transparent return 0; } @@ -100,6 +115,7 @@ int BC_CModels::calculate_pixelsize(int colormodel) case BC_YUV420PI: return 1; case BC_YUV422P: return 1; case BC_YUV444P: return 1; + case BC_GBRP: return 1; case BC_YUV422: return 2; case BC_UVY422: return 2; case BC_YUV411P: return 1; @@ -132,6 +148,7 @@ int BC_CModels::calculate_max(int colormodel) case BC_RGBA_FLOATP: return 1; case BC_GREY8: return 0xff; case BC_GREY16: return 0xffff; + case BC_GBRP: return 0xff; } return 0; } @@ -145,6 +162,7 @@ int BC_CModels::calculate_datasize(int w, int h, int bytes_per_line, int color_m case BC_YUV411P: return w * h + w * h / 2 + 4; case BC_YUV422P: return w * h * 2 + 4; case BC_YUV444P: return w * h * 3 + 4; + case BC_GBRP: return w * h * 3 + 4; case BC_RGB_FLOATP: return w * h * 3 * sizeof(float) + 4; case BC_RGBA_FLOATP: return w * h * 4 * sizeof(float) + 4; } diff --git a/cinelerra-5.1/guicast/bccmodels.h b/cinelerra-5.1/guicast/bccmodels.h index 63b7d8c3..6597bc75 100644 --- a/cinelerra-5.1/guicast/bccmodels.h +++ b/cinelerra-5.1/guicast/bccmodels.h @@ -61,6 +61,7 @@ enum BC_CModel { BC_RGB_FLOATP = 32, BC_RGBA_FLOATP = 33, BC_YUV420PI = 34, + BC_GBRP = 38, // only used in intermediate ffmpeg xfers BC_AYUV16161616 = 35, BC_GREY8 = 36, diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 597a0ec9..58055f78 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -2338,6 +2338,9 @@ void BC_WindowBase::init_xft() { #ifdef HAVE_XFT if( !get_resources()->use_xft ) return; +// apparently, xft is not reentrant, more than this is needed +static Mutex xft_init_lock("BC_WindowBase::xft_init_lock", 0); +xft_init_lock.lock("BC_WindowBase::init_xft"); if(!(smallfont_xft = (resources.small_font_xft[0] == '-' ? XftFontOpenXlfd(display, screen, resources.small_font_xft) : @@ -2407,6 +2410,7 @@ void BC_WindowBase::init_xft() } // _XftDisplayInfo needs a lock. XftDefaultHasRender(display); +xft_init_lock.unlock(); #endif // HAVE_XFT } diff --git a/cinelerra-5.1/guicast/test4.C b/cinelerra-5.1/guicast/test4.C index ed0f3840..114ed49a 100644 --- a/cinelerra-5.1/guicast/test4.C +++ b/cinelerra-5.1/guicast/test4.C @@ -82,7 +82,7 @@ const char *cmdl[] = { "yuv422p", "rgb888", "rgba8888", "rgb161616", "rgba16161616", "yuv888", "yuva8888", "yuv161616", "yuva16161616", "yuv411p", "uvy422", "yuv422", "argb8888", "abgr8888", "a8", "a16", "yuv101010", "vyu888", "uyva8888", "yuv444p", "yuv410p", "rgb_float", "rgba_float", "a_float", - "rgb_floatp", "rgba_floatp", "yuv420pi", "ayuv16161616", "grey8", "grey16", + "rgb_floatp", "rgba_floatp", "yuv420pi", "ayuv16161616", "grey8", "grey16", "gbrp", }; void write_pgm(uint8_t *tp, int w, int h, const char *fmt, ...) @@ -151,13 +151,13 @@ int main(int ac, char **av) close(fd); int w = ifrm.get_w(), h = ifrm.get_h(); TestWindow test_window(100, 100, w, h); - for( int fr_cmdl=1; fr_cmdl<=37; ++fr_cmdl ) { + for( int fr_cmdl=1; fr_cmdl<=38; ++fr_cmdl ) { if( fr_cmdl == BC_TRANSPARENCY || fr_cmdl == BC_COMPRESSED ) continue; if( fr_cmdl == BC_A8 || fr_cmdl == BC_A16 ) continue; if( fr_cmdl == BC_A_FLOAT || fr_cmdl == 8 ) continue; VFrame afrm(w, h, fr_cmdl, -1); afrm.transfer_from(&ifrm, 0); - for( int to_cmdl=1; to_cmdl<=37; ++to_cmdl ) { + for( int to_cmdl=1; to_cmdl<=38; ++to_cmdl ) { if( to_cmdl == BC_TRANSPARENCY || to_cmdl == BC_COMPRESSED ) continue; if( to_cmdl == BC_A8 || to_cmdl == BC_A16 ) continue; if( to_cmdl == BC_A_FLOAT || to_cmdl == 8 ) continue; diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index 79904192..241a773f 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -355,6 +355,7 @@ if( memory_type != VFrame::SHARED ) case BC_YUV444P: case BC_RGB_FLOATP: case BC_RGBA_FLOATP: + case BC_GBRP: break; default: @@ -446,6 +447,12 @@ void VFrame::create_row_pointers() this->u_offset = sz; this->v_offset = sz + sz; break; + case BC_GBRP: + if( this->v_offset ) break; + this->y_offset = 0; + this->u_offset = sz * sizeof(uint8_t); + this->v_offset = 2 * sz * sizeof(uint8_t); + break; case BC_RGBA_FLOATP: if( this->v_offset || a ) break; a = this->data + 3 * sz * sizeof(float); @@ -903,6 +910,12 @@ int VFrame::clear_frame() bzero(get_v(), sz / 2); break; + case BC_GBRP: + bzero(get_y(), sz); + bzero(get_u(), sz); + bzero(get_b(), sz); + break; + case BC_RGBA_FLOATP: if( a ) { float *ap = (float *)a; for( int i=sz; --i>=0; ++ap ) *ap = 1.f; } diff --git a/cinelerra-5.1/guicast/xfer.C b/cinelerra-5.1/guicast/xfer.C index e4ac81fe..44258127 100644 --- a/cinelerra-5.1/guicast/xfer.C +++ b/cinelerra-5.1/guicast/xfer.C @@ -45,6 +45,9 @@ void BC_Xfer::init( this->out_h = out_h; this->in_colormodel = in_colormodel; switch( in_colormodel ) { + case BC_GBRP: + in_rowspan = in_w * sizeof(uint8_t); + break; case BC_RGB_FLOATP: case BC_RGBA_FLOATP: if( !BC_CModels::has_alpha(out_colormodel) ) @@ -55,6 +58,9 @@ void BC_Xfer::init( this->total_in_w = in_rowspan; this->out_colormodel = out_colormodel; switch( out_colormodel ) { + case BC_GBRP: + out_rowspan = out_w * sizeof(uint8_t); + break; case BC_RGB_FLOATP: case BC_RGBA_FLOATP: out_rowspan = out_w * sizeof(float); diff --git a/cinelerra-5.1/guicast/xfer.h b/cinelerra-5.1/guicast/xfer.h index 508f977b..efcbc41f 100644 --- a/cinelerra-5.1/guicast/xfer.h +++ b/cinelerra-5.1/guicast/xfer.h @@ -167,43 +167,49 @@ ZTYP(float); ity_t *uip = (ity_t *)(uip_row + in_ofs); \ ity_t *vip = (ity_t *)(vip_row + in_ofs); \ -// rgb_floatp -#define xfer_rgb_fltp_row_out(oty_t) \ +// rgb planar +#define xfer_rgbp_row_out(oty_t) \ for( unsigned i=y0; iget_rows()[0] == output->get_rows()[0] ) { if( temp_frame && ( @@ -230,3 +232,28 @@ void ScaleRatioMain::update_gui() } +int ScaleRatioMain::handle_opengl() +{ +#ifdef HAVE_GL + VFrame *input = get_input(), *output = get_output(); + float ix1 = (input->get_w() - config.src_w)/2 + config.src_x; + float iy1 = (input->get_h() - config.src_h)/2 + config.src_y; + float ix2 = ix1 + config.src_w; + float iy2 = iy1 + config.src_h; + float ox1 = (output->get_w() - config.dst_w)/2 + config.dst_x; + float oy1 = (output->get_h() - config.dst_h)/2 + config.dst_y; + float ox2 = ox1 + config.dst_w; + float oy2 = oy1 + config.dst_h; + + output->to_texture(); + output->enable_opengl(); + output->init_screen(); + output->clear_pbuffer(); + output->bind_texture(0); + output->draw_texture(ix1,iy1, ix2,iy2, ox1,oy1, ox2,oy2); + output->set_opengl_state(VFrame::SCREEN); +#endif + return 0; +} + + diff --git a/cinelerra-5.1/plugins/scaleratio/scaleratio.h b/cinelerra-5.1/plugins/scaleratio/scaleratio.h index c2df83e7..20aa0d12 100644 --- a/cinelerra-5.1/plugins/scaleratio/scaleratio.h +++ b/cinelerra-5.1/plugins/scaleratio/scaleratio.h @@ -61,7 +61,7 @@ public: void update_gui(); void save_data(KeyFrame *keyframe); void read_data(KeyFrame *keyframe); - + int handle_opengl(); OverlayFrame *overlayer; VFrame *temp_frame; diff --git a/cinelerra-5.1/plugins/scaleratio/scaleratiowin.C b/cinelerra-5.1/plugins/scaleratio/scaleratiowin.C index b9e9d8fd..10961a10 100644 --- a/cinelerra-5.1/plugins/scaleratio/scaleratiowin.C +++ b/cinelerra-5.1/plugins/scaleratio/scaleratiowin.C @@ -29,7 +29,7 @@ ScaleRatioWin::ScaleRatioWin(ScaleRatioMain *client) - : PluginClientWindow(client, 400, 300, 400, 300, 0) + : PluginClientWindow(client, 400, 320, 400, 320, 0) { this->client = client; } -- 2.26.2