From e9a3c57c8d3bb4d79e76a4c3942f86a66d3c267e Mon Sep 17 00:00:00 2001 From: Good Guy Date: Sun, 13 Aug 2017 13:46:32 -0600 Subject: [PATCH] ffmpeg filter memory leak, cursor hopper fix, added leaker.C, misc fixes --- cinelerra-5.1/PKGBUILD | 2 +- cinelerra-5.1/cinelerra/canvas.C | 37 +++++++-- cinelerra-5.1/cinelerra/canvas.h | 5 +- cinelerra-5.1/cinelerra/cwindowgui.C | 2 +- cinelerra-5.1/cinelerra/ffmpeg.C | 6 +- cinelerra-5.1/cinelerra/formatpopup.C | 3 +- cinelerra-5.1/cinelerra/main.C | 15 ++-- cinelerra-5.1/cinelerra/mwindow.C | 6 +- cinelerra-5.1/cinelerra/new.C | 1 - cinelerra-5.1/cinelerra/playbackengine.C | 75 +++++++++--------- cinelerra-5.1/cinelerra/playtransport.C | 10 --- cinelerra-5.1/cinelerra/vdevicex11.C | 60 +------------- cinelerra-5.1/cinelerra/vedit.C | 99 +++++------------------- cinelerra-5.1/cinelerra/virtualvnode.C | 3 +- cinelerra-5.1/cinelerra/vmodule.C | 59 ++++---------- cinelerra-5.1/leaker.C | 78 +++++++++++++++++++ cinelerra-5.1/plugins/C41/c41.C | 36 ++++----- 17 files changed, 218 insertions(+), 279 deletions(-) create mode 100644 cinelerra-5.1/leaker.C diff --git a/cinelerra-5.1/PKGBUILD b/cinelerra-5.1/PKGBUILD index 97042e05..f7953dd9 100644 --- a/cinelerra-5.1/PKGBUILD +++ b/cinelerra-5.1/PKGBUILD @@ -6,7 +6,7 @@ pkgdesc="Cinelerra git://git.cinelerra-cv.org/goodguy/cinelerra.git ($pkgrel)" arch=('x86_64') url="http://www.cinelerra-cv.org" license=('GPL') -depends=('xorg-server' 'xorg-server-utils' 'libpng' 'libxv' 'libva' +depends=('xorg-server' 'libpng' 'libxv' 'libva' 'libxft' 'freetype2' 'alsa-lib' 'inkscape' 'dvdauthor') makedepends=('yasm' 'nasm' 'cmake' 'libxml2' 'perl-xml-libxml' 'perl-xml-parser') diff --git a/cinelerra-5.1/cinelerra/canvas.C b/cinelerra-5.1/cinelerra/canvas.C index b2bd838d..72d8a906 100644 --- a/cinelerra-5.1/cinelerra/canvas.C +++ b/cinelerra-5.1/cinelerra/canvas.C @@ -30,6 +30,8 @@ #include "mwindowgui.h" #include "mutex.h" #include "mwindow.h" +#include "playback3d.h" +#include "videodevice.h" #include "vframe.h" @@ -838,17 +840,40 @@ int Canvas::keypress_event(BC_WindowBase *caller) return 1; } +void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame) +{ + int best_color_model = output_frame->get_color_model(); + int use_opengl = + device->out_config->driver == PLAYBACK_X11_GL && + output_frame->get_opengl_state() == VFrame::SCREEN; +// OpenGL does YUV->RGB in the compositing step + if( use_opengl ) + best_color_model = BC_RGB888; + if( refresh_frame && + (refresh_frame->get_w() != device->out_w || + refresh_frame->get_h() != device->out_h || + refresh_frame->get_color_model() != best_color_model) ) { + delete refresh_frame; refresh_frame = 0; + } + if( !refresh_frame ) { + refresh_frame = + new VFrame(device->out_w, device->out_h, best_color_model); + } + if( use_opengl ) { + get_canvas()->unlock_window(); + unlock_canvas(); - - - - - - + mwindow->playback_3d->copy_from(this, refresh_frame, output_frame, 0); + lock_canvas(" Canvas::output_refresh"); + get_canvas()->lock_window(" Canvas::output_refresh"); + } + else + refresh_frame->copy_from(output_frame); +} diff --git a/cinelerra-5.1/cinelerra/canvas.h b/cinelerra-5.1/cinelerra/canvas.h index 27336588..c5d53703 100644 --- a/cinelerra-5.1/cinelerra/canvas.h +++ b/cinelerra-5.1/cinelerra/canvas.h @@ -25,6 +25,7 @@ #include "edl.inc" #include "guicast.h" #include "mwindow.inc" +#include "videodevice.inc" // Output for all X11 video @@ -141,7 +142,9 @@ public: virtual int get_xscroll() { return 0; }; virtual int get_yscroll() { return 0; }; virtual float get_zoom() { return 0; }; -// Redraws the image +// Updates the refresh_frame + void update_refresh(VideoDevice *device, VFrame *output_frame); +// Redraws the refresh_frame virtual void draw_refresh(int flush = 1) {}; // Get top left offset of canvas relative to output. diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index c3bf4b61..24a515fa 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -386,7 +386,7 @@ void CWindowGUI::zoom_canvas(double value, int update_menu) x = output_x - cx / zoom; y = output_y - cy / zoom; } - canvas->update_zoom((int)x, (int)y, zoom); + canvas->update_zoom((int)(x+0.5), (int)(y+0.5), zoom); if( update_menu ) zoom_panel->update(value); diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 547b7f07..b451c797 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -395,12 +395,11 @@ int FFStream::decode(AVFrame *frame) int FFStream::load_filter(AVFrame *frame) { + av_frame_unref(frame); int ret = av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF); - if( ret < 0 ) { - av_frame_unref(frame); + if( ret < 0 ) eprintf(_("av_buffersrc_add_frame_flags failed\n")); - } return ret; } @@ -418,6 +417,7 @@ int FFStream::read_filter(AVFrame *frame) int FFStream::read_frame(AVFrame *frame) { + av_frame_unref(frame); if( !filter_graph || !buffersrc_ctx || !buffersink_ctx ) return decode(frame); if( !fframe && !(fframe=av_frame_alloc()) ) { diff --git a/cinelerra-5.1/cinelerra/formatpopup.C b/cinelerra-5.1/cinelerra/formatpopup.C index 683c7117..06e41453 100644 --- a/cinelerra-5.1/cinelerra/formatpopup.C +++ b/cinelerra-5.1/cinelerra/formatpopup.C @@ -40,10 +40,9 @@ FormatPopup::FormatPopup(ArrayList *plugindb, void FormatPopup::create_objects() { - format_items.append(new BC_ListBoxItem(_(FFMPEG_NAME))); - if(!use_brender) { + format_items.append(new BC_ListBoxItem(_(FFMPEG_NAME))); format_items.append(new BC_ListBoxItem(_(AC3_NAME))); format_items.append(new BC_ListBoxItem(_(AIFF_NAME))); format_items.append(new BC_ListBoxItem(_(AU_NAME))); diff --git a/cinelerra-5.1/cinelerra/main.C b/cinelerra-5.1/cinelerra/main.C index caa04a83..02417803 100644 --- a/cinelerra-5.1/cinelerra/main.C +++ b/cinelerra-5.1/cinelerra/main.C @@ -42,13 +42,14 @@ #include #if 0 -#define STRC printf("==new %jd from %p\n", n, __builtin_return_address(0)); -void *operator new(size_t n) { STRC void *vp = malloc(n); bzero(vp,n); return vp; } -void operator delete(void *t) { free(t); } -void operator delete(void *t,size_t n) { free(t); } -void *operator new[](size_t n) { STRC void *vp = malloc(n); bzero(vp,n); return vp; } -void operator delete[](void *t) { free(t); } -void operator delete[](void *t,size_t n) { free(t); } +#define STRC(v) printf("==new %p from %p sz %jd\n", v, __builtin_return_address(0), n) +#define STRD(v) printf("==del %p from %p\n", v, __builtin_return_address(0)) +void *operator new(size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; } +void operator delete(void *t) { STRD(t); free(t); } +void operator delete(void *t,size_t n) { STRD(t); free(t); } +void *operator new[](size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; } +void operator delete[](void *t) { STRD(t); free(t); } +void operator delete[](void *t,size_t n) { STRD(t); free(t); } #endif enum diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 8824b868..6e1ecaa9 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -1802,10 +1802,6 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); show_plugin(plugin); } } - else - { - plugin->show = 0; - } plugin = (Plugin*)plugin->next; } @@ -2952,7 +2948,7 @@ void MWindow::update_project(int load_mode) const int debug = 0; if(debug) PRINT_TRACE - restart_brender(); + init_brender(); edl->tracks->update_y_pixels(theme); if(debug) PRINT_TRACE diff --git a/cinelerra-5.1/cinelerra/new.C b/cinelerra-5.1/cinelerra/new.C index 949de932..9f0c70d5 100644 --- a/cinelerra-5.1/cinelerra/new.C +++ b/cinelerra-5.1/cinelerra/new.C @@ -76,7 +76,6 @@ int New::handle_event() mwindow->gui->unlock_window(); mwindow->edl->save_defaults(mwindow->defaults); create_new_edl(); - create_new_project(); thread->start(); mwindow->gui->lock_window("New::handle_event"); diff --git a/cinelerra-5.1/cinelerra/playbackengine.C b/cinelerra-5.1/cinelerra/playbackengine.C index 802b7b61..9f826401 100644 --- a/cinelerra-5.1/cinelerra/playbackengine.C +++ b/cinelerra-5.1/cinelerra/playbackengine.C @@ -351,11 +351,9 @@ void PlaybackEngine::run() { start_lock->unlock(); - do - { + while( !done ) { // Wait for current command to finish que->output_lock->lock("PlaybackEngine::run"); - wait_render_engine(); // Read the new command @@ -365,59 +363,56 @@ void PlaybackEngine::run() command->copy_from(&que->command); que->command.reset(); que->input_lock->unlock(); - //printf("PlaybackEngine::run 1 %d\n", command->command); - switch(command->command) - { + switch( command->command ) { // Parameter change only - case COMMAND_NONE: -// command->command = last_command; - perform_change(); - break; - - case PAUSE: - init_cursor(0); - pause_lock->lock("PlaybackEngine::run"); - stop_cursor(); - break; - - case STOP: + case COMMAND_NONE: +// command->command = last_command; + perform_change(); + break; + + case PAUSE: + init_cursor(0); + pause_lock->lock("PlaybackEngine::run"); + stop_cursor(); + break; + + case STOP: // No changing - break; + break; - case CURRENT_FRAME: - last_command = command->command; - perform_change(); - arm_render_engine(); + case CURRENT_FRAME: + last_command = command->command; + perform_change(); + arm_render_engine(); // Dispatch the command - start_render_engine(); - break; - - default: - last_command = command->command; - is_playing_back = 1; - if(command->command == SINGLE_FRAME_FWD || - command->command == SINGLE_FRAME_REWIND) - { - command->playbackstart = get_tracking_position(); - } + start_render_engine(); + break; - perform_change(); - arm_render_engine(); + case SINGLE_FRAME_FWD: + case SINGLE_FRAME_REWIND: + command->playbackstart = get_tracking_position(); +// fall through + default: + last_command = command->command; + is_playing_back = 1; + + perform_change(); + arm_render_engine(); // Start tracking after arming so the tracking position doesn't change. // The tracking for a single frame command occurs during PAUSE - init_tracking(); + init_tracking(); // Dispatch the command - start_render_engine(); - break; + start_render_engine(); + break; } //printf("PlaybackEngine::run 100\n"); - }while(!done); + } } diff --git a/cinelerra-5.1/cinelerra/playtransport.C b/cinelerra-5.1/cinelerra/playtransport.C index a426ac79..0774c8a4 100644 --- a/cinelerra-5.1/cinelerra/playtransport.C +++ b/cinelerra-5.1/cinelerra/playtransport.C @@ -313,16 +313,6 @@ void PlayTransport::handle_transport(int command, if( do_stop ) { engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0); engine->interrupt_playback(wait_tracking); -// This is necessary to get an OpenGL output buffer -// printf("PlayTransport::handle_transport 2 update_refresh=%d prev_command=%d prev_direction=%d\n", -// update_refresh, prev_command, prev_direction); - if( !prev_single_frame && update_refresh && - prev_command != STOP && prev_command != COMMAND_NONE ) { - int command = (prev_direction == PLAY_FORWARD) ? - SINGLE_FRAME_REWIND : SINGLE_FRAME_FWD; - engine->que->send_command(command, - CHANGE_NONE, get_edl(), 1, 0, 0); - } } } diff --git a/cinelerra-5.1/cinelerra/vdevicex11.C b/cinelerra-5.1/cinelerra/vdevicex11.C index 641a6760..31873e6a 100644 --- a/cinelerra-5.1/cinelerra/vdevicex11.C +++ b/cinelerra-5.1/cinelerra/vdevicex11.C @@ -137,64 +137,8 @@ int VDeviceX11::close_all() if(output && output_frame) { -// Copy our output frame buffer to the canvas's permanent frame buffer. -// They must be different buffers because the output frame is being written -// while the user is redrawing the canvas frame buffer over and over. - - int use_opengl = device->out_config->driver == PLAYBACK_X11_GL && - output_frame->get_opengl_state() == VFrame::SCREEN; - int best_color_model = output_frame->get_color_model(); - -// OpenGL does YUV->RGB in the compositing step - if(use_opengl) - best_color_model = BC_RGB888; - - if(output->refresh_frame && - (output->refresh_frame->get_w() != device->out_w || - output->refresh_frame->get_h() != device->out_h || - output->refresh_frame->get_color_model() != best_color_model)) - { - delete output->refresh_frame; - output->refresh_frame = 0; - } - - if(!output->refresh_frame) - { - output->refresh_frame = new VFrame(0, -1, - device->out_w, device->out_h, - best_color_model, -1); - } - - if(use_opengl) - { - output->get_canvas()->unlock_window(); - output->unlock_canvas(); - - output->mwindow->playback_3d->copy_from(output, - output->refresh_frame, output_frame, 0); - output->lock_canvas("VDeviceX11::close_all 2"); - output->get_canvas()->lock_window("VDeviceX11::close_all 2"); - } - else - output->refresh_frame->copy_from(output_frame); - -// // Update the status bug -// if(!device->single_frame) -// { -// output->stop_video(); -// } -// else -// { -// output->stop_single(); -// } - -// Draw the first refresh with new frame. -// Doesn't work if video and openGL because OpenGL doesn't have -// the output buffer for video. -// Not necessary for any case if we mandate a frame advance after -// every stop. - if(/* device->out_config->driver != PLAYBACK_X11_GL || - */ device->single_frame) + output->update_refresh(device, output_frame); + if( device->single_frame ) output->draw_refresh(); } diff --git a/cinelerra-5.1/cinelerra/vedit.C b/cinelerra-5.1/cinelerra/vedit.C index 775822fe..f8469b10 100644 --- a/cinelerra-5.1/cinelerra/vedit.C +++ b/cinelerra-5.1/cinelerra/vedit.C @@ -54,80 +54,30 @@ int VEdit::load_properties_derived(FileXML *xml) } Asset* VEdit::get_nested_asset(int64_t *source_position, - int64_t position, - int direction) + int64_t position, int direction) { - const int debug = 0; - Asset *result = 0; + double edit_frame_rate = nested_edl ? + nested_edl->session->frame_rate : asset->frame_rate; // Make position relative to edit - *source_position = position - startproject + startsource; - -if(debug) printf("VEdit::get_nested_asset %d %jd %jd %jd %jd\n", -__LINE__, *source_position, position, startproject, startsource); + double edit_position = (position - startproject + startsource) * + edit_frame_rate / edl->session->frame_rate; + *source_position = Units::to_int64(edit_position); + if( !nested_edl ) return asset; // Descend into nested EDLs - if(nested_edl) - { -// Convert position to nested EDL rate -if(debug) printf("VEdit::get_nested_asset %d\n", -__LINE__); - int64_t pos = *source_position; - if(direction == PLAY_REVERSE && pos > 0) --pos; - *source_position = Units::to_int64((double)pos * - nested_edl->session->frame_rate / - edl->session->frame_rate); - PlayableTracks *playable_tracks = new PlayableTracks( - nested_edl, - *source_position, - direction, - TRACK_VIDEO, - 1); - if(playable_tracks->size()) - { - VTrack *nested_track = (VTrack*)playable_tracks->get(0); - VEdit* nested_edit = (VEdit*)nested_track->edits->editof( - *source_position, - direction, - 1); - if(nested_edit) - { - result = nested_edit->get_nested_asset( - source_position, - *source_position, - direction); - } - } - - delete playable_tracks; -if(debug) printf("VEdit::get_nested_asset %d\n", -__LINE__); - return result; - } - else - { -// Convert position to asset rate -if(debug) printf("VEdit::get_nested_asset %d %jd %f %f\n", -__LINE__, -*source_position, -asset->frame_rate, -edl->session->frame_rate); - int64_t pos = *source_position; - if(direction == PLAY_REVERSE && pos > 0) --pos; - *source_position = Units::to_int64((double)pos * - asset->frame_rate / - edl->session->frame_rate); - - return asset; - } + PlayableTracks playable_tracks(nested_edl, + *source_position, direction, TRACK_VIDEO, 1); + if( !playable_tracks.size() ) return 0; + VTrack *nested_track = (VTrack*)playable_tracks[0]; + VEdit* nested_edit = (VEdit*)nested_track->edits-> + editof(*source_position, direction, 1); + if( !nested_edit ) return 0; + return nested_edit->get_nested_asset(source_position, + *source_position, direction); } -int VEdit::read_frame(VFrame *video_out, - int64_t input_position, - int direction, - CICache *cache, - int use_nudge, - int use_cache, - int use_asynchronous) +int VEdit::read_frame(VFrame *video_out, int64_t input_position, int direction, + CICache *cache, int use_nudge, int use_cache, int use_asynchronous) { File *file = 0; int result = 0; @@ -138,9 +88,7 @@ int VEdit::read_frame(VFrame *video_out, if(debug) printf("VEdit::read_frame %d source_position=%jd input_position=%jd\n", __LINE__, source_position, input_position); - Asset *asset = get_nested_asset(&source_position, - input_position, - direction); + Asset *asset = get_nested_asset(&source_position, input_position, direction); if( !asset ) result = 1; if(debug) printf("VEdit::read_frame %d source_position=%jd input_position=%jd\n", @@ -154,13 +102,8 @@ if(debug) printf("VEdit::read_frame %d path=%s source_position=%jd\n", __LINE__, asset->path, source_position); if( !result ) { -if(debug) printf("VEdit::read_frame %d\n", __LINE__); - source_position = (direction == PLAY_FORWARD) ? - source_position : - (source_position - 1); -if(debug) printf("VEdit::read_frame %d %jd %jd\n", - __LINE__, input_position, source_position); - + if(direction == PLAY_REVERSE && source_position > 0) + --source_position; if(use_asynchronous) file->start_video_decode_thread(); else diff --git a/cinelerra-5.1/cinelerra/virtualvnode.C b/cinelerra-5.1/cinelerra/virtualvnode.C index 5b7e3aea..4e285be1 100644 --- a/cinelerra-5.1/cinelerra/virtualvnode.C +++ b/cinelerra-5.1/cinelerra/virtualvnode.C @@ -203,7 +203,8 @@ int VirtualVNode::render_as_module(VFrame *video_out, int64_t start_position_project = (int64_t)(start_position * edl_rate / frame_rate); - if(direction == PLAY_REVERSE) start_position_project--; + if(direction == PLAY_REVERSE && start_position_project > 0 ) + start_position_project--; // speed curve diff --git a/cinelerra-5.1/cinelerra/vmodule.C b/cinelerra-5.1/cinelerra/vmodule.C index 93d6f4d9..e8016e1b 100644 --- a/cinelerra-5.1/cinelerra/vmodule.C +++ b/cinelerra-5.1/cinelerra/vmodule.C @@ -105,54 +105,31 @@ CICache* VModule::get_cache() -int VModule::import_frame(VFrame *output, - VEdit *current_edit, - int64_t input_position, - double frame_rate, - int direction, - int use_opengl) +int VModule::import_frame(VFrame *output, VEdit *current_edit, + int64_t input_position, double frame_rate, int direction, int use_opengl) { int64_t direction_position; // Translation of edit - float in_x; - float in_y; - float in_w; - float in_h; - float out_x; - float out_y; - float out_w; - float out_h; + float in_x, in_y, in_w, in_h; + float out_x, out_y, out_w, out_h; int result = 0; const int debug = 0; double edl_rate = get_edl()->session->frame_rate; int64_t input_position_project = Units::to_int64(input_position * - edl_rate / - frame_rate + - 0.001); - - - - - - + edl_rate / frame_rate + 0.001); if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output); //output->dump_params(); - if(debug) printf("VModule::import_frame %d this=%p input_position=%lld direction=%d\n", - __LINE__, - this, - (long long)input_position, - direction); + __LINE__, this, (long long)input_position, direction); // Convert to position corrected for direction direction_position = input_position; - if(direction == PLAY_REVERSE) - { - direction_position--; - input_position_project--; + if(direction == PLAY_REVERSE) { + if( direction_position > 0 ) direction_position--; + if( input_position_project > 0 ) input_position_project--; } if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output); @@ -168,28 +145,18 @@ int VModule::import_frame(VFrame *output, } if(!output) printf("VModule::import_frame %d output=%p x11_device=%p nested_edl=%p\n", - __LINE__, - output, - x11_device, - nested_edl); - + __LINE__, output, x11_device, nested_edl); if(debug) printf("VModule::import_frame %d current_edit=%p\n", - __LINE__, - current_edit); - + __LINE__, current_edit); // Load frame into output // Create objects for nested EDL - if(current_edit && - current_edit->nested_edl) - { + if(current_edit && current_edit->nested_edl) { int command; if(debug) printf("VModule::import_frame %d nested_edl=%p current_edit->nested_edl=%p\n", - __LINE__, - nested_edl, - current_edit->nested_edl); + __LINE__, nested_edl, current_edit->nested_edl); // Convert requested direction to command if(renderengine->command->command == CURRENT_FRAME) diff --git a/cinelerra-5.1/leaker.C b/cinelerra-5.1/leaker.C new file mode 100644 index 00000000..00987912 --- /dev/null +++ b/cinelerra-5.1/leaker.C @@ -0,0 +1,78 @@ +#include +#include + +#include +using namespace std; + +#if 0 +#define STRC(v) printf("==new %p from %p sz %jd\n", v, __builtin_return_address(0), n) +#define STRD(v) printf("==del %p from %p\n", v, __builtin_return_address(0)) +void *operator new(size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; } +void operator delete(void *t) { STRD(t); free(t); } +void operator delete(void *t,size_t n) { STRD(t); free(t); } +void *operator new[](size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; } +void operator delete[](void *t) { STRD(t); free(t); } +void operator delete[](void *t,size_t n) { STRD(t); free(t); } +#endif + + +class blob +{ +public: + int64_t adr, from, sz; + blob(int64_t adr, int64_t from, int64_t sz) { + this->adr = adr; this->from = from; this->sz = sz; + } +}; +typedef map recd_map; +typedef recd_map::value_type recd_val; +typedef recd_map::iterator recd_it; + +int main(int ac, char **av) +{ + int64_t adr, from, sz; + recd_map recds; + char line[256]; + FILE *fp = stdin; + + while( fgets(line,sizeof(line),fp) ) { + if( line[0] != '=' ) continue; + if( line[1] != '=' ) continue; + if( sscanf(line, "==new %jx from %jx sz %jd\n", &adr, &from, &sz) == 3 ) { + recds.insert(recd_val(adr, new blob(adr,from,sz))); + continue; + } + if( sscanf(line, "==del %jx from %jx\n", &adr, &from) == 2 ) { + recd_it ri = recds.lower_bound(adr); + if( ri == recds.end() || ri->first != adr ) { + printf("del miss adr %jx\n", adr); + continue; + } + recds.erase(ri); + } + } + + int64_t n = recds.size(); sz = 0; + for( recd_it ri = recds.begin(); ri != recds.end(); ++ri ) sz += ri->second->sz; + printf("in use: %jd sz %jd\n", n, sz); + + recd_map leaks; + for( recd_it ri = recds.begin(); ri != recds.end(); ++ri ) { + adr = ri->second->adr; from = ri->second->from; sz = ri->second->sz; + recd_it li = leaks.lower_bound(from); + if( li == leaks.end() || li->first != from ) { + leaks.insert(recd_val(from, new blob(adr,from,sz))); + } + else { + li->second->sz += sz; + } + } + sz = 0; n = 0; + for( recd_it li = leaks.begin(); li != leaks.end(); ++li,++n ) { + printf("==leak at %jx sz %jd\n", li->second->from, li->second->sz); + sz += li->second->sz; + } + printf("leakers: %jd/%jd sz %jd\n", leaks.size(), n, sz); + return 0; +} + diff --git a/cinelerra-5.1/plugins/C41/c41.C b/cinelerra-5.1/plugins/C41/c41.C index 32f5afe3..6a382935 100644 --- a/cinelerra-5.1/plugins/C41/c41.C +++ b/cinelerra-5.1/plugins/C41/c41.C @@ -707,21 +707,25 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output) if( row[2] > maxima_b ) maxima_b = row[2]; } } - if( minima_r < 1e-6 ) minima_r = 1e-6; - if( minima_g < 1e-6 ) minima_g = 1e-6; - if( minima_b < 1e-6 ) minima_b = 1e-6; values.min_r = minima_r; values.max_r = maxima_r; values.min_g = minima_g; values.max_g = maxima_g; values.min_b = minima_b; values.max_b = maxima_b; values.light = maxima_r < 1e-6 ? 1.0 : minima_r / maxima_r; - values.gamma_g = logf(maxima_r / minima_r) / logf(maxima_g / minima_g); - values.gamma_b = logf(maxima_r / minima_r) / logf(maxima_b / minima_b); + bclamp(minima_r, 1e-6, 1-1e-6); bclamp(maxima_r, 1e-6, 1-1e-6); + bclamp(minima_g, 1e-6, 1-1e-6); bclamp(maxima_g, 1e-6, 1-1e-6); + bclamp(minima_b, 1e-6, 1-1e-6); bclamp(maxima_b, 1e-6, 1-1e-6); + float log_r = logf(maxima_r / minima_r); + float log_g = logf(maxima_g / minima_g); + float log_b = logf(maxima_b / minima_b); + if( log_g < 1e-6 ) log_g = 1e-6; + if( log_b < 1e-6 ) log_b = 1e-6; + values.gamma_g = log_r / log_g; + values.gamma_b = log_r / log_b; values.shave_min_col = shave_min_col; values.shave_max_col = shave_max_col; values.shave_min_row = shave_min_row; values.shave_max_row = shave_max_row; - values.coef1 = -1; - values.coef2 = -1; + values.coef1 = values.coef2 = -1; // Update GUI send_render_gui(&values); @@ -764,20 +768,14 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output) // Calculate postprocessing coeficents values.coef2 = minima_r; - if( minima_g < values.coef2 ) - values.coef2 = minima_g; - if( minima_b < values.coef2 ) - values.coef2 = minima_b; + if( minima_g < values.coef2 ) values.coef2 = minima_g; + if( minima_b < values.coef2 ) values.coef2 = minima_b; values.coef1 = maxima_r; - if( maxima_g > values.coef1 ) - values.coef1 = maxima_g; - if( maxima_b > values.coef1 ) - values.coef1 = maxima_b; - // Try not to overflow RGB601 - // (235 - 16) / 256 * 0.9 + if( maxima_g > values.coef1 ) values.coef1 = maxima_g; + if( maxima_b > values.coef1 ) values.coef1 = maxima_b; + // Try not to overflow RGB601 (235 - 16) / 256 * 0.9 float den = values.coef1 - values.coef2; - if( fabs(den) < 1e-6 ) - den = den < 0 ? -1e-6 : 1e-6; + if( fabs(den) < 1e-6 ) den = 1e-6; values.coef1 = 0.770 / den; values.coef2 = 0.065 - values.coef2 * values.coef1; send_render_gui(&values); -- 2.26.2