X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fcrikey%2Fcrikey.C;h=8686613c3d38220188017b6af2b9954aad36a113;hb=5616fa8528aa382cef440a88ffd0d87ed3bbfda2;hp=2f22fed98adf620db3442ef8221a76c8e42b2bb9;hpb=7fd85fb66168f6b518c5f2d73e04036e87faa0e1;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/plugins/crikey/crikey.C b/cinelerra-5.1/plugins/crikey/crikey.C index 2f22fed9..8686613c 100644 --- a/cinelerra-5.1/plugins/crikey/crikey.C +++ b/cinelerra-5.1/plugins/crikey/crikey.C @@ -27,11 +27,15 @@ #include "bccmodels.h" #include "bccolors.h" #include "clip.h" +#include "edl.h" #include "edlsession.h" #include "filexml.h" #include "crikey.h" #include "crikeywindow.h" +#include "keyframe.h" +#include "keyframes.h" #include "language.h" +#include "transportque.inc" #include "vframe.h" // chroma interpolated key, crikey @@ -63,8 +67,6 @@ CriKeyConfig::CriKeyConfig() { threshold = 0.5f; draw_mode = DRAW_ALPHA; - drag = 0; - selected = 0; } CriKeyConfig::~CriKeyConfig() { @@ -74,7 +76,6 @@ int CriKeyConfig::equivalent(CriKeyConfig &that) { if( !EQUIV(this->threshold, that.threshold) ) return 0; if( this->draw_mode != that.draw_mode ) return 0; - if( this->drag != that.drag ) return 0; if( this->points.size() != that.points.size() ) return 0; for( int i=0, n=points.size(); ipoints[i], *bp = that.points[i]; @@ -91,8 +92,6 @@ void CriKeyConfig::copy_from(CriKeyConfig &that) { this->threshold = that.threshold; this->draw_mode = that.draw_mode; - this->drag = that.drag; - this->selected = that.selected; points.remove_all_objects(); for( int i=0,n=that.points.size(); ithreshold = prev.threshold; this->draw_mode = prev.draw_mode; - this->drag = prev.drag; - this->selected = prev.selected; double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); @@ -212,7 +209,7 @@ void FillRegion::run() if( edge_pixel(lofs) ) break; } int rofs = ofs; - for( int i=rt; ++i< w; rt=i,msk[rofs]=0 ) { + for( int i=rt; ++i< w; ) { if( !msk[++rofs] ) break; msk[rofs] = 0; rt = i; if( edge_pixel(rofs) ) break; @@ -230,6 +227,9 @@ CriKey::CriKey(PluginServer *server) engine = 0; msk = 0; edg = 0; + + drag = 0; + selected = 0; } CriKey::~CriKey() @@ -261,15 +261,30 @@ int CriKey::is_realtime() { return 1; } NEW_WINDOW_MACRO(CriKey, CriKeyWindow); LOAD_CONFIGURATION_MACRO(CriKey, CriKeyConfig) +void CriKey::render_gui(void *data) +{ + CriKey *crikey = (CriKey *)data; + crikey->drag = drag; + crikey->selected = selected; +} + +int CriKey::is_dragging() +{ + drag = 0; + selected = 0; + send_render_gui(this); + return drag; +} + int CriKey::new_point() { - EDLSession *session = get_edlsession(); + EDLSession *session = get_edl()->session; float x = !session ? 0.f : session->output_w / 2.f; float y = !session ? 0.f : session->output_h / 2.f; return config.add_point(-1, 0, x, y, 0.5f); } -void CriKey::save_data(KeyFrame *keyframe) +void CriKeyConfig::save_data(KeyFrame *keyframe) { FileXML output; @@ -277,17 +292,15 @@ void CriKey::save_data(KeyFrame *keyframe) output.set_shared_output(keyframe->xbuf); output.tag.set_title("CRIKEY"); - output.tag.set_property("THRESHOLD", config.threshold); - output.tag.set_property("DRAW_MODE", config.draw_mode); - output.tag.set_property("DRAG", config.drag); - output.tag.set_property("SELECTED", config.selected); + output.tag.set_property("THRESHOLD", threshold); + output.tag.set_property("DRAW_MODE", draw_mode); output.append_tag(); output.append_newline(); output.tag.set_title("/CRIKEY"); output.append_tag(); output.append_newline(); - for( int i=0, n = config.points.size(); itag); output.tag.set_title(point+1); @@ -302,21 +315,23 @@ void CriKey::save_data(KeyFrame *keyframe) } output.terminate_string(); } +void CriKey::save_data(KeyFrame *keyframe) +{ + config.save_data(keyframe); +} -void CriKey::read_data(KeyFrame *keyframe) +void CriKeyConfig::read_data(KeyFrame *keyframe) { FileXML input; input.set_shared_input(keyframe->xbuf); - config.points.remove_all_objects(); + points.remove_all_objects(); int result = 0; while( !(result=input.read_tag()) ) { if( input.tag.title_is("CRIKEY") ) { - config.threshold = input.tag.get_property("THRESHOLD", config.threshold); - config.draw_mode = input.tag.get_property("DRAW_MODE", config.draw_mode); - config.drag = input.tag.get_property("DRAG", config.drag); - config.selected = input.tag.get_property("SELECTED", 0); - config.limits(); + threshold = input.tag.get_property("THRESHOLD", threshold); + draw_mode = input.tag.get_property("DRAW_MODE", draw_mode); + limits(); } else if( !strncmp(input.tag.get_title(),"POINT_",6) ) { int tag = atoi(input.tag.get_title() + 6); @@ -324,21 +339,79 @@ void CriKey::read_data(KeyFrame *keyframe) float x = input.tag.get_property("X", 0.f); float y = input.tag.get_property("Y", 0.f); float t = input.tag.get_property("T", .5f); - config.add_point(tag, e, x, y, t); + add_point(tag, e, x, y, t); } } +} +void CriKey::read_data(KeyFrame *keyframe) +{ + config.read_data(keyframe); + if( !config.points.size() ) + new_point(); +} + +void CriKey::span_keyframes(KeyFrame *src, int64_t start, int64_t end) +{ + CriKeyConfig src_config; + src_config.read_data(src); + KeyFrames *keyframes = (KeyFrames *)src->autos; + KeyFrame *prev = keyframes->get_prev_keyframe(start, PLAY_FORWARD); + CriKeyConfig prev_config; + prev_config.read_data(prev); +// Always update the first one + update_parameter(prev_config, src_config, prev); + KeyFrame *curr = (KeyFrame*)prev->next; + while( curr && curr->position < end ) { + update_parameter(prev_config, src_config, curr); + curr = (KeyFrame*)curr->next; + } +} - if( !config.points.size() ) new_point(); +void CriKeyPoint::update_parameter(CriKeyPoint *prev, CriKeyPoint *src) +{ + if( prev->e != src->e ) e = src->e; + if( prev->x != src->x ) x = src->x; + if( prev->y != src->y ) y = src->y; + if( prev->t != src->t ) t = src->t; +} + +void CriKey::update_parameter(CriKeyConfig &prev_config, CriKeyConfig &src_config, + KeyFrame *keyframe) +{ + CriKeyConfig dst_config; + dst_config.read_data(keyframe); + if( !EQUIV(prev_config.threshold, src_config.threshold) ) + dst_config.threshold = src_config.threshold; + if( prev_config.draw_mode != src_config.draw_mode ) + dst_config.draw_mode = src_config.draw_mode; + int src_points = src_config.points.size(); + int dst_points = dst_config.points.size(); + int prev_points = prev_config.points.size(); + int npoints = bmin(prev_points, bmin(src_points, dst_points)); + for( int i=0; itag, k = prev_points; + while( --k >= 0 && tag != prev_config.points[k]->tag ); + if( k < 0 ) continue; + CriKeyPoint *prev_point = prev_config.points[k]; + k = dst_points; + while( --k >= 0 && tag != dst_config.points[k]->tag ); + if( k < 0 ) continue; + CriKeyPoint *dst_point = dst_config.points[k]; + dst_point->update_parameter(prev_point, src_point); + } + dst_config.save_data(keyframe); } void CriKey::update_gui() { if( !thread ) return; - if( !load_configuration() ) return; thread->window->lock_window("CriKey::update_gui"); CriKeyWindow *window = (CriKeyWindow*)thread->window; - window->update_gui(); - window->flush(); + if( load_configuration() ) { + window->update_gui(); + window->flush(); + } thread->window->unlock_window(); } @@ -569,14 +642,6 @@ void CriKey::draw_point(VFrame *src, CriKeyPoint *pt) } -static void get_vframe(VFrame *&vfrm, int w, int h, int color_model) -{ - if( vfrm && ( vfrm->get_w() != w || vfrm->get_h() != h ) ) { - delete vfrm; vfrm = 0; - } - if( !vfrm ) vfrm = new VFrame(w, h, color_model, 0); -} - static void fill_edge(VFrame *vfrm, int w, int h) { int w1 = w-1, h1 = h-1; @@ -598,14 +663,14 @@ int CriKey::process_buffer(VFrame *frame, int64_t start_position, double frame_r if( comp > 3 ) comp = 3; read_frame(src, 0, start_position, frame_rate, 0); - get_vframe(edg, w, h, BC_A_FLOAT); + VFrame::get_temp(edg, w, h, BC_A_FLOAT); if( !engine ) engine = new CriKeyEngine(this, PluginClient::get_project_smp() + 1, PluginClient::get_project_smp() + 1); - get_vframe(msk, w, h, BC_A8); + VFrame::get_temp(msk, w, h, BC_A8); memset(msk->get_data(), 0xff, msk->get_data_size()); for( int i=0, n=config.points.size(); ie ) continue; if( set_target(engine->color, pt->x, pt->y) ) continue; engine->threshold = pt->t; - edg->clear_frame(); + edg->black_frame(); engine->process_packages(); fill_edge(edg, w, h); FillRegion fill_region(edg, msk); @@ -628,10 +693,10 @@ int CriKey::process_buffer(VFrame *frame, int64_t start_position, double frame_r case DRAW_MASK: draw_mask(msk); break; } - if( config.drag ) { + if( is_dragging() ) { for( int i=0, n=config.points.size(); iset_pixel_color(config.selected == i ? GREEN : WHITE); + src->set_pixel_color(selected == i ? GREEN : WHITE); draw_point(src, pt); } } @@ -672,14 +737,14 @@ LoadClient* CriKeyEngine::new_client() float a00 = 0, a01 = 0, a10 = 0, a11 = 0; \ for( int c=0; c= threshold ) continue; \ *edgp += (mx - mn); \ } \