histogram rework to add sum_frames, update suv/cakewalk autorange icons, add new...
authorGood Guy <[email protected]>
Fri, 9 Oct 2020 01:06:33 +0000 (19:06 -0600)
committerGood Guy <[email protected]>
Fri, 9 Oct 2020 01:06:33 +0000 (19:06 -0600)
29 files changed:
cinelerra-5.1/cinelerra/convert.C
cinelerra-5.1/cinelerra/convert.h
cinelerra-5.1/cinelerra/recordgui.C
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/guicast/vicon.C
cinelerra-5.1/plugin_defs
cinelerra-5.1/plugins/Makefile
cinelerra-5.1/plugins/histogram/histogram.C
cinelerra-5.1/plugins/histogram/histogram.h
cinelerra-5.1/plugins/histogram/histogram.inc
cinelerra-5.1/plugins/histogram/histogramconfig.C
cinelerra-5.1/plugins/histogram/histogramconfig.h
cinelerra-5.1/plugins/histogram/histogramwindow.C
cinelerra-5.1/plugins/histogram/histogramwindow.h
cinelerra-5.1/plugins/histogram/histogramwindow.inc
cinelerra-5.1/plugins/theme_cakewalk/data/autorange_bottom.png
cinelerra-5.1/plugins/theme_cakewalk/data/autorange_hi.png
cinelerra-5.1/plugins/theme_cakewalk/data/autorange_top.png
cinelerra-5.1/plugins/theme_cakewalk/data/autorange_up.png
cinelerra-5.1/plugins/theme_suv/data/autorange_bottom.png
cinelerra-5.1/plugins/theme_suv/data/autorange_hi..png [deleted file]
cinelerra-5.1/plugins/theme_suv/data/autorange_hi.png
cinelerra-5.1/plugins/theme_suv/data/autorange_top.png
cinelerra-5.1/plugins/theme_suv/data/autorange_up.png
cinelerra-5.1/plugins/timeblur/Makefile [new file with mode: 0644]
cinelerra-5.1/plugins/timeblur/timeblur.C [new file with mode: 0644]
cinelerra-5.1/plugins/timeblur/timeblur.h [new file with mode: 0644]
cinelerra-5.1/plugins/timeblur/timeblurwindow.C [new file with mode: 0644]
cinelerra-5.1/plugins/timeblur/timeblurwindow.h [new file with mode: 0644]

index c6ecb0438ad271d89869f82a0357d75a3499164b..45fff292840f8e60a97de0f187bf7a5e4053f393 100644 (file)
@@ -71,10 +71,19 @@ ConvertRender::ConvertRender(MWindow *mwindow)
        result = 0;
        beep = 0;
        to_proxy = 0;
+       renderer = 0;
 }
 
 ConvertRender::~ConvertRender()
 {
+       if( running() ) {
+               canceled = 1;
+               if( renderer )
+                       renderer->set_result(1);
+               cancel();
+               join();
+       }
+       delete renderer;
        delete [] suffix;
        delete progress;
        delete counter_lock;
@@ -515,19 +524,20 @@ void ConvertRender::create_copy(int i)
        Asset *needed_copy = needed_copies[i];
        EDL *edl = convert_edl(mwindow->edl, orig_idxbl);
        double length = get_length(orig_idxbl);
-       ConvertPackageRenderer renderer(this);
-       renderer.initialize(mwindow, edl, mwindow->preferences, needed_copy);
+       renderer = new ConvertPackageRenderer(this);
+       renderer->initialize(mwindow, edl, mwindow->preferences, needed_copy);
        PackageDispatcher dispatcher;
        dispatcher.create_packages(mwindow, edl, mwindow->preferences,
                SINGLE_PASS, needed_copy, 0, length, 0);
        RenderPackage *package = dispatcher.get_package(0);
-       if( !renderer.render_package(package) ) {
+       if( !renderer->render_package(package) ) {
                Asset *asset = mwindow->edl->assets->update(needed_copy);
                mwindow->mainindexes->add_indexable(asset);
                mwindow->mainindexes->start_build();
        }
        else
                failed = 1;
+       delete renderer;  renderer = 0;
        edl->remove_user();
 }
 
index dde071d4c1e137f64b733295361487d163e4feaa..41c125c9b6977626b24f9cc1867ebe0cdb17743b 100644 (file)
@@ -74,6 +74,7 @@ public:
        MainProgressBar *progress;
        ConvertProgress *convert_progress;
        Timer *progress_timer;
+       ConvertPackageRenderer *renderer;
 
        Mutex *counter_lock;
        int total_rendered, remove_originals;
@@ -151,7 +152,7 @@ class ConvertPackageRenderer : public PackageRenderer
 {
 public:
        ConvertPackageRenderer(ConvertRender *render);
-       ~ConvertPackageRenderer();
+       virtual ~ConvertPackageRenderer();
 
        int get_master();
        int get_result();
index c2fbe0ecf2c2a1bc7ba6c4c096feb0ee65bfacbe..d425dbce17e6bff9665ce546fd357a1627aecfd9 100644 (file)
@@ -809,6 +809,16 @@ int RecordGUIMonitorVideo::handle_event()
                lock_window("RecordGUIMonitorVideo::handle_event");
                record->video_window_open = 1;
        }
+       else {
+               unlock_window();
+               BC_Window *window = record->record_monitor->window;
+               window->lock_window("RecordGUIMonitorVideo::handle_event");
+               window->hide_window();
+               window->flush();
+               window->unlock_window();
+               lock_window("RecordGUIMonitorVideo::handle_event");
+               record->video_window_open = 0;
+       }
        return 1;
 }
 
index ce7ecadc59529194233ade5524569f8218d4ab90..e2a2f7f6f8453e264919a08826694205b54104a3 100644 (file)
@@ -237,23 +237,18 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
 // Make positions based on requested frame rate.
                        int64_t position = Units::to_int64((double)pos * frame_rate / edl_rate);
 
-                       int64_t max_position;
+                       int64_t video_length;
                        int asset_w, asset_h;
                        if( file ) {
                                asset_w = current_edit->asset->width;
                                asset_h = current_edit->asset->height;
-                               max_position = Units::to_int64((double)file->get_video_length() *
-                                       frame_rate / current_edit->asset->frame_rate - 1);
+                               video_length = file->get_video_length();
                        }
                        else {
                                asset_w = nested_edl->session->output_w;
                                asset_h = nested_edl->session->output_h;
-                               max_position = Units::to_int64(nested_edl->tracks->total_length() *
-                                       frame_rate - 1);
+                               video_length = nested_edl->tracks->total_length();
                        }
-                       if( max_position < 0 ) max_position = 0;
-// if we hit the end of stream, freeze at last frame
-                       CLAMP(position, 0, max_position);
 
                        VFrame *&input = commonrender ?
                                ((VRender*)commonrender)->input_temp : // Realtime playback
@@ -302,6 +297,10 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
                                                curr_pos += current_edit->startsource;
                                                int64_t norm_pos = Units::to_int64((double)curr_pos *
                                                        current_edit->asset->frame_rate / edl_rate);
