ffmpeg filter memory leak, cursor hopper fix, added leaker.C, misc fixes
authorGood Guy <good1.2guy@gmail.com>
Sun, 13 Aug 2017 19:46:32 +0000 (13:46 -0600)
committerGood Guy <good1.2guy@gmail.com>
Sun, 13 Aug 2017 19:46:32 +0000 (13:46 -0600)
17 files changed:
cinelerra-5.1/PKGBUILD
cinelerra-5.1/cinelerra/canvas.C
cinelerra-5.1/cinelerra/canvas.h
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/formatpopup.C
cinelerra-5.1/cinelerra/main.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/new.C
cinelerra-5.1/cinelerra/playbackengine.C
cinelerra-5.1/cinelerra/playtransport.C
cinelerra-5.1/cinelerra/vdevicex11.C
cinelerra-5.1/cinelerra/vedit.C
cinelerra-5.1/cinelerra/virtualvnode.C
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/leaker.C [new file with mode: 0644]
cinelerra-5.1/plugins/C41/c41.C

index 97042e05e248a25d0de833b38fe863eb00c5a247..f7953dd995156bdaf6a9f09c96182876b0ffe8b4 100644 (file)
@@ -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')
index b2bd838ddb01d94c81b535e1e8a6c517cc87766a..72d8a906544c86c63ab63b2f1d94ea5c9e675b93 100644 (file)
@@ -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);
+}
 
 
 
index 27336588f67f166125b6a13d64dc86056837da22..c5d53703a791cd34d9e6e6bd5b432ebcf04b9875 100644 (file)
@@ -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.
index c3bf4b61b88ddf0a7b491edf3fc4556344853d9f..24a515fa83a3f3ec6009ab7211651dab01990545 100644 (file)
@@ -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);
index 547b7f074f1276262838c65b5d6d5f8a361ce424..b451c79780127ca1dbffe59f0f2a62dae583cc94 100644 (file)
@@ -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()) ) {
index 683c7117d076e0b87bde18ad98a76e39e3a24f59..06e41453a561a34fe538cbaf9c68161c89f0b188 100644 (file)
@@ -40,10 +40,9 @@ FormatPopup::FormatPopup(ArrayList<PluginServer*> *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)));
index caa04a83b69af29295eb7d2974fcb2d095f90928..0241780313371c57dc97c304c3f4ebf1646dc07f 100644 (file)
 #include <string.h>
 
 #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
index 8824b86872be7cd9430fbdddff51c639a2035935..6e1ecaa912d094629747dbd28d3c122f03237679 100644 (file)
@@ -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
index 949de932ad505907849abf942f41342f8ba2b5b5..9f0c70d507c1545b48bb58f943ea386922c5c78c 100644 (file)
@@ -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");
 
index 802b7b610c24e04ed931085319a6310d3d0fa4f4..9f826401d755cfe1fafd11268434905661375f93 100644 (file)
@@ -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);
+       }
 }
 
 
index a426ac79336e6509c098c5ce475413985bffad05..0774c8a493d1eeb761af2830517e17d25dbc46ad 100644 (file)
@@ -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);
-               }
        }
 }
 
index 641a6760bd03f0167c8e315083e54eb896ef63e3..31873e6a4c1b79d7687cc8231f27798baf5e64c5 100644 (file)
@@ -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();
        }
 
index 775822fe5a0976201d0a6f2ce97ce6de3b98151a..f8469b10410d67f2179fe869aae8b3638866f2e8 100644 (file)
@@ -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
index 5b7e3aea6e560ec28419a7357ef33d772512d446..4e285be1b735fcbca8b661800a956330d03e32da 100644 (file)
@@ -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
index 93d6f4d9e4fa73f782018ca5806db825312f43d3..e8016e1b5e3bc5e8f084dca2252f8000347ad33b 100644 (file)
@@ -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 (file)
index 0000000..0098791
--- /dev/null
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <strings.h>
+
+#include <map>
+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<int64_t, blob*> 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;
+}
+
index 32f5afe322faec964013338e4175bf0047a5ec2f..6a3829354c49b3930bf846d0d542784f8cd3e9a4 100644 (file)
@@ -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);