+                                               if( norm_pos < 0 || video_length < 0 )
+                                                       norm_pos = 0;
+                                               else if( norm_pos >= video_length )
+                                                       norm_pos = video_length-1;
                                                if( first_frame ) {
                                                        if( file->get_cache_frame(input, norm_pos) )
                                                                break;  // if inside a cache run
@@ -318,6 +317,10 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
 
                                int64_t normalized_position = Units::to_int64((double)position *
                                        current_edit->asset->frame_rate / frame_rate);
+                               if( normalized_position < 0 || video_length < 0 )
+                                       normalized_position = 0;
+                               else if( normalized_position >= video_length )
+                                       normalized_position = video_length-1;
 //printf("VModule::import_frame %d %lld %lld\n", __LINE__, position, normalized_position);
                                file->set_layer(current_edit->channel);
                                file->set_video_position(normalized_position, 0);
index 9d6b94e0ed0add20e2721b3437d1499d0605b680..84c675ef79feb9eaf376766e6b430b556d103893 100644 (file)
@@ -279,9 +279,10 @@ update_view(int do_audio)
 {
        if( viewing ) viewing->stop_audio();
        delete view_win;  view_win = 0;
-       if( (viewing=vicon) != 0 ) {
+       VFrame *vfrm;
+       if( (viewing=vicon) != 0 && (vfrm=viewing->frame()) != 0 ) {
                view_win = new_view_window(0);
-               view_win->draw_vframe(viewing->frame());
+               view_win->draw_vframe(vfrm);
                view_win->flash(0);
                view_win->show_window();
                if( do_audio ) vicon->start_audio();
@@ -292,14 +293,15 @@ update_view(int do_audio)
 
 int VIconThread::zoom_scale(int dir)
 {
-       if( !viewing || !view_win ) return 0;
+       VFrame *vfrm;
+       if( !viewing || !view_win || !(vfrm=viewing->frame()) ) return 0;
        int view_h = this->view_h;
        view_h += dir*view_h/10 + dir;
        bclamp(view_h, 16,512);
        this->view_h = view_h;
        this->view_w = view_h * vw/vh;
        new_view_window(view_win);
-       view_win->draw_vframe(viewing->frame());
+       view_win->draw_vframe(vfrm);
        view_win->flash(1);
        return 1;
 }
@@ -328,13 +330,14 @@ draw(VIcon *vicon)
        int draw_img = visible(vicon, x, y);
        int draw_win = view_win && viewing == vicon ? 1 : 0;
        if( !draw_img && !draw_win ) return 0;
-       if( !vicon->frame() ) return 0;
+       VFrame *vfrm = vicon->frame();
+       if( !vfrm ) return 0;
        if( draw_img ) {
                vicon->draw_vframe(this, wdw, x, y);
                img_dirty = 1;
        }
        if( draw_win ) {
-               view_win->draw_vframe(vicon->frame());
+               view_win->draw_vframe(vfrm);
                win_dirty = 1;
        }
        return 1;
index 9376d5db8f79a5c6797bdbd07debe113f5dd70e3..137c49f468e17711b19dd7e79e9cb59f9831a900 100644 (file)
@@ -112,6 +112,7 @@ video := \
        swapframes \
        threshold \
        timeavg \
+       timeblur \
        timefront \
        titler \
        tracer \
index 178e0ef210f49b3f291973efc9194b71d373d43b..39230250687fadfa422a58c8e029dc1994c45e1f 100644 (file)
@@ -140,6 +140,7 @@ DIRS = $(OPENCV_OBJS) \
        synthesizer \
        threshold \
        timeavg \
+       timeblur \
        timefront \
        timestretch \
        timestretchrt \
index a2cf0c987e555dca592ee089ff6bdb45656a7f0b..c78c3c7c44eb3b44c547de8f81059dd7f4ba7b68 100644 (file)
@@ -62,23 +62,24 @@ HistogramMain::HistogramMain(PluginServer *server)
  : PluginVClient(server)
 {
        engine = 0;
-       stripe_engine = 0;
        for( int i=0; i<HISTOGRAM_MODES; ++i ) {
-               lookup[i] = 0;
-               accum[i] = 0;
-               preview_lookup[i] = 0;
+               lookup[i] = new int[0x10000];
+               preview_lookup[i] = new int[0x10000];
+               accum[i] = new int64_t[HISTOGRAM_SLOTS];
+               bzero(accum[i], sizeof(int64_t)*HISTOGRAM_SLOTS);
        }
        current_point = -1;
        mode = HISTOGRAM_VALUE;
+       last_position = -1;
+       need_reconfigure = 1;
+       sum_frames = 0;
+       frames = 1;
        dragging_point = 0;
        input = 0;
        output = 0;
        w = 440;
        h = 500;
        parade = 0;
-       fframe = 0;
-       last_frames = 0;
-       last_position = -1;
 }
 
 HistogramMain::~HistogramMain()
@@ -86,12 +87,10 @@ HistogramMain::~HistogramMain()
 
        for( int i=0; i<HISTOGRAM_MODES; ++i ) {
                delete [] lookup[i];
-               delete [] accum[i];
                delete [] preview_lookup[i];
+               delete [] accum[i];
        }
        delete engine;
-       delete stripe_engine;
-       delete fframe;
 }
 
 const char* HistogramMain::plugin_title() { return N_("Histogram"); }
@@ -105,50 +104,22 @@ LOAD_CONFIGURATION_MACRO(HistogramMain, HistogramConfig)
 
 void HistogramMain::render_gui(void *data)
 {
-       input = (VFrame*)data;
-       if( thread ) {
-// Process just the RGB values to determine the automatic points or
-// all the points if manual
-               if( !config.automatic ) {
-// Generate curves for value histogram
-// Lock out changes to curves
-                       ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 1");
-                       tabulate_curve(HISTOGRAM_RED, 0);
-                       tabulate_curve(HISTOGRAM_GREEN, 0);
-                       tabulate_curve(HISTOGRAM_BLUE, 0);
-                       tabulate_curve(preview_lookup, HISTOGRAM_RED, 0x10000, 0);
-                       tabulate_curve(preview_lookup, HISTOGRAM_GREEN, 0x10000, 0);
-                       tabulate_curve(preview_lookup, HISTOGRAM_BLUE, 0x10000, 0);
-                       ((HistogramWindow*)thread->window)->unlock_window();
-               }
-
-               calculate_histogram(input, !config.automatic);
-
-               if( config.automatic ) {
-                       calculate_automatic(input);
-// Generate curves for value histogram
-// Lock out changes to curves
-                       ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 1");
-                       tabulate_curve(HISTOGRAM_RED, 0);
-                       tabulate_curve(HISTOGRAM_GREEN, 0);
-                       tabulate_curve(HISTOGRAM_BLUE, 0);
-                       tabulate_curve(preview_lookup, HISTOGRAM_RED, 0x10000, 0);
-                       tabulate_curve(preview_lookup, HISTOGRAM_GREEN, 0x10000, 0);
-                       tabulate_curve(preview_lookup, HISTOGRAM_BLUE, 0x10000, 0);
-                       ((HistogramWindow*)thread->window)->unlock_window();
-// Need a second pass to get the luminance values.
-                       calculate_histogram(input, 1);
-               }
-
-               ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 2");
-// Always draw the histogram but don't update widgets if automatic
-               ((HistogramWindow*)thread->window)->update(1,
-                       config.automatic && mode != HISTOGRAM_VALUE,
-                       config.automatic && mode != HISTOGRAM_VALUE,
-                       0);
-
-               ((HistogramWindow*)thread->window)->unlock_window();
+       if( !thread ) return;
+       HistogramWindow *window = (HistogramWindow*)thread->window;
+       HistogramMain *plugin = (HistogramMain*)data;
+//update gui client instance, needed for drawing
+       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
+               config.low_input[i] = plugin->config.low_input[i];
+               config.high_input[i] = plugin->config.high_input[i];
+               memcpy(accum[i], plugin->accum[i], HISTOGRAM_SLOTS*sizeof(*accum));
        }
+       window->lock_window("HistogramMain::render_gui 2");
+// draw all if reconfigure
+       int reconfig = plugin->need_reconfigure;
+// Always draw the histogram but don't update widgets if automatic
+       int auto_rgb = reconfig ? 1 : config.automatic && mode != HISTOGRAM_VALUE ? 1 : 0;
+       window->update(1, auto_rgb, auto_rgb, reconfig);
+       window->unlock_window();
 }
 
 void HistogramMain::update_gui()
@@ -166,7 +137,6 @@ void HistogramMain::update_gui()
 void HistogramMain::save_data(KeyFrame *keyframe)
 {
        FileXML output;
-
 // cause data to be stored directly in text
        output.set_shared_output(keyframe->xbuf);
        output.tag.set_title("HISTOGRAM");
@@ -176,8 +146,8 @@ void HistogramMain::save_data(KeyFrame *keyframe)
        output.tag.set_property("AUTOMATIC", config.automatic);
        output.tag.set_property("THRESHOLD", config.threshold);
        output.tag.set_property("PLOT", config.plot);
+       output.tag.set_property("SUM_FRAMES", config.sum_frames);
        output.tag.set_property("SPLIT", config.split);
-       output.tag.set_property("FRAMES", config.frames);
        output.tag.set_property("LOG_SLIDER", config.log_slider);
        output.tag.set_property("W", w);
        output.tag.set_property("H", h);
@@ -216,8 +186,8 @@ void HistogramMain::read_data(KeyFrame *keyframe)
                        config.automatic = input.tag.get_property("AUTOMATIC", config.automatic);
                        config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
                        config.plot = input.tag.get_property("PLOT", config.plot);
+                       config.sum_frames = input.tag.get_property("SUM_FRAMES", config.sum_frames);
                        config.split = input.tag.get_property("SPLIT", config.split);
-                       config.frames = input.tag.get_property("FRAMES", config.frames);
                        config.log_slider = input.tag.get_property("LOG_SLIDER", config.log_slider);
 
                        if( is_defaults() ) {
@@ -289,21 +259,22 @@ void HistogramMain::calculate_histogram(VFrame *data, int do_value)
                if( cpus > smps ) cpus = smps;
                engine = new HistogramEngine(this, cpus, cpus);
        }
-       if( !accum[0] ) {
-               for( int i=0; i<HISTOGRAM_MODES; ++i )
-                       accum[i] = new int[HISTOGRAM_SLOTS];
-       }
 
        engine->process_packages(HistogramEngine::HISTOGRAM, data, do_value);
 
+       int k = 0;
        HistogramUnit *unit = (HistogramUnit*)engine->get_client(0);
-       for( int i=0; i<HISTOGRAM_MODES; ++i )
-               memcpy(accum[i], unit->accum[i], sizeof(int)*HISTOGRAM_SLOTS);
+       if( !sum_frames ) {
+               frames = 0;
+               for( int i=0; i<HISTOGRAM_MODES; ++i )
+                       memcpy(accum[i], unit->accum[i], sizeof(int64_t)*HISTOGRAM_SLOTS);
+               k = 1;
+       }
 
-       for( int i=1,n=engine->get_total_clients(); i<n; ++i ) {
+       for( int i=k,n=engine->get_total_clients(); i<n; ++i ) {
                unit = (HistogramUnit*)engine->get_client(i);
                for( int j=0; j<HISTOGRAM_MODES; ++j ) {
-                       int *in = unit->accum[j], *out = accum[j];
+                       int64_t *in = unit->accum[j], *out = accum[j];
                        for( int k=HISTOGRAM_SLOTS; --k>=0; ) *out++ += *in++;
                }
        }
@@ -314,6 +285,7 @@ void HistogramMain::calculate_histogram(VFrame *data, int do_value)
                accum[i][0] = 0;
                accum[i][HISTOGRAM_SLOTS - 1] = 0;
        }
+       ++frames;
 }
 
 
@@ -324,14 +296,16 @@ void HistogramMain::calculate_automatic(VFrame *data)
 
 // Do each channel
        for( int i=0; i<3; ++i ) {
-               int *accum = this->accum[i];
-               int pixels = data->get_w() * data->get_h();
+               int64_t *accum = this->accum[i];
+               int64_t sz = data->get_w() * data->get_h();
+               int64_t pixels = sz * frames;
                float white_fraction = 1.0 - (1.0 - config.threshold) / 2;
                int threshold = (int)(white_fraction * pixels);
                float min_level = 0.0, max_level = 1.0;
 
 // Get histogram slot above threshold of pixels
-               for( int j=0, total=0; j<HISTOGRAM_SLOTS; ++j ) {
+               int64_t total = 0;
+               for( int j=0; j<HISTOGRAM_SLOTS; ++j ) {
                        total += accum[j];
                        if( total >= threshold ) {
                                max_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
@@ -339,8 +313,9 @@ void HistogramMain::calculate_automatic(VFrame *data)
                        }
                }
 
-// Get slot below 99% of pixels
-               for( int j=HISTOGRAM_SLOTS, total=0; --j> 0; ) {
+// Get histogram slot below threshold of pixels
+               total = 0;
+               for( int j=HISTOGRAM_SLOTS; --j> 0; ) {
                        total += accum[j];
                        if( total >= threshold ) {
                                min_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
@@ -368,100 +343,34 @@ int HistogramMain::process_buffer(VFrame *frame,
        int64_t start_position,
        double frame_rate)
 {
-       int need_reconfigure = load_configuration();
+       need_reconfigure = load_configuration();
        int use_opengl = calculate_use_opengl();
-
+       sum_frames = last_position == start_position ? config.sum_frames : 0;
+       last_position = get_direction() == PLAY_FORWARD ?
+                       start_position+1 : start_position-1;
        this->input = frame;
        this->output = frame;
        int cpus = input->get_w() * input->get_h() / 0x80000 + 2;
        int smps = get_project_smp();
        if( cpus > smps ) cpus = smps;
-       if( !engine ) {
+       if( !engine )
                engine = new HistogramEngine(this, cpus, cpus);
+       read_frame(frame, 0, start_position, frame_rate, use_opengl);
+       if( config.automatic )
+               calculate_automatic(frame);
+       if( config.plot ) {
+// Generate curves for value histogram
+               tabulate_curve(lookup, 0);
+               tabulate_curve(preview_lookup, 0, 0x10000);
+// Need to get the luminance values.
+               calculate_histogram(input, 1);
+               send_render_gui(this);
        }
-       int frames = config.frames;
-       MWindow *mwindow = server->mwindow;
-       if( frames > 1 && (!mwindow || // dont scan during SELECT_REGION
-             mwindow->session->current_operation != SELECT_REGION ||
-             mwindow->edl->local_session->get_selectionstart() ==
-                 mwindow->edl->local_session->get_selectionend() ) ) {
-               if( !stripe_engine )
-                       stripe_engine = new HistStripeEngine(this, cpus, cpus);
-               int fw = frame->get_w(), fh =frame->get_h();
-               new_temp(fw, fh, BC_RGB_FLOAT);
-               MWindow *mwindow = server->mwindow;
-               if( (mwindow && mwindow->session->current_operation == SELECT_REGION) ||
-                   ( last_frames == frames && last_position-1 == start_position &&
-                     fframe && fframe->get_w() == fw && fframe->get_h() == fh ) ) {
-                       read_frame(temp, 0, start_position, frame_rate, use_opengl);
-                       stripe_engine->process_packages(ADD_FFRM);
-                       frame->transfer_from(temp);
-               }
-               else if( last_frames != frames || last_position != start_position ||
-                     !fframe || fframe->get_w() != fw || fframe->get_h() != fh ) {
-                       last_frames = frames;
-                       last_position = start_position;
-                       VFrame::get_temp(fframe, fw, fh, BC_RGB_FLOAT);
-                       read_frame(fframe, 0, start_position+1, frame_rate, use_opengl);
-                       BC_ProgressBox *progress = 0;
-                       const char *progress_title = _("Histogram: scanning\n");
-                       Timer timer;
-                       for( int i=2; i<frames; ++i ) {
-                                read_frame(temp, 0, start_position+i, frame_rate, use_opengl);
-                               stripe_engine->process_packages(ADD_TEMP);
-                               if( !progress && gui_open() && frames > 2*frame_rate ) {
-                                       progress = new BC_ProgressBox(-1, -1, progress_title, frames);
-                                       progress->start();
-                               }
-                               if( progress && timer.get_difference() > 100 ) {
-                                       timer.update();
-                                       progress->update(i, 1);
-                                       char string[BCTEXTLEN];
-                                       sprintf(string, "%sframe: %d", progress_title, i);
-                                       progress->update_title(string, 1);
-                                       if( progress->is_cancelled() ) break;
-                               }
-                               if( progress && !gui_open() ) {
-                                       progress->stop_progress();
-                                       delete progress;  progress = 0;
-                               }
-                       }
-                       read_frame(temp, 0, start_position, frame_rate, use_opengl);
-                       stripe_engine->process_packages(ADD_FFRMS);
-                       frame->transfer_from(temp);
-                       if( progress ) {
-                               progress->stop_progress();
-                               delete progress;
-                       }
-                       ++last_position;
-               }
-               else {
-                       read_frame(temp, 0, start_position+frames-1, frame_rate, use_opengl);
-                       stripe_engine->process_packages(ADD_TEMPS);
-                       frame->transfer_from(fframe);
-                       read_frame(temp, 0, start_position, frame_rate, use_opengl);
-                       stripe_engine->process_packages(SUB_TEMPS);
-                       ++last_position;
-               }
-       }
-       else
-               read_frame(frame, 0, start_position, frame_rate, use_opengl);
 
-// if to plot histogram
-       if(config.plot) send_render_gui(frame);
-
-// Generate tables here.  The same table is used by many packages to render
-// each horizontal stripe.  Need to cover the entire output range in  each
-// table to avoid green borders
-
-
-       if( need_reconfigure || !lookup[0] || config.automatic ) {
+       if( need_reconfigure || config.automatic || config.plot ) {
 // Calculate new curves
-               if( config.automatic )
-                       calculate_automatic(input);
 // Generate transfer tables with value function for integer colormodels.
-               for( int i=0; i<3; ++i )
-                       tabulate_curve(i, 1);
+               tabulate_curve(lookup, 1);
        }
 
 // Apply histogram in hardware
@@ -473,24 +382,26 @@ int HistogramMain::process_buffer(VFrame *frame,
        return 0;
 }
 
-void HistogramMain::tabulate_curve(int **table, int idx, int len, int use_value)
+void HistogramMain::tabulate_curve(int **table, int idx, int use_value, int len)
 {
-       if( !table[idx] )  // must use max demand here
-               table[idx] = new int[0x10000];
-       int *curve = table[idx], len1 = len-1;
+       int len1 = len - 1;
+       int *curve = table[idx];
        for( int i=0; i<len; ++i ) {
                curve[i] = calculate_level((float)i/len1, idx, use_value) * len1;
                CLAMP(curve[i], 0, len1);
        }
 }
 
-void HistogramMain::tabulate_curve(int idx, int use_value)
+void HistogramMain::tabulate_curve(int **table, int use_value, int len)
 {
 // uint8 rgb is 8 bit, all others are converted to 16 bit RGB
-       int color_model = input->get_color_model();
-       int lookup_len = color_model == BC_RGB888 ||
-                 color_model == BC_RGBA8888 ? 0x100 : 0x10000;
-       tabulate_curve(lookup, idx, lookup_len, use_value);
+       if( len < 0 ) {
+               int color_model = input->get_color_model();
+               len = color_model == BC_RGB888 || color_model == BC_RGBA8888 ?
+                       0x100 : 0x10000;
+       }
+       for( int i=0; i<3; ++i )
+               tabulate_curve(table, i, use_value, len);
 }
 
 int HistogramMain::handle_opengl()
@@ -750,121 +661,6 @@ int HistogramMain::handle_opengl()
 }
 
 
-HistStripePackage::HistStripePackage()
- : LoadPackage()
-{
-}
-
-HistStripeUnit::HistStripeUnit(HistStripeEngine *server, HistogramMain *plugin)
- : LoadClient(server)
-{
-       this->plugin = plugin;
-       this->server = server;
-}
-
-void HistStripeUnit::process_package(LoadPackage *package)
-{
-       HistStripePackage *pkg = (HistStripePackage*)package;
-       int frames = plugin->config.frames;
-       float scale = 1. / frames;
-       int iy0 = pkg->y0, iy1 = pkg->y1;
-       int fw = plugin->fframe->get_w();
-       uint8_t **frows = plugin->fframe->get_rows();
-       uint8_t **trows = plugin->temp->get_rows();
-       switch( server->operation ) {
-       case ADD_TEMP:  // add temp to fframe
-               for( int iy=iy0; iy<iy1; ++iy ) {
-                       float *trow = (float *)trows[iy];
-                       float *frow = (float *)frows[iy];
-                       for( int ix=0; ix<fw; ++ix ) {
-                               *frow++ += *trow++;
-                               *frow++ += *trow++;
-                               *frow++ += *trow++;
-                       }
-               }
-               break;
-       case ADD_FFRM:  // add fframe to scaled temp
-               for( int iy=iy0; iy<iy1; ++iy ) {
-                       float *trow = (float *)trows[iy];
-                       float *frow = (float *)frows[iy];
-                       for( int ix=0; ix<fw; ++ix ) {
-                               *trow = *trow * scale + *frow++;  ++trow;
-                               *trow = *trow * scale + *frow++;  ++trow;
-                               *trow = *trow * scale + *frow++;  ++trow;
-                       }
-               }
-               break;
-       case ADD_FFRMS:  // add fframe to temp, scale temp, scale fframe
-               for( int iy=iy0; iy<iy1; ++iy ) {
-                       float *trow = (float *)trows[iy];
-                       float *frow = (float *)frows[iy];
-                       for( int ix=0; ix<fw; ++ix ) {
-                               *trow += *frow;  *trow++ *= scale;  *frow++ *= scale;
-                               *trow += *frow;  *trow++ *= scale;  *frow++ *= scale;
-                               *trow += *frow;  *trow++ *= scale;  *frow++ *= scale;
-                       }
-               }
-               break;
-       case ADD_TEMPS:  // add scaled temp to fframe
-               for( int iy=iy0; iy<iy1; ++iy ) {
-                       float *trow = (float *)trows[iy];
-                       float *frow = (float *)frows[iy];
-                       for( int ix=0; ix<fw; ++ix ) {
-                               *frow++ += *trow++ * scale;
-                               *frow++ += *trow++ * scale;
-                               *frow++ += *trow++ * scale;
-                       }
-               }
-               break;
-       case SUB_TEMPS:  // sub scaled temp from frame
-               for( int iy=iy0; iy<iy1; ++iy ) {
-                       float *trow = (float *)trows[iy];
-                       float *frow = (float *)frows[iy];
-                       for( int ix=0; ix<fw; ++ix ) {
-                               *frow++ -= *trow++ * scale;
-                               *frow++ -= *trow++ * scale;
-                               *frow++ -= *trow++ * scale;
-                       }
-               }
-               break;
-       }
-}
-
-HistStripeEngine::HistStripeEngine(HistogramMain *plugin,
-       int total_clients, int total_packages)
- : LoadServer(total_clients, total_packages)
-{
-       this->plugin = plugin;
-}
-void HistStripeEngine::init_packages()
-{
-       int ih = plugin->input->get_h(), iy0 = 0;
-       for( int i=0,n=get_total_packages(); i<n; ) {
-               HistStripePackage *pkg = (HistStripePackage*)get_package(i);
-               int iy1 = (ih * ++i) / n;
-               pkg->y0 = iy0;  pkg->y1 = iy1;
-               iy0 = iy1;
-       }
-}
-
-LoadClient* HistStripeEngine::new_client()
-{
-       return new HistStripeUnit(this, plugin);
-}
-
-LoadPackage* HistStripeEngine::new_package()
-{
-       return new HistStripePackage();
-}
-
-void HistStripeEngine::process_packages(int operation)
-{
-       this->operation = operation;
-       LoadServer::process_packages();
-}
-
-
-
 HistogramPackage::HistogramPackage()
  : LoadPackage()
 {
@@ -877,7 +673,7 @@ HistogramUnit::HistogramUnit(HistogramEngine *server,
        this->plugin = plugin;
        this->server = server;
        for(int i = 0; i < HISTOGRAM_MODES; i++)
-               accum[i] = new int[HISTOGRAM_SLOTS];
+               accum[i] = new int64_t[HISTOGRAM_SLOTS];
 }
 
 HistogramUnit::~HistogramUnit()
@@ -908,7 +704,7 @@ void HistogramUnit::process_package(LoadPackage *package)
                                b_out = preview_b[bclip(b, 0, 0xffff)]; \
 /*                             v = (r * 76 + g * 150 + b * 29) >> 8; */ \
 /* Value takes the maximum of the output RGB values */ \
-                               v = MAX(r_out, g_out); v = MAX(v, b_out); \
+                               int v = MAX(r_out, g_out); v = MAX(v, b_out); \
                                ++accum_v[bclip(v -= hmin, 0, slots1)]; \
                        } \
  \
@@ -923,10 +719,10 @@ void HistogramUnit::process_package(LoadPackage *package)
                VFrame *data = server->data;
                int w = data->get_w();
                //int h = data->get_h();
-               int *accum_r = accum[HISTOGRAM_RED];
-               int *accum_g = accum[HISTOGRAM_GREEN];
-               int *accum_b = accum[HISTOGRAM_BLUE];
-               int *accum_v = accum[HISTOGRAM_VALUE];
+               int64_t *accum_r = accum[HISTOGRAM_RED];
+               int64_t *accum_g = accum[HISTOGRAM_GREEN];
+               int64_t *accum_b = accum[HISTOGRAM_BLUE];
+               int64_t *accum_v = accum[HISTOGRAM_VALUE];
                int32_t r, g, b, y, u, v;
                int r_out, g_out, b_out;
                int *preview_r = plugin->preview_lookup[HISTOGRAM_RED];
@@ -1159,7 +955,7 @@ void HistogramEngine::init_packages()
        for( int i=0,n=get_total_clients(); i<n; ++i ) {
                HistogramUnit *unit = (HistogramUnit*)get_client(i);
                for( int j=0; j<HISTOGRAM_MODES; ++j )
-                       bzero(unit->accum[j], sizeof(int) * HISTOGRAM_SLOTS);
+                       bzero(unit->accum[j], sizeof(int64_t) * HISTOGRAM_SLOTS);
        }
 }
 
index 0051243855f9f8413fcf569d10edde6fb184b26e..b26fafabf38967b717c3035529ef69889a42aabb 100644 (file)
@@ -45,6 +45,7 @@ public:
        void read_data(KeyFrame *keyframe);
        void update_gui();
        void render_gui(void *data);
+       void do_render_gui(HistogramWindow *gui);
        int calculate_use_opengl();
        int handle_opengl();
 
@@ -60,18 +61,18 @@ public:
 // Value is only calculated for preview.
        void calculate_histogram(VFrame *data, int do_value);
 // Calculate the linear, smoothed, lookup curves
-       void tabulate_curve(int **table, int idx, int len, int use_value);
-       void tabulate_curve(int idx, int use_value);
+       void tabulate_curve(int **table, int idx, int use_value, int len);
+       void tabulate_curve(int **table, int use_value, int len=-1);
 
 
        VFrame *input, *output;
        HistogramEngine *engine;
-       HistStripeEngine *stripe_engine;
 
+       int need_reconfigure;
        int *lookup[HISTOGRAM_MODES];
 // No value applied to this
        int *preview_lookup[HISTOGRAM_MODES];
-       int *accum[HISTOGRAM_MODES];
+       int64_t *accum[HISTOGRAM_MODES];
 // Input point being dragged or edited
        int current_point;
 // Current channel being viewed
@@ -81,39 +82,8 @@ public:
        int point_y_offset;
        int w, h;
        int parade;
-       VFrame *fframe;
        int64_t last_position;
-       int last_frames;
-};
-
-enum { ADD_TEMP, ADD_FFRM, ADD_FFRMS, ADD_TEMPS, SUB_TEMPS };
-
-class HistStripePackage : public LoadPackage
-{
-public:
-       HistStripePackage();
-       int y0, y1;
-};
-
-class HistStripeUnit : public LoadClient
-{
-public:
-       HistStripeUnit(HistStripeEngine *server, HistogramMain *plugin);
-       void process_package(LoadPackage *package);
-       HistStripeEngine *server;
-       HistogramMain *plugin;
-};
-
-class HistStripeEngine : public LoadServer
-{
-public:
-       HistStripeEngine(HistogramMain *plugin, int total_clients, int total_packages);
-       void process_packages(int operation);
-       void init_packages();
-       LoadClient *new_client();
-       LoadPackage *new_package();
-       HistogramMain *plugin;
-       int operation;
+       int sum_frames, frames;
 };
 
 
@@ -132,7 +102,7 @@ public:
        void process_package(LoadPackage *package);
        HistogramEngine *server;
        HistogramMain *plugin;
-       int *accum[5];
+       int64_t *accum[HISTOGRAM_MODES];
 };
 
 class HistogramEngine : public LoadServer
index 0608165dbb2e533dcd36416c79e598fd97e0d1da..38d47aabbd8550c44863ebfc90a3189af4430be3 100644 (file)
 #ifndef HISTOGRAM_INC
 #define HISTOGRAM_INC
 
-
-
-
-
 // modes
-#define HISTOGRAM_MODES 4
 #define HISTOGRAM_RED 0
 #define HISTOGRAM_GREEN 1
 #define HISTOGRAM_BLUE 2
 #define HISTOGRAM_VALUE 3
+#define HISTOGRAM_MODES 4
 
 // Number of divisions in histogram.
 // 65536 + min and max range to speed up the tabulation
 
 
 class HistogramMain;
-class HistStripePackage;
-class HistStripeUnit;
-class HistStripeEngine;
-
 class HistogramPackage;
 class HistogramUnit;
 class HistogramEngine;
index fc138ba7fa85202e5c0d6565a9bc04c6970076f2..20bc6ba35ed0b1fabdbf95075fa9b4580d2a1dff 100644 (file)
@@ -31,7 +31,7 @@ HistogramConfig::HistogramConfig()
 {
        plot = 1;
        split = 0;
-
+       sum_frames = 0;
        reset(1);
 }
 
@@ -49,11 +49,9 @@ void HistogramConfig::reset(int do_mode)
        if(do_mode)
        {
                automatic = 0;
-               automatic_v = 0;
-               threshold = 1.0;
+               threshold = 0.97;
        }
 
-       frames = 0;
        log_slider = .5;
 }
 
@@ -84,34 +82,31 @@ void HistogramConfig::boundaries()
        }
        CLAMP(threshold, 0, 1);
        CLAMP(log_slider, 0, 1);
-       CLAMP(frames, 0, 65535);
 }
 
 int HistogramConfig::equivalent(HistogramConfig &that)
 {
 // EQUIV isn't precise enough to detect changes in points
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
+       for(int i = 0; i < HISTOGRAM_MODES; i++) {
 //             if(!EQUIV(low_input[i], that.low_input[i]) ||
 //                     !EQUIV(high_input[i], that.high_input[i]) ||
 //                     !EQUIV(gamma[i], that.gamma[i]) ||
 //                     !EQUIV(low_output[i], that.low_output[i]) ||
 //                     !EQUIV(high_output[i], that.high_output[i])) return 0;
-               if(low_input[i] != that.low_input[i] ||
-                       high_input[i] != that.high_input[i] ||
-                       gamma[i] != that.gamma[i] ||
-                       low_output[i] != that.low_output[i] ||
-                       high_output[i] != that.high_output[i]) return 0;
+               if( low_input[i] != that.low_input[i] ||
+                   high_input[i] != that.high_input[i] ||
+                   gamma[i] != that.gamma[i] ||
+                   low_output[i] != that.low_output[i] ||
+                   high_output[i] != that.high_output[i] ) return 0;
        }
 
-       if(automatic != that.automatic ||
-               automatic_v != that.automatic_v ||
-               threshold != that.threshold) return 0;
+       if( automatic != that.automatic ||
+           threshold != that.threshold ) return 0;
 
-       if(plot != that.plot ||
-               split != that.split ||
-               frames != that.frames ||
-               log_slider != that.log_slider ) return 0;
+       if( plot != that.plot ||
+           split != that.split ||
+           sum_frames != that.sum_frames ||
+           log_slider != that.log_slider ) return 0;
 
        return 1;
 }
@@ -128,25 +123,20 @@ void HistogramConfig::copy_from(HistogramConfig &that)
        }
 
        automatic = that.automatic;
-       automatic_v = that.automatic_v;
        threshold = that.threshold;
        plot = that.plot;
        split = that.split;
-       frames = that.frames;
+       sum_frames = that.sum_frames;
        log_slider = that.log_slider;
 }
 
-void HistogramConfig::interpolate(HistogramConfig &prev,
-       HistogramConfig &next,
-       int64_t prev_frame,
-       int64_t next_frame,
-       int64_t current_frame)
+void HistogramConfig::interpolate(HistogramConfig &prev, HistogramConfig &next,
+               int64_t prev_frame, int64_t next_frame, int64_t current_frame)
 {
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
        double prev_scale = 1.0 - next_scale;
 
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
+       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
                low_input[i] = prev.low_input[i] * prev_scale + next.low_input[i] * next_scale;
                high_input[i] = prev.high_input[i] * prev_scale + next.high_input[i] * next_scale;
                gamma[i] = prev.gamma[i] * prev_scale + next.gamma[i] * next_scale;
@@ -156,21 +146,18 @@ void HistogramConfig::interpolate(HistogramConfig &prev,
 
        threshold = prev.threshold * prev_scale + next.threshold * next_scale;
        automatic = prev.automatic;
-       automatic_v = prev.automatic_v;
        plot = prev.plot;
        split = prev.split;
-       frames = prev.frames;
+       sum_frames = prev.sum_frames;
        log_slider = prev.log_slider;
 }
 
 
 void HistogramConfig::dump()
 {
-       for(int j = 0; j < HISTOGRAM_MODES; j++)
-       {
-               printf("HistogramConfig::dump mode=%d plot=%d split=%d frames=%d\n", j, plot, split, frames);
+       for( int j=0; j<HISTOGRAM_MODES; ++j ) {
+               printf("HistogramConfig::dump mode=%d plot=%d split=%d sum_frames=%d\n",
+                       j, plot, split, sum_frames);
        }
 }
 
-
-
index 38f9982f21080124a86f9b9f7a51a2282f7da99a..2d8554d30a716da0da7e34110e36b1c21a1a5e1c 100644 (file)
@@ -57,11 +57,10 @@ public:
        float high_output[HISTOGRAM_MODES];
 
        int automatic;
-       int automatic_v;
        float threshold;
        int plot;
+       int sum_frames;
        int split;
-       int frames;
        float log_slider;
 };
 
index 3261fbc906fd2c5840df8f9963e655e102103af7..49e9a91a1314a960079c0dc7c376be1c028cfb66 100644 (file)
@@ -185,12 +185,8 @@ void HistogramWindow::create_objects()
        threshold->create_objects();
        y += automatic->get_h() + margin;
 
-       add_subwindow(plot = new HistogramPlot(plugin, x1, y));
-       add_subwindow(select = new HistogramSelect(plugin, this, x2, y));
-       frames = new HistogramFrames(plugin, this, x3, y);
-       frames->create_objects();
-       x = x3 + frames->get_w() + margin;
-       add_subwindow(clear_frames = new HistogramClearFrames(plugin, this, x, y));
+       add_subwindow(plot= new HistogramPlot(plugin, x, y));
+       add_subwindow(sum_frames = new HistogramSumFrames(plugin, x2, y));
        y += plot->get_h() + margin;
 
        x = x1;
@@ -284,19 +280,14 @@ int HistogramWindow::resize_event(int w, int h)
                threshold->get_y() + ydiff);
        plot->reposition_window(plot->get_x(),
                plot->get_y() + ydiff);
+       sum_frames->reposition_window(sum_frames->get_x(),
+               sum_frames->get_y() + ydiff);
 
        split->reposition_window(split->get_x(),
                split->get_y() + ydiff);
        reset->reposition_window(reset->get_x(),
                reset->get_y() + ydiff);
 
-       frames->reposition_window(frames->get_x(),
-               frames->get_y() + ydiff);
-       select->reposition_window(select->get_x(),
-               select->get_y() + ydiff);
-       clear_frames->reposition_window(clear_frames->get_x(),
-               clear_frames->get_y() + ydiff);
-
        update(1, 1, 1, 1);
 
        plugin->w = w;
@@ -342,34 +333,28 @@ int HistogramWindow::keypress_event()
        return result;
 }
 
-void HistogramWindow::update(int do_canvases,
-       int do_carrots,
-       int do_text,
-       int do_toggles)
+void HistogramWindow::update(int do_canvases, int do_carrots, int do_text, int do_toggles)
 {
-       if(do_toggles)
-       {
+       if(do_toggles) {
                automatic->update(plugin->config.automatic);
                mode_v->update(plugin->mode == HISTOGRAM_VALUE ? 1 : 0);
                mode_r->update(plugin->mode == HISTOGRAM_RED ? 1 : 0);
                mode_g->update(plugin->mode == HISTOGRAM_GREEN ? 1 : 0);
                mode_b->update(plugin->mode == HISTOGRAM_BLUE ? 1 : 0);
                plot->update(plugin->config.plot);
+               sum_frames->update(plugin->config.sum_frames);
                split->update(plugin->config.split);
-               frames->update(plugin->config.frames);
                parade_on->update(plugin->parade ? 1 : 0);
                parade_off->update(plugin->parade ? 0 : 1);
                log_slider->update(plugin->config.log_slider);
                output->update();
        }
 
-       if(do_canvases)
-       {
+       if(do_canvases) {
                update_canvas();
        }
 
-       if(do_carrots)
-       {
+       if(do_carrots) {
                low_input_carrot->update();
                high_input_carrot->update();
                gamma_carrot->update();
@@ -377,8 +362,7 @@ void HistogramWindow::update(int do_canvases,
                high_output_carrot->update();
        }
 
-       if(do_text)
-       {
+       if(do_text) {
                low_input->update();
                gamma->update();
                high_input->update();
@@ -386,40 +370,45 @@ void HistogramWindow::update(int do_canvases,
                high_output->update();
                threshold->update();
        }
-
-
 }
 
 
 void HistogramWindow::draw_canvas_mode(int mode, int color, int y, int h)
 {
 // Draw histogram
-       int max = 0, *accum = plugin->accum[mode];
-       if( accum ) {
-               for( int i=0,x=0; x<canvas_w; ++x ) {
-                       int m = 0;
-                       int i1 = (HISTOGRAM_SLOTS * (x+1)) / canvas_w;
-                       while( i < i1 ) m += accum[i++];
-                       if( max < m ) max = m;
+       int64_t max = 0;
+       int64_t *accum = plugin->accum[mode];
+       for( int k0=0,x=0; x<canvas_w; ++x ) {
+               int k1 = (HISTOGRAM_SLOTS * (x+1)) / canvas_w;
+               if( k0 == k1 ) continue;
+               int64_t m = accum[k0];
+               for( int k=k0; ++k<k1; ) {
+                       if( m < accum[k] ) m = accum[k];
                }
+               if( max < m ) max = m;
+               k0 = k1;
        }
-
        if( max > 0 ) {
                double log_slider = plugin->config.log_slider;
                double lin_slider = 1. - log_slider;
-               double lin_scale = (lin_slider * h) / max;
-               double log_scale = (log_slider * h) / log(max);
-               for( int i=0,x=0; x<canvas_w; ++x ) {
-                       int m = 0, i0 = i;
-                       int i1 = (HISTOGRAM_SLOTS * (x+1)) / canvas_w;
-                       while( i < i1 ) m += accum[i++];
-                       double v = m > 0 && i1 > i0 ? (double)m : 0;
-                       m = v > 0 ? v*lin_scale + log(v)*log_scale : 0;
-
+               double lin_max = (lin_slider * h) / max;
+               double log_max = (log_slider * h) / log(max);
+               for( int k0=0,x=0; x<canvas_w; ++x ) {
+                       int k1 = (HISTOGRAM_SLOTS * (x+1)) / canvas_w;
+                       if( k0 == k1 ) continue;
+                       int64_t m = accum[k0];
+                       for( int k=k0; ++k<k1; ) {
+                               if( m < accum[k] ) m = accum[k];
+                       }
+                       int y1 = y+h;
+                       double vv = m > 0 ? (double)m : 0;
+                       m = vv > 0 ? vv*lin_max + log(vv)*log_max : 0;
                        canvas->set_color(BLACK);
-                       canvas->draw_line(x, y, x, y+h - m);
+                       int y0 = y1 - m;
+                       canvas->draw_line(x, y, x, y0);
                        canvas->set_color(color);
-                       canvas->draw_line(x, y+h - m, x, y+h);
+                       canvas->draw_line(x, y0, x, y1);
+                       k0 = k1;
                }
        }
        else {
@@ -463,28 +452,16 @@ void HistogramWindow::update_canvas()
 // Draw 0 and 100% lines.
        canvas->set_color(RED);
        int x = (int)(canvas_w * -HIST_MIN_INPUT / FLOAT_RANGE);
-       canvas->draw_line(x,
-               0,
-               x,
-               canvas_h);
+       canvas->draw_line(x, 0, x, canvas_h);
        x = (int)(canvas_w * (1.0 - HIST_MIN_INPUT) / FLOAT_RANGE);
-       canvas->draw_line(x,
-               0,
-               x,
-               canvas_h);
+       canvas->draw_line(x, 0, x, canvas_h);
        canvas->flash();
 }
 
 
-
-
-HistogramParade::HistogramParade(HistogramMain *plugin,
-       HistogramWindow *gui,
-       int x,
-       int y,
-       int value)
- : BC_Toggle(x,
-       y,
+HistogramParade::HistogramParade(HistogramMain *plugin, HistogramWindow *gui,
+               int x, int y, int value)
+ : BC_Toggle(x, y,
        value ? plugin->get_theme()->get_image_set("histogram_rgb_toggle") :
                plugin->get_theme()->get_image_set("histogram_toggle"),
        0)
@@ -502,30 +479,13 @@ int HistogramParade::handle_event()
 {
        update(1);
        plugin->parade = value;
-       gui->update(1,
-               0,
-               0,
-               1);
+       gui->update(1, 0, 0, 1);
        return 1;
 }
 
-
-
-
-
-
-
-HistogramCanvas::HistogramCanvas(HistogramMain *plugin,
-       HistogramWindow *gui,
-       int x,
-       int y,
-       int w,
-       int h)
- : BC_SubWindow(x,
-       y,
-       w,
-       h,
-       BLACK)
+HistogramCanvas::HistogramCanvas(HistogramMain *plugin, HistogramWindow *gui,
+               int x, int y, int w, int h)
+ : BC_SubWindow(x, y, w, h, BLACK)
 {
        this->plugin = plugin;
        this->gui = gui;
@@ -573,48 +533,6 @@ int HistogramReset::handle_event()
 }
 
 
-HistogramSelect::HistogramSelect(HistogramMain *plugin, HistogramWindow *gui,
-               int x, int y)
- : BC_GenericButton(x, y, xS(100), _("Frames"))
-{
-       this->plugin = plugin;
-       this->gui = gui;
-       set_tooltip(_("Set frames to selection duration"));
-}
-int HistogramSelect::handle_event()
-{
-       MWindow *mwindow = plugin->server->mwindow;
-       if( mwindow ) {
-               EDL *edl = mwindow->edl;
-               double start = edl->local_session->get_selectionstart();
-               int64_t start_pos = edl->get_frame_rate() * start;
-               double end = edl->local_session->get_selectionend();
-               int64_t end_pos = edl->get_frame_rate() * end;
-               int64_t frames = end_pos - start_pos;
-               gui->frames->update(frames);
-               plugin->config.frames = frames;
-               plugin->send_configure_change();
-       }
-       return 1;
-}
-
-HistogramClearFrames::HistogramClearFrames(HistogramMain *plugin, HistogramWindow *gui,
-               int x, int y)
- : BC_Button(x, y, plugin->get_theme()->get_image_set("reset_button"))
-{
-       this->plugin = plugin;
-       this->gui = gui;
-       set_tooltip(_("Clear frames"));
-}
-
-int HistogramClearFrames::handle_event()
-{
-       plugin->config.frames = 0;
-       gui->frames->update(0);
-       plugin->send_configure_change();
-       return 1;
-}
-
 HistogramLogSlider::HistogramLogSlider(HistogramMain *plugin, HistogramWindow *gui,
                int x, int y)
 : BC_FSlider(x, y, 0, xS(100), xS(100), 0., 1., plugin->config.log_slider)
@@ -782,18 +700,8 @@ int HistogramCarrot::cursor_motion_event()
 
 
 
-
-
-
-
-
-HistogramSlider::HistogramSlider(HistogramMain *plugin,
-       HistogramWindow *gui,
-       int x,
-       int y,
-       int w,
-       int h,
-       int is_input)
+HistogramSlider::HistogramSlider(HistogramMain *plugin, HistogramWindow *gui,
+               int x, int y, int w, int h, int is_input)
  : BC_SubWindow(x, y, w, h)
 {
        this->plugin = plugin;
@@ -820,44 +728,30 @@ void HistogramSlider::update()
 
        clear_box(0, 0, w, h);
 
-       switch(mode)
-       {
-               case HISTOGRAM_RED:
-                       g = b = 0x00;
-                       break;
-               case HISTOGRAM_GREEN:
-                       r = b = 0x00;
-                       break;
-               case HISTOGRAM_BLUE:
-                       r = g = 0x00;
-                       break;
+       switch(mode) {
+       case HISTOGRAM_RED:
+               g = b = 0x00;
+               break;
+       case HISTOGRAM_GREEN:
+               r = b = 0x00;
+               break;
+       case HISTOGRAM_BLUE:
+               r = g = 0x00;
+               break;
        }
 
-       for(int i = 0; i < w; i++)
-       {
+       for( int i = 0; i < w; i++ ) {
                int color = (int)(i * 0xff / w);
                set_color(((r * color / 0xff) << 16) |
                        ((g * color / 0xff) << 8) |
                        (b * color / 0xff));
-
                draw_line(i, 0, i, h);
        }
-
-
        flash();
 }
 
 
-
-
-
-
-
-
-
-HistogramAuto::HistogramAuto(HistogramMain *plugin,
-       int x,
-       int y)
+HistogramAuto::HistogramAuto(HistogramMain *plugin, int x, int y)
  : BC_CheckBox(x, y, plugin->config.automatic, _("Automatic"))
 {
        this->plugin = plugin;
@@ -871,11 +765,7 @@ int HistogramAuto::handle_event()
 }
 
 
-
-
-HistogramPlot::HistogramPlot(HistogramMain *plugin,
-       int x,
-       int y)
+HistogramPlot::HistogramPlot(HistogramMain *plugin, int x, int y)
  : BC_CheckBox(x, y, plugin->config.plot, _("Plot histogram"))
 {
        this->plugin = plugin;
@@ -889,11 +779,21 @@ int HistogramPlot::handle_event()
 }
 
 
+HistogramSumFrames::HistogramSumFrames(HistogramMain *plugin, int x, int y)
+ : BC_CheckBox(x, y, plugin->config.sum_frames, _("Sum frames"))
+{
+       this->plugin = plugin;
+}
+
+int HistogramSumFrames::handle_event()
+{
+       plugin->config.sum_frames = get_value();
+       plugin->send_configure_change();
+       return 1;
+}
 
 
-HistogramSplit::HistogramSplit(HistogramMain *plugin,
-       int x,
-       int y)
+HistogramSplit::HistogramSplit(HistogramMain *plugin, int x, int y)
  : BC_CheckBox(x, y, plugin->config.split, _("Split output"))
 {
        this->plugin = plugin;
@@ -908,10 +808,7 @@ int HistogramSplit::handle_event()
 
 
 HistogramMode::HistogramMode(HistogramMain *plugin,
-       int x,
-       int y,
-       int value,
-       char *text)
+               int x, int y, int value, char *text)
  : BC_Radial(x, y, plugin->mode == value, text)
 {
        this->plugin = plugin;
@@ -934,27 +831,6 @@ int HistogramMode::handle_event()
 }
 
 
-HistogramFrames::HistogramFrames(HistogramMain *plugin, HistogramWindow *gui,
-               int x, int y)
- : BC_TumbleTextBox(gui, 0, 0, 65535, x, y, xS(80))
-{
-       this->plugin = plugin;
-       this->gui = gui;
-}
-
-int HistogramFrames::handle_event()
-{
-       plugin->config.frames = atoi(get_text());
-       plugin->send_configure_change();
-       return 1;
-}
-
-void HistogramFrames::update(int frames)
-{
-       BC_TumbleTextBox::update((int64_t)frames);
-}
-
-
 HistogramText::HistogramText(HistogramMain *plugin,
        HistogramWindow *gui, int x, int y, float hist_min, float hist_max)
  : BC_TumbleTextBox(gui, 0.0, hist_min, hist_max, x, y, xS(80))
index fb2b01e73da769598f8d687143c9f4fd951e14df..44cf8d990f2d65bfe9f1e3d9013a7000c8260631 100644 (file)
 class HistogramSlider : public BC_SubWindow
 {
 public:
-       HistogramSlider(HistogramMain *plugin,
-               HistogramWindow *gui,
-               int x,
-               int y,
-               int w,
-               int h,
-               int is_input);
+       HistogramSlider(HistogramMain *plugin, HistogramWindow *gui,
+                       int x, int y, int w, int h, int is_input);
 
        void update();
        int input_to_pixel(float input);
 
        int operation;
-       enum
-       {
+       enum {
                NONE,
                DRAG_INPUT,
                DRAG_MIN_OUTPUT,
@@ -60,11 +54,8 @@ public:
 class HistogramParade : public BC_Toggle
 {
 public:
-       HistogramParade(HistogramMain *plugin,
-               HistogramWindow *gui,
-               int x,
-               int y,
-               int value);
+       HistogramParade(HistogramMain *plugin, HistogramWindow *gui,
+                       int x, int y, int value);
        int handle_event();
        HistogramMain *plugin;
        HistogramWindow *gui;
@@ -108,6 +99,14 @@ public:
        HistogramMain *plugin;
 };
 
+class HistogramSumFrames : public BC_CheckBox
+{
+public:
+       HistogramSumFrames(HistogramMain *plugin, int x, int y);
+       int handle_event();
+       HistogramMain *plugin;
+};
+
 class HistogramSplit : public BC_CheckBox
 {
 public:
@@ -134,24 +133,6 @@ public:
        HistogramMain *plugin;
 };
 
-class HistogramSelect : public BC_GenericButton
-{
-public:
-       HistogramSelect(HistogramMain *plugin, HistogramWindow *gui, int x, int y);
-       int handle_event();
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-};
-
-class HistogramClearFrames : public BC_Button
-{
-public:
-       HistogramClearFrames(HistogramMain *plugin, HistogramWindow *gui, int x, int y);
-       int handle_event();
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-};
-
 class HistogramLogSlider : public BC_FSlider
 {
 public:
@@ -161,17 +142,6 @@ public:
        HistogramWindow *gui;
 };
 
-class HistogramFrames : public BC_TumbleTextBox
-{
-public:
-       HistogramFrames(HistogramMain *plugin, HistogramWindow *gui, int x, int y);
-       int handle_event();
-       void update(int frames);
-
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-};
-
 class HistogramText : public BC_TumbleTextBox
 {
 public:
@@ -226,7 +196,6 @@ public:
        HistogramText *low_input;
        HistogramText *high_input;
        HistogramText *gamma;
-       HistogramFrames *frames;
        HistogramCanvas *canvas;
        HistogramCarrot *low_input_carrot;
        HistogramCarrot *gamma_carrot;
@@ -238,8 +207,6 @@ public:
        BC_Title *canvas_title2;
        BC_Title *threshold_title;
        BC_Bar *bar;
-       HistogramSelect *select;
-       HistogramClearFrames *clear_frames;
        HistogramLogSlider *log_slider;
        BC_Title *log_title1;
        BC_Title *log_title2;
@@ -254,6 +221,7 @@ public:
        int title3_x;
        int title4_x;
        HistogramPlot *plot;
+       HistogramSumFrames *sum_frames;
        HistogramSplit *split;
 };
 
index 35cd2f9789ab7ffc8a155a75651b13ca1802478b..8b755c72a24fde00cd35302aff769b6d61f00e21 100644 (file)
@@ -27,12 +27,11 @@ class HistogramParade;
 class HistogramCarrot;
 class HistogramAuto;
 class HistogramPlot;
+class HistogramSumFrames;
 class HistogramSplit;
 class HistogramMode;
 class HistogramReset;
-class HistogramSelect;
 class HistogramLogSlider;
-class HistogramFrames;
 class HistogramText;
 class HistogramCanvas;
 class HistogramWindow;
index 22787e155529478db6ec317fbd6bbb48989736b3..e26fd9e48154865751b0a14997d9b03c0c6da059 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_bottom.png and b/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_bottom.png differ
index c5b2fbceb37cb49307d591d962b7b1462b930e4b..d257f9cd0580603609f89367197e1ac7de6744e5 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_hi.png and b/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_hi.png differ
index 75efb5f2fcaa9fb3300f721645848f59b89cb683..7316d905d33b5e24983750b798d24934b167f054 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_top.png and b/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_top.png differ
index 45264a67c4dc666e00079a3482adf3abb875a9cf..dd10afd8cb03275dbce93ff3f8ac88eb0e4ee1bc 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_up.png and b/cinelerra-5.1/plugins/theme_cakewalk/data/autorange_up.png differ
index 07e3441f585778e7c06dde6c6ec28dcdae45d598..d69f5bdf90b37ec0211c2840c806284421a1f65e 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_suv/data/autorange_bottom.png and b/cinelerra-5.1/plugins/theme_suv/data/autorange_bottom.png differ
diff --git a/cinelerra-5.1/plugins/theme_suv/data/autorange_hi..png b/cinelerra-5.1/plugins/theme_suv/data/autorange_hi..png
deleted file mode 100644 (file)
index fe59edb..0000000
Binary files a/cinelerra-5.1/plugins/theme_suv/data/autorange_hi..png and /dev/null differ
index fe59edba7fd85e76a2e658b5783e39fd2a25dc79..efd513d3d5386212713a423a1e499b3e0e2b1fb3 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_suv/data/autorange_hi.png and b/cinelerra-5.1/plugins/theme_suv/data/autorange_hi.png differ
index cbb034d9b0efd361e02e79e716d37544b866ea1e..00f119860b6fc67eabbd22e0131d7989e127f4e0 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_suv/data/autorange_top.png and b/cinelerra-5.1/plugins/theme_suv/data/autorange_top.png differ
index 859060121a8b563e3d6158519cb1e19eb8beaa17..1aa90e4c68aa44a4b46b2f905c26c2ef776c3829 100644 (file)
Binary files a/cinelerra-5.1/plugins/theme_suv/data/autorange_up.png and b/cinelerra-5.1/plugins/theme_suv/data/autorange_up.png differ
diff --git a/cinelerra-5.1/plugins/timeblur/Makefile b/cinelerra-5.1/plugins/timeblur/Makefile
new file mode 100644 (file)
index 0000000..0e203e9
--- /dev/null
@@ -0,0 +1,12 @@
+include ../../plugin_defs
+
+OBJS = \
+       $(OBJDIR)/timeblur.o \
+       $(OBJDIR)/timeblurwindow.o
+
+PLUGIN = timeblur
+
+include ../../plugin_config
+
+$(OBJDIR)/timeblur.o: timeblur.C
+$(OBJDIR)/timeblurwindow.o: timeblurwindow.C
diff --git a/cinelerra-5.1/plugins/timeblur/timeblur.C b/cinelerra-5.1/plugins/timeblur/timeblur.C
new file mode 100644 (file)
index 0000000..9306fe8
--- /dev/null
@@ -0,0 +1,313 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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 <math.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "bcprogressbox.h"
+#include "edl.h"
+#include "filexml.h"
+#include "language.h"
+#include "loadbalance.h"
+#include "localsession.h"
+#include "mainsession.h"
+#include "mwindow.h"
+#include "pluginserver.h"
+#include "timeblur.h"
+#include "timeblurwindow.h"
+#include "vframe.h"
+
+REGISTER_PLUGIN(TimeBlurMain)
+
+
+TimeBlurConfig::TimeBlurConfig()
+{
+       frames = 0;
+}
+
+int TimeBlurConfig::equivalent(TimeBlurConfig &that)
+{
+       return frames != that.frames ? 0 : 1;
+}
+
+void TimeBlurConfig::copy_from(TimeBlurConfig &that)
+{
+       frames = that.frames;
+}
+
+void TimeBlurConfig::interpolate(TimeBlurConfig &prev, TimeBlurConfig &next,
+               int64_t prev_frame, int64_t next_frame, int64_t current_frame)
+{
+       frames = prev.frames;
+}
+
+
+TimeBlurMain::TimeBlurMain(PluginServer *server)
+ : PluginVClient(server)
+{
+       stripe_engine = 0;
+       input = 0;
+       fframe = 0;
+       last_frames = 0;
+       last_position = -1;
+}
+
+TimeBlurMain::~TimeBlurMain()
+{
+
+       delete stripe_engine;
+       delete fframe;
+}
+
+const char* TimeBlurMain::plugin_title() { return N_("TimeBlur"); }
+int TimeBlurMain::is_realtime() { return 1; }
+
+
+
+NEW_WINDOW_MACRO(TimeBlurMain, TimeBlurWindow)
+
+LOAD_CONFIGURATION_MACRO(TimeBlurMain, TimeBlurConfig)
+
+
+void TimeBlurMain::save_data(KeyFrame *keyframe)
+{
+       FileXML output;
+
+// cause data to be stored directly in text
+       output.set_shared_output(keyframe->xbuf);
+       output.tag.set_title("TIMEBLUR");
+
+       output.tag.set_property("FRAMES", config.frames);
+       output.append_tag();
+       output.tag.set_title("/TIMEBLUR");
+       output.append_tag();
+       output.append_newline();
+       output.terminate_string();
+}
+
+void TimeBlurMain::read_data(KeyFrame *keyframe)
+{
+       FileXML input;
+
+       input.set_shared_input(keyframe->xbuf);
+
+       int result = 0;
+       while( !(result = input.read_tag()) ) {
+               if( input.tag.title_is("TIMEBLUR") ) {
+                       config.frames = input.tag.get_property("FRAMES", config.frames);
+               }
+       }
+}
+
+int TimeBlurMain::process_buffer(VFrame *frame, int64_t start_position, double frame_rate)
+{
+       load_configuration();
+       this->input = frame;
+       int cpus = input->get_w() * input->get_h() / 0x80000 + 2;
+       int smps = get_project_smp();
+       if( cpus > smps ) cpus = smps;
+       int frames = config.frames;
+       int use_opengl = 0;
+       MWindow *mwindow = server->mwindow;
+       if( frames > 1 && (!mwindow || // dont scan during SELECT_REGION
+             mwindow->session->current_operation != SELECT_REGION ||
+             mwindow->edl->local_session->get_selectionstart() ==
+                 mwindow->edl->local_session->get_selectionend() ) ) {
+               if( !stripe_engine )
+                       stripe_engine = new TimeBlurStripeEngine(this, cpus, cpus);
+               int fw = frame->get_w(), fh =frame->get_h();
+               new_temp(fw, fh, BC_RGB_FLOAT);
+               MWindow *mwindow = server->mwindow;
+               if( (mwindow && mwindow->session->current_operation == SELECT_REGION) ||
+                   ( last_frames == frames && last_position-1 == start_position &&
+                     fframe && fframe->get_w() == fw && fframe->get_h() == fh ) ) {
+                       read_frame(temp, 0, start_position, frame_rate, use_opengl);
+                       stripe_engine->process_packages(ADD_FFRM);
+                       frame->transfer_from(temp);
+               }
+               else if( last_frames != frames || last_position != start_position ||
+                     !fframe || fframe->get_w() != fw || fframe->get_h() != fh ) {
+                       last_frames = frames;
+                       last_position = start_position;
+                       VFrame::get_temp(fframe, fw, fh, BC_RGB_FLOAT);
+                       read_frame(fframe, 0, start_position+1, frame_rate, use_opengl);
+                       BC_ProgressBox *progress = 0;
+                       const char *progress_title = _("TimeBlur: scanning\n");
+                       Timer timer;
+                       for( int i=2; i<frames; ++i ) {
+                                read_frame(temp, 0, start_position+i, frame_rate, use_opengl);
+                               stripe_engine->process_packages(ADD_TEMP);
+                               if( !progress && gui_open() && frames > 2*frame_rate ) {
+                                       progress = new BC_ProgressBox(-1, -1, progress_title, frames);
+                                       progress->start();
+                               }
+                               if( progress && timer.get_difference() > 100 ) {
+                                       timer.update();
+                                       progress->update(i, 1);
+                                       char string[BCTEXTLEN];
+                                       sprintf(string, "%sframe: %d", progress_title, i);
+                                       progress->update_title(string, 1);
+                                       if( progress->is_cancelled() ) break;
+                               }
+                               if( progress && !gui_open() ) {
+                                       progress->stop_progress();
+                                       delete progress;  progress = 0;
+                               }
+                       }
+                       read_frame(temp, 0, start_position, frame_rate, use_opengl);
+                       stripe_engine->process_packages(ADD_FFRMS);
+                       frame->transfer_from(temp);
+                       if( progress ) {
+                               progress->stop_progress();
+                               delete progress;
+                       }
+                       ++last_position;
+               }
+               else {
+                       read_frame(temp, 0, start_position+frames-1, frame_rate, use_opengl);
+                       stripe_engine->process_packages(ADD_TEMPS);
+                       frame->transfer_from(fframe);
+                       read_frame(temp, 0, start_position, frame_rate, use_opengl);
+                       stripe_engine->process_packages(SUB_TEMPS);
+                       ++last_position;
+               }
+       }
+       else
+               read_frame(frame, 0, start_position, frame_rate, use_opengl);
+       return 0;
+}
+
+
+TimeBlurStripePackage::TimeBlurStripePackage()
+ : LoadPackage()
+{
+}
+
+TimeBlurStripeUnit::TimeBlurStripeUnit(TimeBlurStripeEngine *server, TimeBlurMain *plugin)
+ : LoadClient(server)
+{
+       this->plugin = plugin;
+       this->server = server;
+}
+
+void TimeBlurStripeUnit::process_package(LoadPackage *package)
+{
+       TimeBlurStripePackage *pkg = (TimeBlurStripePackage*)package;
+       int frames = plugin->config.frames;
+       float scale = 1. / frames;
+       int iy0 = pkg->y0, iy1 = pkg->y1;
+       int fw = plugin->fframe->get_w();
+       uint8_t **frows = plugin->fframe->get_rows();
+       uint8_t **trows = plugin->temp->get_rows();
+       switch( server->operation ) {
+       case ADD_TEMP:  // add temp to fframe
+               for( int iy=iy0; iy<iy1; ++iy ) {
+                       float *trow = (float *)trows[iy];
+                       float *frow = (float *)frows[iy];
+                       for( int ix=0; ix<fw; ++ix ) {
+                               *frow++ += *trow++;
+                               *frow++ += *trow++;
+                               *frow++ += *trow++;
+                       }
+               }
+               break;
+       case ADD_FFRM:  // add fframe to scaled temp
+               for( int iy=iy0; iy<iy1; ++iy ) {
+                       float *trow = (float *)trows[iy];
+                       float *frow = (float *)frows[iy];
+                       for( int ix=0; ix<fw; ++ix ) {
+                               *trow = *trow * scale + *frow++;  ++trow;
+                               *trow = *trow * scale + *frow++;  ++trow;
+                               *trow = *trow * scale + *frow++;  ++trow;
+                       }
+               }
+               break;
+       case ADD_FFRMS:  // add fframe to temp, scale temp, scale fframe
+               for( int iy=iy0; iy<iy1; ++iy ) {
+                       float *trow = (float *)trows[iy];
+                       float *frow = (float *)frows[iy];
+                       for( int ix=0; ix<fw; ++ix ) {
+                               *trow += *frow;  *trow++ *= scale;  *frow++ *= scale;
+                               *trow += *frow;  *trow++ *= scale;  *frow++ *= scale;
+                               *trow += *frow;  *trow++ *= scale;  *frow++ *= scale;
+                       }
+               }
+               break;
+       case ADD_TEMPS:  // add scaled temp to fframe
+               for( int iy=iy0; iy<iy1; ++iy ) {
+                       float *trow = (float *)trows[iy];
+                       float *frow = (float *)frows[iy];
+                       for( int ix=0; ix<fw; ++ix ) {
+                               *frow++ += *trow++ * scale;
+                               *frow++ += *trow++ * scale;
+                               *frow++ += *trow++ * scale;
+                       }
+               }
+               break;
+       case SUB_TEMPS:  // sub scaled temp from frame
+               for( int iy=iy0; iy<iy1; ++iy ) {
+                       float *trow = (float *)trows[iy];
+                       float *frow = (float *)frows[iy];
+                       for( int ix=0; ix<fw; ++ix ) {
+                               *frow++ -= *trow++ * scale;
+                               *frow++ -= *trow++ * scale;
+                               *frow++ -= *trow++ * scale;
+                       }
+               }
+               break;
+       }
+}
+
+TimeBlurStripeEngine::TimeBlurStripeEngine(TimeBlurMain *plugin,
+       int total_clients, int total_packages)
+ : LoadServer(total_clients, total_packages)
+{
+       this->plugin = plugin;
+}
+void TimeBlurStripeEngine::init_packages()
+{
+       int ih = plugin->input->get_h(), iy0 = 0;
+       for( int i=0,n=get_total_packages(); i<n; ) {
+               TimeBlurStripePackage *pkg = (TimeBlurStripePackage*)get_package(i);
+               int iy1 = (ih * ++i) / n;
+               pkg->y0 = iy0;  pkg->y1 = iy1;
+               iy0 = iy1;
+       }
+}
+
+LoadClient* TimeBlurStripeEngine::new_client()
+{
+       return new TimeBlurStripeUnit(this, plugin);
+}
+
+LoadPackage* TimeBlurStripeEngine::new_package()
+{
+       return new TimeBlurStripePackage();
+}
+
+void TimeBlurStripeEngine::process_packages(int operation)
+{
+       this->operation = operation;
+       LoadServer::process_packages();
+}
+
diff --git a/cinelerra-5.1/plugins/timeblur/timeblur.h b/cinelerra-5.1/plugins/timeblur/timeblur.h
new file mode 100644 (file)
index 0000000..f2204a1
--- /dev/null
@@ -0,0 +1,102 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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 TIMEBLUR_H
+#define TIMEBLUR_H
+
+#include "loadbalance.h"
+#include "pluginvclient.h"
+#include "linklist.h"
+#include <stdint.h>
+
+class TimeBlurConfig;
+class TimeBlurMain;
+class TimeBlurStripePackage;
+class TimeBlurStripeUnit;
+class TimeBlurStripeEngine;
+
+class TimeBlurConfig
+{
+public:
+       TimeBlurConfig();
+       int equivalent(TimeBlurConfig &that);
+       void copy_from(TimeBlurConfig &that);
+       void interpolate(TimeBlurConfig &prev, TimeBlurConfig &next,
+               int64_t prev_frame, int64_t next_frame, int64_t current_frame);
+
+       int frames;
+};
+
+class TimeBlurMain : public PluginVClient
+{
+public:
+       TimeBlurMain(PluginServer *server);
+       ~TimeBlurMain();
+
+       int process_buffer(VFrame *frame,
+               int64_t start_position,
+               double frame_rate);
+       int is_realtime();
+       void save_data(KeyFrame *keyframe);
+       void read_data(KeyFrame *keyframe);
+
+       PLUGIN_CLASS_MEMBERS(TimeBlurConfig)
+
+       VFrame *input;
+       TimeBlurStripeEngine *stripe_engine;
+
+       int w, h;
+       VFrame *fframe;
+       int64_t last_position;
+       int last_frames;
+};
+
+enum { ADD_TEMP, ADD_FFRM, ADD_FFRMS, ADD_TEMPS, SUB_TEMPS };
+
+class TimeBlurStripePackage : public LoadPackage
+{
+public:
+       TimeBlurStripePackage();
+       int y0, y1;
+};
+
+class TimeBlurStripeUnit : public LoadClient
+{
+public:
+       TimeBlurStripeUnit(TimeBlurStripeEngine *server, TimeBlurMain *plugin);
+       void process_package(LoadPackage *package);
+       TimeBlurStripeEngine *server;
+       TimeBlurMain *plugin;
+};
+
+class TimeBlurStripeEngine : public LoadServer
+{
+public:
+       TimeBlurStripeEngine(TimeBlurMain *plugin, int total_clients, int total_packages);
+       void process_packages(int operation);
+       void init_packages();
+       LoadClient *new_client();
+       LoadPackage *new_package();
+       TimeBlurMain *plugin;
+       int operation;
+};
+
+#endif
diff --git a/cinelerra-5.1/plugins/timeblur/timeblurwindow.C b/cinelerra-5.1/plugins/timeblur/timeblurwindow.C
new file mode 100644 (file)
index 0000000..3f447b0
--- /dev/null
@@ -0,0 +1,123 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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 "bcdisplayinfo.h"
+#include "bcsignals.h"
+#include "cursors.h"
+#include "edl.h"
+#include "timeblur.h"
+#include "timeblurwindow.h"
+#include "language.h"
+#include "localsession.h"
+#include "mwindow.h"
+#include "pluginserver.h"
+#include "theme.h"
+
+#include <unistd.h>
+
+
+TimeBlurWindow::TimeBlurWindow(TimeBlurMain *plugin)
+ : PluginClientWindow(plugin, xS(250), yS(50), xS(250), yS(50), 0)
+{
+       this->plugin = plugin;
+}
+
+TimeBlurWindow::~TimeBlurWindow()
+{
+}
+
+void TimeBlurWindow::create_objects()
+{
+       int margin = plugin->get_theme()->widget_border;
+       int x = margin, y = margin;
+       int x1 = x;
+       add_subwindow(select = new TimeBlurSelect(plugin, this, x1, y));
+       x1 += select->get_w() + margin;
+       frames = new TimeBlurFrames(plugin, this, x1, y);
+       frames->create_objects();
+       x1 += frames->get_w() + 3*margin;
+       add_subwindow(clear_frames = new TimeBlurClearFrames(plugin, this, x1, y));
+       show_window();
+}
+
+
+TimeBlurSelect::TimeBlurSelect(TimeBlurMain *plugin, TimeBlurWindow *gui,
+               int x, int y)
+ : BC_GenericButton(x, y, xS(100), _("Frames"))
+{
+       this->plugin = plugin;
+       this->gui = gui;
+       set_tooltip(_("Set frames to selection duration"));
+}
+int TimeBlurSelect::handle_event()
+{
+       MWindow *mwindow = plugin->server->mwindow;
+       if( mwindow ) {
+               EDL *edl = mwindow->edl;
+               double start = edl->local_session->get_selectionstart();
+               int64_t start_pos = edl->get_frame_rate() * start;
+               double end = edl->local_session->get_selectionend();
+               int64_t end_pos = edl->get_frame_rate() * end;
+               int64_t frames = end_pos - start_pos;
+               gui->frames->update(frames);
+               plugin->config.frames = frames;
+               plugin->send_configure_change();
+       }
+       return 1;
+}
+
+TimeBlurClearFrames::TimeBlurClearFrames(TimeBlurMain *plugin, TimeBlurWindow *gui,
+               int x, int y)
+ : BC_Button(x, y, plugin->get_theme()->get_image_set("reset_button"))
+{
+       this->plugin = plugin;
+       this->gui = gui;
+       set_tooltip(_("Clear frames"));
+}
+
+int TimeBlurClearFrames::handle_event()
+{
+       plugin->config.frames = 0;
+       gui->frames->update(0);
+       plugin->send_configure_change();
+       return 1;
+}
+
+TimeBlurFrames::TimeBlurFrames(TimeBlurMain *plugin, TimeBlurWindow *gui,
+               int x, int y)
+ : BC_TumbleTextBox(gui, 0, 0, 65535, x, y, xS(80))
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+
+int TimeBlurFrames::handle_event()
+{
+       plugin->config.frames = atoi(get_text());
+       plugin->send_configure_change();
+       return 1;
+}
+
+void TimeBlurFrames::update(int frames)
+{
+       BC_TumbleTextBox::update((int64_t)frames);
+}
+
diff --git a/cinelerra-5.1/plugins/timeblur/timeblurwindow.h b/cinelerra-5.1/plugins/timeblur/timeblurwindow.h
new file mode 100644 (file)
index 0000000..5e88fcd
--- /dev/null
@@ -0,0 +1,74 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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 TIMEBLURWINDOW_H
+#define TIMEBLURWINDOW_H
+
+#include "timeblur.h"
+
+class TimeBlurSelect;
+class TimeBlurClearFrames;
+class TimeBlurFrames;
+class TimeBlurWindow;
+
+class TimeBlurSelect : public BC_GenericButton
+{
+public:
+       TimeBlurSelect(TimeBlurMain *plugin, TimeBlurWindow *gui, int x, int y);
+       int handle_event();
+       TimeBlurMain *plugin;
+       TimeBlurWindow *gui;
+};
+
+class TimeBlurClearFrames : public BC_Button
+{
+public:
+       TimeBlurClearFrames(TimeBlurMain *plugin, TimeBlurWindow *gui, int x, int y);
+       int handle_event();
+       TimeBlurMain *plugin;
+       TimeBlurWindow *gui;
+};
+
+class TimeBlurFrames : public BC_TumbleTextBox
+{
+public:
+       TimeBlurFrames(TimeBlurMain *plugin, TimeBlurWindow *gui, int x, int y);
+       int handle_event();
+       void update(int frames);
+
+       TimeBlurMain *plugin;
+       TimeBlurWindow *gui;
+};
+
+class TimeBlurWindow : public PluginClientWindow
+{
+public:
+       TimeBlurWindow(TimeBlurMain *plugin);
+       ~TimeBlurWindow();
+
+       void create_objects();
+       TimeBlurMain *plugin;
+       TimeBlurSelect *select;
+       TimeBlurFrames *frames;
+       TimeBlurClearFrames *clear_frames;
+};
+
+#endif