From: Good Guy Date: Wed, 25 Dec 2019 02:48:44 +0000 (-0700) Subject: add stacked edl editing, add sketcher/vframe line anti-aliasing X-Git-Tag: 2019-12~6 X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=commitdiff_plain;h=5d8a7826b0f80f00622e46baf75453995a76e343 add stacked edl editing, add sketcher/vframe line anti-aliasing fix amodule arender infinite loop for nested silence, es.po tweaks colorpicker gadget grab fixes for foreground plugin, eye dropper fixes fix mixer close window, tracer layout tweaks, add 9 ffmpeg formats olaf --- diff --git a/cinelerra-5.1/cinelerra/amodule.C b/cinelerra-5.1/cinelerra/amodule.C index 9e2c59b6..fb102c5c 100644 --- a/cinelerra-5.1/cinelerra/amodule.C +++ b/cinelerra-5.1/cinelerra/amodule.C @@ -295,6 +295,8 @@ int AModule::import_samples(AEdit *edit, nested_renderengine->command->command = command; result = 0; } + if( edit_sample_rate <= 0 ) + result = 1; if( !result ) { // speed_buffer is (have_speed ? speed_temp : buffer) diff --git a/cinelerra-5.1/cinelerra/assetpopup.C b/cinelerra-5.1/cinelerra/assetpopup.C index 156d86ab..d8142f02 100644 --- a/cinelerra-5.1/cinelerra/assetpopup.C +++ b/cinelerra-5.1/cinelerra/assetpopup.C @@ -76,13 +76,15 @@ void AssetPopup::create_objects() BC_SubMenu *submenu; add_item(info = new AssetPopupInfo(mwindow, this)); add_item(format = new AWindowListFormat(mwindow, gui)); - add_item(new AssetPopupSort(mwindow, this)); + add_item(open_edl = new AssetPopupOpenEDL(mwindow, this)); + add_item(to_clip = new AssetPopupToClip(mwindow, this)); + add_item(sort = new AssetPopupSort(mwindow, this)); add_item(index = new AssetPopupBuildIndex(mwindow, this)); add_item(view = new AssetPopupView(mwindow, this)); add_item(view_window = new AssetPopupViewWindow(mwindow, this)); add_item(open_mixer = new AssetPopupOpenMixer(mwindow, this)); add_item(insert_mixer = new AssetPopupInsertMixer(mwindow, this)); - add_item(new AssetPopupPaste(mwindow, this)); + add_item(paste = new AssetPopupPaste(mwindow, this)); add_item(menu_item = new BC_MenuItem(_("Match..."))); menu_item->add_submenu(submenu = new BC_SubMenu()); submenu->add_submenuitem(new AssetMatchSize(mwindow, this)); @@ -179,6 +181,51 @@ int AssetPopupInfo::handle_event() } +AssetPopupOpenEDL::AssetPopupOpenEDL(MWindow *mwindow, AssetPopup *popup) + : BC_MenuItem(_("Open EDL")) +{ + this->mwindow = mwindow; + this->popup = popup; +} +AssetPopupOpenEDL::~AssetPopupOpenEDL() +{ +} + +int AssetPopupOpenEDL::handle_event() +{ + int assets_total = mwindow->session->drag_assets->size(); + if( assets_total ) { + popup->unlock_window(); + Indexable *idxbl = mwindow->session->drag_assets->get(0); + EDL *edl = idxbl && !idxbl->is_asset ? (EDL *)idxbl : 0; + if( edl ) + mwindow->stack_push(edl); + else + eprintf(_("media is not EDL:\n%s"), idxbl->path); + popup->lock_window("AssetPopupOpenEDL::handle_event"); + } + return 1; +} + + +AssetPopupToClip::AssetPopupToClip(MWindow *mwindow, AssetPopup *popup) + : BC_MenuItem(_("EDL to clip")) +{ + this->mwindow = mwindow; + this->popup = popup; +} + +AssetPopupToClip::~AssetPopupToClip() +{ +} + +int AssetPopupToClip::handle_event() +{ + mwindow->media_to_clip(); + return 1; +} + + AssetPopupBuildIndex::AssetPopupBuildIndex(MWindow *mwindow, AssetPopup *popup) : BC_MenuItem(_("Rebuild index")) { diff --git a/cinelerra-5.1/cinelerra/assetpopup.h b/cinelerra-5.1/cinelerra/assetpopup.h index eea5a8ea..22624e47 100644 --- a/cinelerra-5.1/cinelerra/assetpopup.h +++ b/cinelerra-5.1/cinelerra/assetpopup.h @@ -51,12 +51,16 @@ public: AssetPopupInfo *info; + AWindowListFormat *format; + AssetPopupOpenEDL *open_edl; + AssetPopupToClip *to_clip; + AssetPopupSort *sort; AssetPopupBuildIndex *index; AssetPopupView *view; AssetPopupViewWindow *view_window; AssetPopupOpenMixer *open_mixer; AssetPopupInsertMixer *insert_mixer; - AWindowListFormat *format; + AssetPopupPaste *paste; }; class AssetPopupInfo : public BC_MenuItem @@ -72,6 +76,30 @@ public: AssetPopup *popup; }; +class AssetPopupOpenEDL : public BC_MenuItem +{ +public: + AssetPopupOpenEDL(MWindow *mwindow, AssetPopup *popup); + ~AssetPopupOpenEDL(); + + int handle_event(); + + MWindow *mwindow; + AssetPopup *popup; +}; + +class AssetPopupToClip : public BC_MenuItem +{ +public: + AssetPopupToClip(MWindow *mwindow, AssetPopup *popup); + ~AssetPopupToClip(); + + int handle_event(); + + MWindow *mwindow; + AssetPopup *popup; +}; + class AssetPopupSort : public BC_MenuItem { public: diff --git a/cinelerra-5.1/cinelerra/assetpopup.inc b/cinelerra-5.1/cinelerra/assetpopup.inc index 4cdb174c..096c729b 100644 --- a/cinelerra-5.1/cinelerra/assetpopup.inc +++ b/cinelerra-5.1/cinelerra/assetpopup.inc @@ -34,6 +34,8 @@ class AssetPopup; class AssetPopupInfo; +class AssetPopupOpenEDL; +class AssetPopupToClip; class AssetPopupSort; class AssetPopupBuildIndex; class AssetPopupView; diff --git a/cinelerra-5.1/cinelerra/cachebase.C b/cinelerra-5.1/cinelerra/cachebase.C index 40b1e1bf..69012960 100644 --- a/cinelerra-5.1/cinelerra/cachebase.C +++ b/cinelerra-5.1/cinelerra/cachebase.C @@ -88,20 +88,26 @@ void CacheBase::remove_all() } -void CacheBase::remove_asset(Asset *asset) +void CacheBase::remove_item(int source_id, char *path) { CacheItemBase *current, *next; lock->lock("CacheBase::remove_id"); for( current=first; current; current=next ) { next = current->next; - if( (current->path && !strcmp(current->path, asset->path)) || - current->source_id == asset->id) + if( current->source_id == source_id || + (path && current->path && !strcmp(current->path, path)) ) del_item(current); } lock->unlock(); -//printf("CacheBase::remove_asset: removed %d entries for %s\n", total, asset->path); } - +void CacheBase::remove_item(Indexable *idxbl) +{ + remove_item(idxbl->id, idxbl->path); +} +void CacheBase::remove_asset(Asset *asset) +{ + remove_item(asset); +} void CacheBase::del_item(CacheItemBase *item) { diff --git a/cinelerra-5.1/cinelerra/cachebase.h b/cinelerra-5.1/cinelerra/cachebase.h index a548891a..e8791642 100644 --- a/cinelerra-5.1/cinelerra/cachebase.h +++ b/cinelerra-5.1/cinelerra/cachebase.h @@ -73,7 +73,9 @@ public: // Delete item. void del_item(CacheItemBase *item); int delete_item(CacheItemBase *item); -// Remove all items with the asset id. +// Remove all items with the same source_id or matching path if set + void remove_item(int source_id, char *path); + void remove_item(Indexable *idxbl); void remove_asset(Asset *asset); // Called when done with the item returned by get_. // Ignore if item was 0. diff --git a/cinelerra-5.1/cinelerra/clippopup.C b/cinelerra-5.1/cinelerra/clippopup.C index c9151e67..c38efd99 100644 --- a/cinelerra-5.1/cinelerra/clippopup.C +++ b/cinelerra-5.1/cinelerra/clippopup.C @@ -65,13 +65,13 @@ void ClipPopup::create_objects() BC_SubMenu *submenu; add_item(info = new ClipPopupInfo(mwindow, this)); add_item(format = new AWindowListFormat(mwindow, gui)); - add_item(new ClipPopupSort(mwindow, this)); + add_item(sort = new ClipPopupSort(mwindow, this)); + add_item(open_edl = new ClipPopupOpenEDL(mwindow, this)); + add_item(to_media = new ClipPopupToMedia(mwindow, this)); add_item(view = new ClipPopupView(mwindow, this)); add_item(view_window = new ClipPopupViewWindow(mwindow, this)); - add_item(new ClipPopupCopy(mwindow, this)); - add_item(new ClipPopupNest(mwindow, this)); - add_item(new ClipPopupUnNest(mwindow, this)); - add_item(new ClipPopupPaste(mwindow, this)); + add_item(copy = new ClipPopupCopy(mwindow, this)); + add_item(paste = new ClipPopupPaste(mwindow, this)); add_item(menu_item = new BC_MenuItem(_("Match..."))); menu_item->add_submenu(submenu = new BC_SubMenu()); submenu->add_submenuitem(new ClipMatchSize(mwindow, this)); @@ -417,107 +417,46 @@ void ClipListMenu::update() } -ClipPopupNest::ClipPopupNest(MWindow *mwindow, ClipPopup *popup) - : BC_MenuItem(_("Nest")) +ClipPopupToMedia::ClipPopupToMedia(MWindow *mwindow, ClipPopup *popup) + : BC_MenuItem(_("Nest to Media")) { this->mwindow = mwindow; this->popup = popup; } -ClipPopupNest::~ClipPopupNest() +ClipPopupToMedia::~ClipPopupToMedia() { } -int ClipPopupNest::handle_event() +int ClipPopupToMedia::handle_event() { - MWindowGUI *gui = mwindow->gui; - gui->lock_window("ClipPopupNest::handle_event 1"); - if( mwindow->edl->session->proxy_scale != 1 ) { + if( mwindow->edl->session->proxy_scale == 1 ) + mwindow->clip_to_media(); + else eprintf("Nesting not allowed when proxy scale != 1"); - return 1; - } - int clips_total = mwindow->session->drag_clips->total; - for( int i=0; iedl; - time_t dt; time(&dt); - struct tm dtm; localtime_r(&dt, &dtm); - char path[BCSTRLEN]; - sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"), - dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, - dtm.tm_hour, dtm.tm_min, dtm.tm_sec); - EDL *clip = mwindow->session->drag_clips->values[i]; - EDL *nested = edl->new_nested(clip, path); - EDL *new_clip = edl->create_nested_clip(nested); - new_clip->folder_no = AW_CLIP_FOLDER; - sprintf(new_clip->local_session->clip_icon, - "clip_%02d%02d%02d-%02d%02d%02d.png", - dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, - dtm.tm_hour, dtm.tm_min, dtm.tm_sec); - snprintf(new_clip->local_session->clip_title, - sizeof(new_clip->local_session->clip_title), - _("Nested: %s"), clip->local_session->clip_title); - strcpy(new_clip->local_session->clip_notes, - clip->local_session->clip_notes); - int idx = edl->clips.number_of(clip); - if( idx >= 0 ) { - edl->clips[idx] = new_clip; - clip->remove_user(); - } - else - edl->clips.append(new_clip); - mwindow->mainindexes->add_next_asset(0, nested); - } - mwindow->mainindexes->start_build(); - popup->gui->async_update_assets(); - gui->unlock_window(); return 1; } -ClipPopupUnNest::ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup) - : BC_MenuItem(_("UnNest")) +ClipPopupOpenEDL::ClipPopupOpenEDL(MWindow *mwindow, ClipPopup *popup) + : BC_MenuItem(_("Open EDL")) { this->mwindow = mwindow; this->popup = popup; } -ClipPopupUnNest::~ClipPopupUnNest() + +ClipPopupOpenEDL::~ClipPopupOpenEDL() { } -int ClipPopupUnNest::handle_event() +int ClipPopupOpenEDL::handle_event() { - EDL *nested_edl = 0; - MWindowGUI *gui = mwindow->gui; - gui->lock_window("ClipPopupUnNest::handle_event 1"); int clips_total = mwindow->session->drag_clips->total; - for( int i=0; isession->drag_clips->values[i]; - Track *track = clip->tracks->first; - Edit *edit = track ? track->edits->first : 0; - nested_edl = edit && !edit->next && !edit->asset ? edit->nested_edl : 0; - while( nested_edl && (track=track->next)!=0 ) { - Edit *edit = track->edits->first; - if( !edit || edit->next || - ( edit->nested_edl != nested_edl && - strcmp(edit->nested_edl->path, nested_edl->path) ) ) - nested_edl = 0; - } - if( nested_edl ) { - EDL *edl = mwindow->edl; - EDL *new_clip = new EDL(edl); - new_clip->create_objects(); - new_clip->copy_all(nested_edl); - new_clip->folder_no = AW_CLIP_FOLDER; - int idx = edl->clips.number_of(clip); - if( idx >= 0 ) { - edl->clips[idx] = new_clip; - clip->remove_user(); - } - else - edl->clips.append(new_clip); - popup->gui->async_update_assets(); - } + if( clips_total ) { + popup->unlock_window(); + EDL *clip = mwindow->session->drag_clips->values[0]; + mwindow->stack_push(clip); + popup->lock_window("ClipPopupOpenEDL::handle_event"); } - gui->unlock_window(); return 1; } diff --git a/cinelerra-5.1/cinelerra/clippopup.h b/cinelerra-5.1/cinelerra/clippopup.h index dba9eab4..c09508aa 100644 --- a/cinelerra-5.1/cinelerra/clippopup.h +++ b/cinelerra-5.1/cinelerra/clippopup.h @@ -51,9 +51,14 @@ public: ClipPopupInfo *info; + AWindowListFormat *format; + ClipPopupSort *sort; + ClipPopupOpenEDL *open_edl; ClipPopupView *view; ClipPopupViewWindow *view_window; - AWindowListFormat *format; + ClipPopupCopy *copy; + ClipPopupToMedia *to_media; + ClipPopupPaste *paste; }; class ClipPopupInfo : public BC_MenuItem @@ -208,11 +213,11 @@ public: AWindowGUI *gui; }; -class ClipPopupNest : public BC_MenuItem +class ClipPopupToMedia : public BC_MenuItem { public: - ClipPopupNest(MWindow *mwindow, ClipPopup *popup); - ~ClipPopupNest(); + ClipPopupToMedia(MWindow *mwindow, ClipPopup *popup); + ~ClipPopupToMedia(); int handle_event(); @@ -220,11 +225,11 @@ public: ClipPopup *popup; }; -class ClipPopupUnNest : public BC_MenuItem +class ClipPopupOpenEDL : public BC_MenuItem { public: - ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup); - ~ClipPopupUnNest(); + ClipPopupOpenEDL(MWindow *mwindow, ClipPopup *popup); + ~ClipPopupOpenEDL(); int handle_event(); diff --git a/cinelerra-5.1/cinelerra/clippopup.inc b/cinelerra-5.1/cinelerra/clippopup.inc index 365d4725..21399eaf 100644 --- a/cinelerra-5.1/cinelerra/clippopup.inc +++ b/cinelerra-5.1/cinelerra/clippopup.inc @@ -32,10 +32,11 @@ class ClipPopupPaste; class ClipMatchSize; class ClipMatchRate; class ClipMatchAll; -class ClipPopupProjectRemove; -class ClipPopupDiskRemove; +class ClipPopupDelete; class ClipPasteToFolder; -class ClipListMenu; class ClipListFormat; +class ClipListMenu; +class ClipPopupToMedia; +class ClipPopupOpenEDL; #endif diff --git a/cinelerra-5.1/cinelerra/colorpicker.C b/cinelerra-5.1/cinelerra/colorpicker.C index 78f1f957..26451d70 100644 --- a/cinelerra-5.1/cinelerra/colorpicker.C +++ b/cinelerra-5.1/cinelerra/colorpicker.C @@ -79,7 +79,7 @@ BC_Window* ColorPicker::new_gui() int w = ColorWindow::calculate_w(); int h = ColorWindow::calculate_h(); if( ok_cancel ) - h += bmax(BC_OKButton::calculate_h(),BC_CancelButton::calculate_h()); + h += bmax(ColorOK::calculate_h(),ColorCancel::calculate_h()); int root_w = display_info.get_root_w(), root_h = display_info.get_root_h(); if( x+w > root_w ) x = root_w - w; if( y+h > root_h ) y = root_h - h; @@ -266,8 +266,8 @@ void ColorGUI::create_objects() aph_a->create_objects(); aph_a->set_tooltip(_("Alpha")); } if( ok_cancel ) { - add_tool(new BC_OKButton(window)); - add_tool(new BC_CancelButton(window)); + add_tool(new ColorOK(this, window)); + add_tool(new ColorCancel(this, window)); } create_objects(this); @@ -289,8 +289,41 @@ void ColorGUI::change_values() } +ColorOK::ColorOK(ColorGUI *gui, BC_WindowBase *window) + : BC_OKButton(window) +{ + this->gui = gui; + this->window = window; +} +int ColorOK::handle_event() +{ + gui->ok_cancel = 0; + gui->close_gui(); + window->sync_display(); + return 1; +} + +ColorCancel::ColorCancel(ColorGUI *gui, BC_WindowBase *window) + : BC_CancelButton(window) +{ + this->gui = gui; + this->window = window; +} +int ColorCancel::handle_event() +{ + gui->ok_cancel = 1; + gui->close_gui(); + window->sync_display(); + return 1; +} + int ColorGUI::close_gui() { + if( button_grabbed ) { + button_grabbed = 0; + window->ungrab_buttons(); + window->ungrab_cursor(); + } window->set_done(ok_cancel ? 1 : 0); return 1; } @@ -1141,7 +1174,7 @@ int PaletteGrabButton::handle_event() if( gui->window->grab_buttons() ) { gui->window->grab_cursor(); gui->button_grabbed = 1; - gui->button_press_gui(); // redraw face HI + return BC_Button::button_press_event(); // redraw face HI } return 1; } diff --git a/cinelerra-5.1/cinelerra/colorpicker.h b/cinelerra-5.1/cinelerra/colorpicker.h index 85fa706b..706b2792 100644 --- a/cinelerra-5.1/cinelerra/colorpicker.h +++ b/cinelerra-5.1/cinelerra/colorpicker.h @@ -151,6 +151,25 @@ public: ColorPicker *thread; }; +class ColorOK : public BC_OKButton +{ +public: + ColorOK(ColorGUI *gui, BC_WindowBase *window); + int handle_event(); + + BC_WindowBase *window; + ColorGUI *gui; +}; + +class ColorCancel : public BC_CancelButton +{ +public: + ColorCancel(ColorGUI *gui, BC_WindowBase *window); + int handle_event(); + + BC_WindowBase *window; + ColorGUI *gui; +}; class PaletteWheel : public BC_SubWindow { diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index 970cadf9..052a713d 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -21,6 +21,7 @@ #include "automation.h" #include "autos.h" +#include "bccolors.h" #include "bcsignals.h" #include "canvas.h" #include "clip.h" @@ -2345,45 +2346,22 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) gui->eyedrop_visible = 1; } -// Decompression coefficients straight out of jpeglib -#define V_TO_R 1.40200 -#define V_TO_G -0.71414 - -#define U_TO_G -0.34414 -#define U_TO_B 1.77200 - -#define GET_COLOR(type, components, max, do_yuv) \ -{ \ +#define GET_COLOR(type, components, max, do_yuv) { \ type *row = (type*)(refresh_frame->get_rows()[i]) + \ j * components; \ float red = (float)*row++ / max; \ float green = (float)*row++ / max; \ float blue = (float)*row++ / max; \ if( do_yuv ) \ - { \ - float r = red + V_TO_R * (blue - 0.5); \ - float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \ - float b = red + U_TO_B * (green - 0.5); \ - mwindow->edl->local_session->red += r; \ - mwindow->edl->local_session->green += g; \ - mwindow->edl->local_session->blue += b; \ - if( r > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = r; \ - if( g > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = g; \ - if( b > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = b; \ - } \ - else \ - { \ - mwindow->edl->local_session->red += red; \ - mwindow->edl->local_session->green += green; \ - mwindow->edl->local_session->blue += blue; \ - if( red > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = red; \ - if( green > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = green; \ - if( blue > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = blue; \ - } \ + YUV::yuv.yuv_to_rgb_f(red, green, blue, red, green-0.5, blue-0.5); \ + mwindow->edl->local_session->red += red; \ + mwindow->edl->local_session->green += green; \ + mwindow->edl->local_session->blue += blue; \ + if( red > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = red; \ + if( green > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = green; \ + if( blue > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = blue; \ } - - mwindow->edl->local_session->red = 0; mwindow->edl->local_session->green = 0; mwindow->edl->local_session->blue = 0; diff --git a/cinelerra-5.1/cinelerra/cwindowtool.C b/cinelerra-5.1/cinelerra/cwindowtool.C index 64c3c78e..2f284b10 100644 --- a/cinelerra-5.1/cinelerra/cwindowtool.C +++ b/cinelerra-5.1/cinelerra/cwindowtool.C @@ -636,8 +636,8 @@ void CWindowEyedropGUI::update() float y, u, v; YUV::yuv.rgb_to_yuv_f(r, g, b, y, u, v); this->y->update(y); - this->u->update(u); u += 0.5; - this->v->update(v); v += 0.5; + this->u->update(u += 0.5); + this->v->update(v += 0.5); int yx = 255*y + 0.5; bclamp(yx,0,255); int ux = 255*u + 0.5; bclamp(ux,0,255); @@ -3082,7 +3082,7 @@ int CWindowMaskGUI::save_mask(const char *nm) int i = masks.size(); while( --i >= 0 ) { if( strcmp(masks[i]->name, nm) ) continue; - masks.remove_object_number(i); + masks.remove_object_number(i++); } mask = new SubMask(0, -1); strncpy(mask->name, nm, sizeof(mask->name)-1); @@ -3100,7 +3100,7 @@ int CWindowMaskGUI::del_mask(const char *nm) int i = masks.size(); while( --i >= 0 ) { if( strcmp(masks[i]->name, nm) ) continue; - masks.remove_object_number(i); + masks.remove_object_number(i++); } save_masks(masks); masks.remove_all_objects(); diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index 7d04cc8d..dbda78c1 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -34,6 +34,7 @@ #include "edits.h" #include "edl.h" #include "edlsession.h" +#include "file.h" #include "filexml.h" #include "floatauto.h" #include "floatautos.h" @@ -600,7 +601,7 @@ void EDL::copy_indexables(EDL *edl) } } -EDL *EDL::new_nested(EDL *edl, const char *path) +EDL *EDL::new_nested_edl(EDL *edl, const char *path) { EDL *nested = new EDL; // no parent for nested edl nested->create_objects(); @@ -613,6 +614,22 @@ EDL *EDL::new_nested(EDL *edl, const char *path) return nested; } +EDL *EDL::get_nested_edl() +{ + Track *track = tracks->first; + Edit *edit = track ? track->edits->first : 0; + EDL *nested = edit && !edit->next && !edit->asset ? edit->nested_edl : 0; + while( nested && (track=track->next)!=0 ) { + Edit *edit = track->edits->first; + if( !edit || edit->next || + ( edit->nested_edl != nested && + strcmp(edit->nested_edl->path, nested->path) ) ) + nested = 0; + } + return nested; +} + + EDL *EDL::create_nested_clip(EDL *nested) { EDL *new_edl = new EDL(this); // parent for clip edl @@ -623,14 +640,46 @@ EDL *EDL::create_nested_clip(EDL *nested) void EDL::create_nested(EDL *nested) { + int video_tracks = 0, audio_tracks = 0; + for( Track *track=nested->tracks->first; track!=0; track=track->next ) { + if( track->data_type == TRACK_VIDEO && track->record ) ++video_tracks; + if( track->data_type == TRACK_AUDIO && track->record ) ++audio_tracks; + } +// renderengine properties + if( video_tracks > 0 ) + video_tracks = 1; + if( audio_tracks > 0 ) + audio_tracks = nested->session->audio_channels; + // Keep frame rate, sample rate, and output size unchanged. // Nest all video & audio outputs + session->video_channels = video_tracks; + session->audio_channels = audio_tracks; session->video_tracks = 1; - session->audio_tracks = nested->session->audio_channels; + session->audio_tracks = audio_tracks; create_default_tracks(); insert_asset(0, nested, 0, 0, 0); } +void EDL::overwrite_clip(EDL *clip) +{ + int folder = folder_no; + char clip_title[BCTEXTLEN]; strcpy(clip_title, local_session->clip_title); + char clip_notes[BCTEXTLEN]; strcpy(clip_notes, local_session->clip_notes); + char clip_icon[BCSTRLEN]; strcpy(clip_icon, local_session->clip_icon); + copy_all(clip); + folder_no = folder; + strcpy(local_session->clip_title, clip_title); + strcpy(local_session->clip_notes, clip_notes); + strcpy(local_session->clip_icon, clip_icon); + if( !clip_icon[0] ) return; +// discard old clip icon to reconstruct + char clip_icon_path[BCTEXTLEN]; + snprintf(clip_icon_path, sizeof(clip_icon_path), + "%s/%s", File::get_config_path(), clip_icon); + remove(clip_icon_path); +} + void EDL::retrack() { int min_w = session->output_w, min_h = session->output_h; @@ -1158,7 +1207,7 @@ void EDL::insert_asset(Asset *asset, if( new_nested_edl ) { length = new_nested_edl->tracks->total_length(); - layers = 1; + layers = new_nested_edl->session->video_channels; channels = new_nested_edl->session->audio_channels; } diff --git a/cinelerra-5.1/cinelerra/edl.h b/cinelerra-5.1/cinelerra/edl.h index 3e201a07..8656c608 100644 --- a/cinelerra-5.1/cinelerra/edl.h +++ b/cinelerra-5.1/cinelerra/edl.h @@ -196,9 +196,11 @@ public: int copy_assets(int copy_flags, double start, double end, FileXML *file, const char *output_path); void copy_indexables(EDL *edl); - EDL *new_nested(EDL *edl, const char *path); + EDL *new_nested_edl(EDL *edl, const char *path); + EDL *get_nested_edl(); EDL *create_nested_clip(EDL *nested); void create_nested(EDL *nested); + void overwrite_clip(EDL *clip); void paste_silence(double start, double end, int edit_labels /* = 1 */, int edit_plugins, diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index d932f679..8d27ff96 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -180,7 +180,6 @@ extern "C" } - extern long cin_timezone; ArrayList* MWindow::plugindb = 0; @@ -1312,7 +1311,7 @@ void MWindow::stop_mixers() } } -void MWindow::close_mixers(int destroy) +void MWindow::close_mixers(int result) { ArrayList closed; zwindows_lock->lock("MWindow::close_mixers"); @@ -1320,10 +1319,9 @@ void MWindow::close_mixers(int destroy) ZWindow *zwindow = zwindows[i]; if( zwindow->idx < 0 ) continue; zwindow->idx = -1; - zwindow->destroy = destroy; ZWindowGUI *zgui = zwindow->zgui; zgui->lock_window("MWindow::select_zwindow 0"); - zgui->set_done(0); + zgui->set_done(result); zgui->unlock_window(); closed.append(zwindow); } @@ -3734,6 +3732,122 @@ void MWindow::update_project(int load_mode) if(debug) PRINT_TRACE } +void MWindow::stack_push(EDL *new_edl) +{ +// needs gui lock + gui->lock_window("MWindow::stack_push"); + if( stack.size() < 9 ) { + undo_before(); + StackItem &item = stack.append(); + item.edl = edl; + item.new_edl = new_edl; + item.undo = undo; + edl = new_edl; + edl->add_user(); + strcpy(session->filename, edl->path); + undo = new MainUndo(this); + gui->stack_button->update(); + update_project(LOADMODE_REPLACE); + } + gui->unlock_window(); +} + +void MWindow::stack_pop() +{ + if( !stack.size() ) return; +// writes on config_path/backup%d.xml + save_backup(); +// already have gui lock + forget_nested_edl(edl); + StackItem &item = stack.last(); +// session edl replaced, overwrite and save clip data + if( item.new_edl != edl && item.new_edl->parent_edl ) + item.new_edl->overwrite_clip(edl); + edl->remove_user(); + edl = item.edl; + delete undo; + undo = item.undo; + stack.remove(); + strcpy(session->filename, edl->path); + update_project(LOADMODE_REPLACE); + undo_after(_("open edl"), LOAD_ALL); + gui->stack_button->update(); +} + +void MWindow::forget_nested_edl(EDL *nested) +{ + frame_cache->remove_item(nested); + wave_cache->remove_item(nested); + if( gui->render_engine && + gui->render_engine_id == nested->id ) { + delete gui->render_engine; + gui->render_engine = 0; + } + if( gui->resource_thread->render_engine_id == nested->id ) { + gui->resource_thread->render_engine_id = -1; + delete gui->resource_thread->render_engine; + gui->resource_thread->render_engine = 0; + } +} + +void MWindow::clip_to_media() +{ + if( edl->session->proxy_scale != 1 ) { + eprintf("Nesting not allowed when proxy scale != 1"); + return; + } + undo_before(); + int clips_total = session->drag_clips->total; + for( int i=0; idrag_clips->values[i]; + time_t dt; time(&dt); + struct tm dtm; localtime_r(&dt, &dtm); + char path[BCSTRLEN], *cp = path, *ep = cp+sizeof(path)-1; + cp += snprintf(cp, ep-cp, _("Nested_%02d%02d%02d-%02d%02d%02d_"), + dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, + dtm.tm_hour, dtm.tm_min, dtm.tm_sec); + cp += snprintf(cp, ep-cp, clip->local_session->clip_title); + EDL *nested = edl->new_nested_edl(clip, path); + edl->clips.remove(clip); + clip->remove_user(); + mainindexes->add_next_asset(0, nested); + } + undo_after(_("clip2media"), LOAD_ALL); + mainindexes->start_build(); + awindow->gui->async_update_assets(); +} + +void MWindow::media_to_clip() +{ + undo_before(); + int assets_total = session->drag_assets->total; + for( int i=0; idrag_assets->values[i]; + if( idxbl->is_asset ) { + eprintf(_("media is not EDL:\n%s"), idxbl->path); + continue; + } + char clip_title[BCSTRLEN]; + int name_ok = 0; + while( !name_ok ) { + name_ok = 1; + sprintf(clip_title, _("Clip %d"), session->clip_number++); + for( int i=0; name_ok && iclips.size(); ++i ) { + char *title = edl->clips[i]->local_session->clip_title; + if( !strcasecmp(clip_title, title) ) name_ok = 0; + } + } + EDL *nested = (EDL *)idxbl; + EDL *clip = edl->add_clip(nested); + strcpy(clip->local_session->clip_title, clip_title); + snprintf(clip->local_session->clip_notes, + sizeof(clip->local_session->clip_notes), + _("From: %s"), nested->path); + } + undo_after(_("media2clip"), LOAD_ALL); + awindow->gui->async_update_assets(); +} + void MWindow::update_preferences(Preferences *prefs) { if( prefs != preferences ) @@ -3807,24 +3921,29 @@ void MWindow::rebuild_indices() } +void MWindow::get_backup_path(char *path, int len) +{ + char *cp = path, *ep = cp + len-1; + cp += snprintf(cp, ep-cp, "%s/", File::get_config_path()); + int idx = stack.size(); + cp += snprintf(cp, ep-cp, idx ? BACKUPn_FILE : BACKUP_FILE, idx); +} + void MWindow::save_backup() { FileXML file; edl->optimize(); edl->set_path(session->filename); + char backup_path[BCTEXTLEN], backup_path1[BCTEXTLEN]; - snprintf(backup_path, sizeof(backup_path), "%s/%s", - File::get_config_path(), BACKUP_FILE); - snprintf(backup_path1, sizeof(backup_path1), "%s/%s", - File::get_config_path(), BACKUP_FILE1); + get_backup_path(backup_path, sizeof(backup_path)); rename(backup_path, backup_path1); edl->save_xml(&file, backup_path); file.terminate_string(); FileSystem fs; fs.complete_path(backup_path); - if(file.write_to_file(backup_path)) - { + if(file.write_to_file(backup_path)) { char string2[256]; sprintf(string2, _("Couldn't open %s for writing."), backup_path); gui->show_message(string2); @@ -3837,8 +3956,7 @@ void MWindow::load_backup() path_list.set_array_delete(); char *out_path; char backup_path[BCTEXTLEN]; - snprintf(backup_path, sizeof(backup_path), "%s/%s", - File::get_config_path(), BACKUP_FILE); + get_backup_path(backup_path, sizeof(backup_path)); FileSystem fs; fs.complete_path(backup_path); diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 66b43626..e938b743 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -105,6 +105,18 @@ #define FONT_SEARCHPATH "fonts" +class StackItem +{ +public: + EDL *edl, *new_edl; + MainUndo *undo; +}; + +class Stack : public ArrayList +{ +public: +}; + class MWindow : public Thread { @@ -135,6 +147,12 @@ public: int get_tracks_height(); // Total horizontal pixels in timeline int get_tracks_width(); +// session stack + void stack_push(EDL *edl); + void stack_pop(); + void forget_nested_edl(EDL *nested); + void clip_to_media(); + void media_to_clip(); // Show windows void show_vwindow(); void show_awindow(); @@ -218,7 +236,7 @@ public: void create_mixers(double position = 0); void refresh_mixers(int dir=1); void stop_mixers(); - void close_mixers(int destroy=1); + void close_mixers(int result=1); void open_mixers(); ZWindow *get_mixer(Mixer *&mixer); void del_mixer(ZWindow *zwindow); @@ -289,6 +307,7 @@ public: void split_y(); void crop_video(int mode); void update_plugins(); + void get_backup_path(char *path, int len); // Call after every edit operation void save_backup(); void load_backup(); @@ -564,6 +583,8 @@ public: // Main undo stack MainUndo *undo; int undo_command; +// session stack + Stack stack; BC_Hash *defaults; Assets *assets; diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index 09c8043b..94d8c4b5 100644 --- a/cinelerra-5.1/cinelerra/mwindowedit.C +++ b/cinelerra-5.1/cinelerra/mwindowedit.C @@ -2177,28 +2177,24 @@ void MWindow::save_clip(EDL *new_edl, const char *txt) time_t now; time(&now); struct tm dtm; localtime_r(&now, &dtm); char *cp = new_edl->local_session->clip_notes; - int n, sz = sizeof(new_edl->local_session->clip_notes)-1; - if( txt && *txt ) { - n = snprintf(cp, sz, "%s", txt); - cp += n; sz -= n; - } - n = snprintf(cp, sz, + char *ep = cp + sizeof(new_edl->local_session->clip_notes)-1; + if( txt && *txt ) + cp += snprintf(cp, ep-cp, "%s", txt); + cp += snprintf(cp, ep-cp, "%02d/%02d/%02d %02d:%02d:%02d, +%s\n", dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, dtm.tm_hour, dtm.tm_min, dtm.tm_sec, duration); - cp += n; sz -= n; if( path && *path ) { FileSystem fs; char title[BCTEXTLEN]; fs.extract_name(title, path); - n = snprintf(cp, sz, "%s", title); - cp += n; sz -= n; + cp += snprintf(cp, ep-cp, "%s", title); } - cp[n] = 0; sprintf(new_edl->local_session->clip_icon, - "clip_%02d%02d%02d-%02d%02d%02d.png", + "clip_%02d%02d%02d-%02d%02d%02d-%d.png", dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, - dtm.tm_hour, dtm.tm_min, dtm.tm_sec); + dtm.tm_hour, dtm.tm_min, dtm.tm_sec, + new_edl->id); new_edl->folder_no = AW_CLIP_FOLDER; edl->update_assets(new_edl); int cur_x, cur_y; diff --git a/cinelerra-5.1/cinelerra/mwindowgui.C b/cinelerra-5.1/cinelerra/mwindowgui.C index 248a5600..e295c150 100644 --- a/cinelerra-5.1/cinelerra/mwindowgui.C +++ b/cinelerra-5.1/cinelerra/mwindowgui.C @@ -100,6 +100,7 @@ MWindowGUI::MWindowGUI(MWindow *mwindow) drag_popup = 0; render_engine = 0; + render_engine_id = -1; for(int i = 0; i < TOTAL_PANES; i++) pane[i] = 0; @@ -168,20 +169,21 @@ void MWindowGUI::create_objects() if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__); - int x = get_w() - MainShBtns::calculate_w(-1, 0, -1); - add_subwindow(mainmenu = new MainMenu(mwindow, this, x)); - mainmenu->create_objects(); - add_subwindow(mainshbtns = new MainShBtns(mwindow, x, -1)); + int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5); + add_subwindow(mainshbtns = new MainShBtns(mwindow, x1, -1)); mainshbtns->load(mwindow->preferences); + int x2 = x1 - mwindow->theme->stack_button_w - xS(5); + add_subwindow(stack_button = new StackButton(mwindow, x2, yS(2))); + add_subwindow(mainmenu = new MainMenu(mwindow, this, x2)); + mainmenu->create_objects(); mwindow->theme->get_mwindow_sizes(this, get_w(), get_h()); mwindow->theme->draw_mwindow_bg(this); if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__); add_subwindow(mbuttons = new MButtons(mwindow, this)); mbuttons->create_objects(); - int x1 = mbuttons->get_x() + mbuttons->get_w(), y1 = mbuttons->get_y()+yS(2); - add_subwindow(proxy_toggle = new ProxyToggle(mwindow, mbuttons, x1, y1)); - x1 += proxy_toggle->get_w() + xS(3); + int y1 = mbuttons->get_y()+yS(2); + add_subwindow(proxy_toggle = new ProxyToggle(mwindow, mbuttons, x2, y1)); add_subwindow(ffmpeg_toggle = new FFMpegToggle(mwindow, mbuttons, x1, y1)); pane[TOP_LEFT_PANE] = new TimelinePane(mwindow, @@ -289,15 +291,16 @@ int MWindowGUI::resize_event(int w, int h) //printf("MWindowGUI::resize_event %d\n", __LINE__); mwindow->session->mwindow_w = w; mwindow->session->mwindow_h = h; - int x = w - MainShBtns::calculate_w(-1, 0, -1); - mainmenu->resize_event(x, mainmenu->get_h()); - mainshbtns->reposition_window(x, -1); + int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5); + mainshbtns->reposition_window(x1, -1); + int x2 = x1 - mwindow->theme->stack_button_w - xS(5); + stack_button->reposition_window(x2, stack_button->get_y()); + mainmenu->resize_event(x2, mainmenu->get_h()); mwindow->theme->get_mwindow_sizes(this, w, h); mwindow->theme->draw_mwindow_bg(this); mbuttons->resize_event(); - int x1 = mbuttons->get_x() + mbuttons->get_w(), y1 = mbuttons->get_y()+yS(2); - proxy_toggle->reposition_window(x1, y1); - x1 += proxy_toggle->get_w() + xS(3); + int y1 = mbuttons->get_y()+yS(2); + proxy_toggle->reposition_window(x2, y1); ffmpeg_toggle->reposition_window(x1, y1); statusbar->resize_event(); zoombar->resize_event(); @@ -609,6 +612,7 @@ void MWindowGUI::flash_canvas(int flush) int MWindowGUI::show_window(int flush) { int ret = BC_WindowBase::show_window(flush); + stack_button->update(); update_proxy_toggle(); return ret; } @@ -2298,6 +2302,34 @@ int FFMpegToggle::handle_event() } +StackButton::StackButton(MWindow *mwindow, int x, int y) + : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0") +{ + this->mwindow = mwindow; + set_tooltip(_("Return to previous EDL")); +} + +int StackButton::handle_event() +{ + mwindow->stack_pop(); + return 1; +} + +void StackButton::update() +{ + char text[BCSTRLEN]; + int i = mwindow->stack.size(); + sprintf(text, "%d", i); + set_text(text); + draw_face(); + int hidden = is_hidden(); + if( !i && !hidden ) + hide_window(); + else if( hidden ) + show_window(); +} + + ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y) : BC_Toggle(x, y, ( !mwindow->edl->session->proxy_use_scaler ? mwindow->theme->proxy_p_toggle : diff --git a/cinelerra-5.1/cinelerra/mwindowgui.h b/cinelerra-5.1/cinelerra/mwindowgui.h index 68e0a4f7..4ba7c16e 100644 --- a/cinelerra-5.1/cinelerra/mwindowgui.h +++ b/cinelerra-5.1/cinelerra/mwindowgui.h @@ -79,6 +79,16 @@ public: MButtons *mbuttons; }; +class StackButton : public BC_GenericButton +{ +public: + StackButton(MWindow *mwindow, int x, int y); + int handle_event(); + void update(); + + MWindow *mwindow; +}; + class ProxyToggle : public BC_Toggle { public: @@ -225,6 +235,7 @@ public: MButtons *mbuttons; FFMpegToggle *ffmpeg_toggle; ProxyToggle *proxy_toggle; + StackButton *stack_button; PaneDivider *x_divider; PaneDivider *y_divider; TimelinePane *pane[TOTAL_PANES]; diff --git a/cinelerra-5.1/cinelerra/preferences.inc b/cinelerra-5.1/cinelerra/preferences.inc index 00686a45..0d6e5330 100644 --- a/cinelerra-5.1/cinelerra/preferences.inc +++ b/cinelerra-5.1/cinelerra/preferences.inc @@ -25,6 +25,7 @@ // Run-time configuration directory #define DEAMON_PORT 400 #define BACKUP_FILE "backup.xml" +#define BACKUPn_FILE "backup%d.xml" #define BACKUP_FILE1 "backup.prev" #define LAYOUT_FILE "layout%d_rc" #define LAYOUT_NAME_LEN 8 diff --git a/cinelerra-5.1/cinelerra/resourcethread.C b/cinelerra-5.1/cinelerra/resourcethread.C index ae861e96..076b0436 100644 --- a/cinelerra-5.1/cinelerra/resourcethread.C +++ b/cinelerra-5.1/cinelerra/resourcethread.C @@ -174,6 +174,7 @@ ResourceThread::ResourceThread(MWindow *mwindow, MWindowGUI *gui) prev_l = 0; operation_count = 0; render_engine = 0; + render_engine_id = -1; audio_asset = 0; audio_source = 0; diff --git a/cinelerra-5.1/cinelerra/theme.C b/cinelerra-5.1/cinelerra/theme.C index d35e4750..efb513f0 100644 --- a/cinelerra-5.1/cinelerra/theme.C +++ b/cinelerra-5.1/cinelerra/theme.C @@ -70,6 +70,7 @@ Theme::Theme() mtransport_margin = 0; toggle_margin = 0; control_pixels = xS(50); + stack_button_w = xS(32); timebar_cursor_color = RED; BC_WindowBase::get_resources()->bg_color = BLOND; @@ -608,7 +609,9 @@ void Theme::get_mwindow_sizes(MWindowGUI *gui, int w, int h) { mbuttons_x = 0; mbuttons_y = gui->menu_h() + yS(1); - mbuttons_w = w - (ffmpeg_toggle[0]->get_w()+2 + proxy_p_toggle[0]->get_w()+xS(2)); + mbuttons_w = w - (ffmpeg_toggle[0]->get_w()+xS(2) + + proxy_p_toggle[0]->get_w()+xS(2) + + stack_button_w); mbuttons_h = get_image("mbutton_bg")->get_h(); mclock_x = window_border - xS(5); mclock_y = mbuttons_y-1 + mbuttons_h; diff --git a/cinelerra-5.1/cinelerra/theme.h b/cinelerra-5.1/cinelerra/theme.h index 1b1e4b38..f0eb5cf2 100644 --- a/cinelerra-5.1/cinelerra/theme.h +++ b/cinelerra-5.1/cinelerra/theme.h @@ -165,6 +165,7 @@ public: int adivider_x, adivider_y, adivider_w, adivider_h; int afolders_x, afolders_y, afolders_w, afolders_h; int alist_x, alist_y, alist_w, alist_h; + int stack_button_w; int audio_color; // audio zero crossing int zero_crossing_color; diff --git a/cinelerra-5.1/cinelerra/zwindow.C b/cinelerra-5.1/cinelerra/zwindow.C index 7f6d2800..f40e804b 100644 --- a/cinelerra-5.1/cinelerra/zwindow.C +++ b/cinelerra-5.1/cinelerra/zwindow.C @@ -185,7 +185,6 @@ ZWindow::ZWindow(MWindow *mwindow) idx = -1; edl = 0; highlighted = 0; - destroy = 1; title[0] = 0; zgui = 0; } @@ -207,10 +206,10 @@ BC_Window* ZWindow::new_gui() void ZWindow::handle_done_event(int result) { - idx = -1; stop_playback(1); - if( destroy ) + if( result ) mwindow->del_mixer(this); + idx = -1; } void ZWindow::handle_close_event(int result) { diff --git a/cinelerra-5.1/cinelerra/zwindow.h b/cinelerra-5.1/cinelerra/zwindow.h index fcd05699..1c6f4ce0 100644 --- a/cinelerra-5.1/cinelerra/zwindow.h +++ b/cinelerra-5.1/cinelerra/zwindow.h @@ -81,7 +81,7 @@ public: ZWindowGUI *zgui; EDL* edl; - int idx, destroy; + int idx; int highlighted; char title[BCTEXTLEN]; }; diff --git a/cinelerra-5.1/cinelerra/zwindowgui.C b/cinelerra-5.1/cinelerra/zwindowgui.C index b6cccd03..90cd349a 100644 --- a/cinelerra-5.1/cinelerra/zwindowgui.C +++ b/cinelerra-5.1/cinelerra/zwindowgui.C @@ -85,7 +85,7 @@ int ZWindowGUI::translation_event() int ZWindowGUI::close_event() { - set_done(0); + set_done(1); return 1; } diff --git a/cinelerra-5.1/ffmpeg/audio/user_s16le.mka b/cinelerra-5.1/ffmpeg/audio/user_s16le.mka new file mode 100644 index 00000000..57124225 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s16le.mka @@ -0,0 +1,6 @@ +matroska pcm_s16le +# PCM signed 16-bit little-endian (pcm_s16le) in +# Matroska (Audio) container. +# The extension should be "mka". +# ffmpeg --help encoder=pcm_s16le +# ffmpeg --help muxer=matroska diff --git a/cinelerra-5.1/ffmpeg/audio/user_s16le.mkv b/cinelerra-5.1/ffmpeg/audio/user_s16le.mkv new file mode 100644 index 00000000..47a3a113 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s16le.mkv @@ -0,0 +1,7 @@ +matroska pcm_s16le +# PCM signed 16-bit little-endian (pcm_s16le) in +# Matroska container. +# If only audio is exported, the extension should +# be "mka". +# ffmpeg --help encoder=pcm_s16le +# ffmpeg --help muxer=matroska diff --git a/cinelerra-5.1/ffmpeg/audio/user_s16le.w64 b/cinelerra-5.1/ffmpeg/audio/user_s16le.w64 new file mode 100644 index 00000000..84d6718f --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s16le.w64 @@ -0,0 +1,6 @@ +w64 pcm_s16le +# Pure audio format. +# PCM signed 16-bit little-endian (pcm_s16le) in +# Sony Pictures Digital Wave 64 (Wave64, .w64) +# ffmpeg --help encoder=pcm_s16le +# ffmpeg --help muxer=w64 diff --git a/cinelerra-5.1/ffmpeg/audio/user_s24le-2.mkv b/cinelerra-5.1/ffmpeg/audio/user_s24le-2.mkv new file mode 100644 index 00000000..7eddfe59 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s24le-2.mkv @@ -0,0 +1,7 @@ +matroska pcm_s24le +# PCM signed 24-bit little-endian (pcm_s24le) in +# Matroska container. +# If only audio is exported, the extension should +# be "mka". +# ffmpeg --help encoder=pcm_s24le +# ffmpeg --help muxer=matroska diff --git a/cinelerra-5.1/ffmpeg/audio/user_s24le.mka b/cinelerra-5.1/ffmpeg/audio/user_s24le.mka new file mode 100644 index 00000000..4db4d3be --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s24le.mka @@ -0,0 +1,6 @@ +matroska pcm_s24le +# PCM signed 24-bit little-endian (pcm_s24le) in +# Matroska (Audio) container. +# The extension should be "mka". +# ffmpeg --help encoder=pcm_s24le +# ffmpeg --help muxer=matroska diff --git a/cinelerra-5.1/ffmpeg/audio/user_s24le.w64 b/cinelerra-5.1/ffmpeg/audio/user_s24le.w64 new file mode 100644 index 00000000..4d92a438 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s24le.w64 @@ -0,0 +1,6 @@ +w64 pcm_s24le +# Pure audio format. +# PCM signed 24-bit little-endian (pcm_s24le) in +# Sony Pictures Digital Wave 64 (Wave64, .w64) +# ffmpeg --help encoder=pcm_s24le +# ffmpeg --help muxer=w64 diff --git a/cinelerra-5.1/ffmpeg/audio/user_s32le.mka b/cinelerra-5.1/ffmpeg/audio/user_s32le.mka new file mode 100644 index 00000000..b7422510 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s32le.mka @@ -0,0 +1,6 @@ +matroska pcm_s32le +# PCM signed 32-bit little-endian (pcm_s32le) in +# Matroska (Audio) container. +# The extension should be "mka". +# ffmpeg --help encoder=pcm_s32le +# ffmpeg --help muxer=matroska diff --git a/cinelerra-5.1/ffmpeg/audio/user_s32le.mkv b/cinelerra-5.1/ffmpeg/audio/user_s32le.mkv new file mode 100644 index 00000000..6d092e44 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s32le.mkv @@ -0,0 +1,7 @@ +matroska pcm_s32le +# PCM signed 32-bit little-endian (pcm_s32le) in +# Matroska container. +# If only audio is exported, the extension should +# be "mka". +# ffmpeg --help encoder=pcm_s32le +# ffmpeg --help muxer=matroska diff --git a/cinelerra-5.1/ffmpeg/audio/user_s32le.w64 b/cinelerra-5.1/ffmpeg/audio/user_s32le.w64 new file mode 100644 index 00000000..48e5b946 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/user_s32le.w64 @@ -0,0 +1,6 @@ +w64 pcm_s32le +# Pure audio format. +# PCM signed 32-bit little-endian (pcm_s32le) in +# Sony Pictures Digital Wave 64 (Wave64, .w64) +# ffmpeg --help encoder=pcm_s32le +# ffmpeg --help muxer=w64 diff --git a/cinelerra-5.1/guicast/bcbutton.C b/cinelerra-5.1/guicast/bcbutton.C index e4088e55..03256e60 100644 --- a/cinelerra-5.1/guicast/bcbutton.C +++ b/cinelerra-5.1/guicast/bcbutton.C @@ -480,7 +480,11 @@ int BC_GenericButton::draw_face(int flush) return 0; } - +void BC_GenericButton::set_text(const char *cp) +{ + strncpy(text, cp, sizeof(text)); + draw_face(); +} diff --git a/cinelerra-5.1/guicast/bcbutton.h b/cinelerra-5.1/guicast/bcbutton.h index 2250dc6d..372b4d30 100644 --- a/cinelerra-5.1/guicast/bcbutton.h +++ b/cinelerra-5.1/guicast/bcbutton.h @@ -75,6 +75,8 @@ private: class BC_GenericButton : public BC_Button { + int color; + char text[BCTEXTLEN]; public: BC_GenericButton(int x, int y, const char *text, VFrame **data = 0, int color=-1); @@ -85,10 +87,8 @@ public: int draw_face(int flash = 1); static int calculate_w(BC_WindowBase *gui, const char *text); static int calculate_h(); + void set_text(const char *cp); const char *get_text () { return text; } -private: - int color; - char text[BCTEXTLEN]; }; class BC_OKTextButton : public BC_GenericButton diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index f94ee165..a362095e 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -2437,6 +2437,8 @@ void BC_WindowBase::init_glyphs() // Not a fix, but much better than nothing. static int inited = 0; if( inited ) return; + XGrabServer(display); + XSync(display, 0); inited = 1; int cur_font = current_font; // locale encodings, needed glyphs to be preloaded @@ -2449,6 +2451,7 @@ void BC_WindowBase::init_glyphs() draw_text(5,5, text, 0); } set_font(cur_font); + XUngrabServer(display); } void BC_WindowBase::init_im() diff --git a/cinelerra-5.1/guicast/test3.C b/cinelerra-5.1/guicast/test3.C index d8f30152..c94be14f 100644 --- a/cinelerra-5.1/guicast/test3.C +++ b/cinelerra-5.1/guicast/test3.C @@ -22,8 +22,12 @@ #include "bcsignals.h" #include "guicast.h" - - +/* +c++ x.C -I/mnt1/build5/cinelerra-5.1/guicast \ + -L/mnt1/build5/cinelerra-5.1/guicast/x86_64 -lguicast \ + -DHAVE_GL -DHAVE_XFT -I/usr/include/freetype2 -lGL -lX11 -lXext \ + -lXinerama -lXv -lpng -lfontconfig -lfreetype -lXft -pthread +*/ class TestWindow : public BC_Window { @@ -32,18 +36,21 @@ public: void create_objects() { + lock_window("TestWindow::create_objects"); set_color(BLACK); set_font(LARGEFONT); draw_text(10, 50, "Hello world"); flash(); flush(); + unlock_window(); }; }; int main() { - new BC_Signals; + BC_Signals signals; + BC_WindowBase::init_resources(1.); TestWindow window; window.create_objects(); window.run_window(); diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index 29320582..869bba0e 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -276,6 +276,8 @@ int VFrame::reset_parameters(int do_opengl) is_keyframe = 0; pixel_rgb = 0x000000; // BLACK pixel_yuv = 0x008080; + draw_alpha = 1.f; + draw_flags = ALIAS_OFF; stipple = 0; clear_color = 0x000000; clear_alpha = 0x00; @@ -1394,109 +1396,120 @@ int VFrame::get_memory_usage() // a (~alpha) transparency, 0x00==solid .. 0xff==transparent void VFrame::set_pixel_color(int rgb, int a) { - pixel_rgb = (rgb&0xffffff) | ~a<<24; + pixel_rgb = (~a<<24) | (rgb&0xffffff); int ir = 0xff & (pixel_rgb >> 16); int ig = 0xff & (pixel_rgb >> 8); int ib = 0xff & (pixel_rgb >> 0); YUV::yuv.rgb_to_yuv_8(ir, ig, ib); - pixel_yuv = (~a<<24) | (ir<<16) | (ig<<8) | (ib<<0); + pixel_yuv = (~a<<24) | (ir<<16) | (ig<<8) | (ib<<0); } void VFrame::set_stiple(int mask) { stipple = mask; } - -int VFrame::draw_pixel(int x, int y) +void VFrame::set_draw_alpha(float alpha) { - if( x < 0 || y < 0 || x >= get_w() || y >= get_h() ) return 1; - -#define DRAW_PIXEL(type, r, g, b, comps, a) { \ - type **rows = (type**)get_rows(); \ - type *rp = rows[y], *bp = rp + x*comps; \ - bp[0] = r; \ - if( comps > 1 ) { bp[1] = g; bp[2] = b; } \ - if( comps == 4 ) bp[3] = a; \ + draw_alpha = alpha; +} +void VFrame::set_draw_flags(int flags) +{ + draw_flags = flags; } + +int VFrame::draw_pixel(float x, float y, float a) +{ + int ix = x, iy = y; + if( ix < 0 || iy < 0 || ix >= get_w() || iy >= get_h() ) return 1; + if( a <= 0 ) return 0; + if( a > 1 ) a = 1; + int color = BC_CModels::is_yuv(color_model) ? pixel_yuv : pixel_rgb; float fr = 0, fg = 0, fb = 0, fa = 0; - int pixel_color = BC_CModels::is_yuv(color_model) ? pixel_yuv : pixel_rgb; - int ir = (0xff & (pixel_color >> 16)); - int ig = (0xff & (pixel_color >> 8)); - int ib = (0xff & (pixel_color >> 0)); - int ia = (0xff & (pixel_color >> 24)) ^ 0xff; // transparency, not opacity - if( (x+y) & stipple ) { + int ir = (0xff & (color >> 16)); + int ig = (0xff & (color >> 8)); + int ib = (0xff & (color >> 0)); + int ia = (0xff & ~(color >> 24)); // transparency, not opacity + if( (ix+iy) & stipple ) { ir = 255 - ir; ig = 255 - ig; ib = 255 - ib; } int rr = (ir<<8) | ir, gg = (ig<<8) | ig, bb = (ib<<8) | ib, aa = (ia<<8) | ia; + float fmax = 65535.f; fa = aa/fmax; if( BC_CModels::is_float(color_model) ) { - fr = rr/65535.f; fg = gg/65535.f; fb = bb/65535.f; fa = aa/65535.f; + fr = rr/fmax; fg = gg/fmax; fb = bb/fmax; } +#define DRAW_PIXEL(cmdl, type, r, g, b, ofs, max, comps) \ +case cmdl: { \ + float src_a = fa*draw_alpha, src_1a = 1 - src_a; \ + type **rows = (type**)get_rows(); \ + type *rp = rows[iy], *bp = rp + ix*comps; \ + bp[0] = src_a * r + src_1a * bp[0]; \ + if( comps > 1 ) { \ + bp[1] = src_a * (g-ofs) + src_1a * (bp[1]-ofs) + ofs; \ + bp[2] = src_a * (b-ofs) + src_1a * (bp[2]-ofs) + ofs; \ + } \ + if( comps == 4 ) \ + bp[3] = src_a * max + src_1a * bp[3]; \ + break;\ +} + switch(get_color_model()) { - case BC_A8: - DRAW_PIXEL(uint8_t, ib, 0, 0, 1, 0); - break; - case BC_RGB888: - case BC_YUV888: - DRAW_PIXEL(uint8_t, ir, ig, ib, 3, 0); - break; - case BC_RGBA8888: - case BC_YUVA8888: - DRAW_PIXEL(uint8_t, ir, ig, ib, 4, ia); - break; - case BC_RGB161616: - case BC_YUV161616: - DRAW_PIXEL(uint16_t, rr, gg, bb, 3, 0); - break; - case BC_RGBA16161616: - case BC_YUVA16161616: - DRAW_PIXEL(uint16_t, rr, gg, bb, 4, aa); - break; - case BC_RGB_FLOAT: - DRAW_PIXEL(float, fr, fg, fb, 3, 0); - break; - case BC_RGBA_FLOAT: - DRAW_PIXEL(float, fr, fg, fb, 4, fa); - break; + DRAW_PIXEL(BC_A8, uint8_t, ib, 0, 0, 0x00, 0xff, 1); + DRAW_PIXEL(BC_RGB888, uint8_t, ir, ig, ib, 0x00, 0xff, 3); + DRAW_PIXEL(BC_YUV888, uint8_t, ir, ig, ib, 0x80, 0xff, 3); + DRAW_PIXEL(BC_RGBA8888, uint8_t, ir, ig, ib, 0x00, 0xff, 4); + DRAW_PIXEL(BC_YUVA8888, uint8_t, ir, ig, ib, 0x80, 0xff, 4); + DRAW_PIXEL(BC_RGB161616, uint16_t, rr, gg, bb, 0x0000, 0xffff, 3); + DRAW_PIXEL(BC_YUV161616, uint16_t, rr, gg, bb, 0x8000, 0xffff, 3); + DRAW_PIXEL(BC_RGBA16161616, uint16_t, rr, gg, bb, 0x0000, 0xffff, 4); + DRAW_PIXEL(BC_YUVA16161616, uint16_t, rr, gg, bb, 0x8000, 0xffff, 4); + DRAW_PIXEL(BC_RGB_FLOAT, float, fr, fg, fb, 0., 1., 3); + DRAW_PIXEL(BC_RGBA_FLOAT, float, fr, fg, fb, 0., 1., 4); } return 0; } +int VFrame::draw_pixel(float x, float y, float frac, int axis) +{ + if( draw_flags ) { + int xs = axis, ys = 1-axis; + if( draw_flags & ALIAS_TOP ) draw_pixel(x-xs, y-ys, 1-frac); + draw_pixel(x, y, draw_flags & ALIAS_CTR ? 1-frac : 1); + if( draw_flags & ALIAS_BOT ) draw_pixel(x+xs, y+ys, frac); + } + else + draw_pixel(x, y); + return 0; +} -// Bresenham's -void VFrame::draw_line(int x1, int y1, int x2, int y2) +void VFrame::draw_line(float x1, float y1, float x2, float y2) { if( y1 > y2 ) { int tx = x1; x1 = x2; x2 = tx; int ty = y1; y1 = y2; y2 = ty; } - - int x = x1, y = y1; - int dx = x2-x1, dy = y2-y1; - int dx2 = 2*dx, dy2 = 2*dy; - if( dx < 0 ) dx = -dx; - int r = dx > dy ? dx : dy, n = r; - int dir = 0; - if( dx2 < 0 ) dir += 1; - if( dy >= dx ) { - if( dx2 >= 0 ) do { /* +Y, +X */ - draw_pixel(x, y++); - if( (r -= dx2) < 0 ) { r += dy2; ++x; } - } while( --n >= 0 ); - else do { /* +Y, -X */ - draw_pixel(x, y++); - if( (r += dx2) < 0 ) { r += dy2; --x; } - } while( --n >= 0 ); + float dx = x2-x1, dy = y2-y1; + float s = dx ? dy/dx : 1; + float t = dy ? dx/dy : 0; + int xs = dx < 0 ? -1 : 1; + dx *= xs; + int idx = (int)x2 - (int)x1; + int idy = (int)y2 - (int)y1; + int d = dx >= dy ? abs(idx) : idy; + float x = x1, y = y1; + if( dx > dy ) { + draw_pixel(x, y, y-(int)y, 0); + while( --d >= 0 ) { + y = y1 + ((x += xs) - x1) * s; + draw_pixel(x, y, y-(int)y, 0); + } } else { - if( dx2 >= 0 ) do { /* +X, +Y */ - draw_pixel(x++, y); - if( (r -= dy2) < 0 ) { r += dx2; ++y; } - } while( --n >= 0 ); - else do { /* -X, +Y */ - draw_pixel(x--, y); - if( (r -= dy2) < 0 ) { r -= dx2; ++y; } - } while( --n >= 0 ); + draw_pixel(x, y, x-(int)x, 1); + while( --d >= 0 ) { + x = x1 + (++y - y1) * t; + draw_pixel(x, y, x-(int)x, 1); + } } } @@ -1562,7 +1575,15 @@ void smooth_line::draw() if( abs(rr) < abs(r) ) moveX(rr); } -xit: vframe->draw_pixel(sx, sy); +xit: +// vframe->draw_pixel(sx, sy); + float vx = abs(dx), vy = abs(dy); + float vv = 4*(vx > vy ? dx : dy); + float frac = vv ? -r / vv : 0; + frac = (1+frac) / 2; + bclamp(frac, 0, 1); + int axis = abs(dx) >= abs(dy) ? 1 : 0; + vframe->draw_pixel(sx, sy, frac, axis); } void VFrame::draw_smooth(int x1, int y1, int x2, int y2, int x3, int y3) @@ -1696,10 +1717,10 @@ void smooth_line::init1(int x1,int y1, int x2,int y2, int x3,int y3) xmxx = ex; xmxy = ey; } if( xs > 0 ) - vframe->draw_pixel(sx, sy); + vframe->draw_pixel(sx, sy, 0, 0); while( xs*(sx-xmxx) < 0 && (xs*dx < 0 || rx() < 0) ) { moveX(rx()); - vframe->draw_pixel(sx, sy); + vframe->draw_pixel(sx, sy, 0, 0); } } @@ -1723,9 +1744,9 @@ void VFrame::smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3) else if( y1 < y2 && y3 < y2 ) { smooth_line lt(this), rt(this); // Q on top lt.init0(x1, y1, x2, y2, x3, y3, 1); - draw_pixel(lt.sx, lt.sy); + draw_pixel(lt.sx, lt.sy, 0, 0); rt.init0(x1, y1, x2, y2, x3, y3, -1); - draw_pixel(rt.sx, rt.sy); + draw_pixel(rt.sx, rt.sy, 0, 0); while( !lt.done || !rt.done ) { lt.draw(); rt.draw(); @@ -1734,7 +1755,7 @@ void VFrame::smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3) else { smooth_line pt(this); // Q in between pt.init0(x1, y1, x2, y2, x3, y3, 0); - draw_pixel(pt.sx, pt.sy); + draw_pixel(pt.sx, pt.sy, 0, 1); while( !pt.done ) { pt.draw(); } diff --git a/cinelerra-5.1/guicast/vframe.h b/cinelerra-5.1/guicast/vframe.h index 5c717200..21b6497a 100644 --- a/cinelerra-5.1/guicast/vframe.h +++ b/cinelerra-5.1/guicast/vframe.h @@ -35,6 +35,13 @@ #define MAX_STACK_ELEMENTS 255 #define SHM_MIN_SIZE 2048 +#define ALIAS_OFF 0 +#define ALIAS_TOP 1 +#define ALIAS_CTR 2 +#define ALIAS_BOT 4 +#define ALIAS_DBL 5 +#define ALIAS_NRM 6 + // Scene graph for 3D models // Defined by the subclass class VFrameScene @@ -342,16 +349,20 @@ public: void copy_stacks(VFrame *src); // Updates the params with values from src void copy_params(VFrame *src); - // This clears the stacks and the param table void clear_stacks(); - virtual int draw_pixel(int x, int y); - int pixel_rgb, pixel_yuv, stipple; +// pixel drawing + virtual int draw_pixel(float x, float y, float a=1.f); + virtual int draw_pixel(float x, float y, float frac, int axis); + void set_draw_alpha(float a); + void set_draw_flags(int flags); + int pixel_rgb, pixel_yuv, stipple, draw_flags; + float draw_alpha; void set_pixel_color(int rgb, int a=0xff); void set_stiple(int mask); - void draw_line(int x1, int y1, int x2, int y2); + void draw_line(float x1, float y1, float x2, float y2); void draw_smooth(int x1, int y1, int x2, int y2, int x3, int y3); void smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3); void draw_rect(int x1, int y1, int x2, int y2); diff --git a/cinelerra-5.1/plugins/foreground/foreground.h b/cinelerra-5.1/plugins/foreground/foreground.h index 8036cb8b..bd57f639 100644 --- a/cinelerra-5.1/plugins/foreground/foreground.h +++ b/cinelerra-5.1/plugins/foreground/foreground.h @@ -72,6 +72,12 @@ public: void create_objects(); void update(); + int close_event() { return colors->close_gui(); } + int cursor_motion_event() { return colors->cursor_motion_gui(); } + int button_press_event() { return colors->button_press_gui(); } + int button_release_event() { return colors->button_release_gui(); } + void done_event(int result) { colors->close_gui(); } + ForegroundMain *plugin; ForegroundColors *colors; }; diff --git a/cinelerra-5.1/plugins/sketcher/sketcher.C b/cinelerra-5.1/plugins/sketcher/sketcher.C index 272bcf04..2b392327 100644 --- a/cinelerra-5.1/plugins/sketcher/sketcher.C +++ b/cinelerra-5.1/plugins/sketcher/sketcher.C @@ -242,6 +242,7 @@ REGISTER_PLUGIN(Sketcher) SketcherConfig::SketcherConfig() { drag = 1; + aliasing = 0; cv_selected = 0; pt_selected = 0; } @@ -252,6 +253,7 @@ SketcherConfig::~SketcherConfig() int SketcherConfig::equivalent(SketcherConfig &that) { if( this->drag != that.drag ) return 0; + if( this->aliasing != that.aliasing ) return 0; if( this->cv_selected != that.cv_selected ) return 0; if( this->pt_selected != that.pt_selected ) return 0; if( this->curves.size() != that.curves.size() ) return 0; @@ -264,6 +266,7 @@ int SketcherConfig::equivalent(SketcherConfig &that) void SketcherConfig::copy_from(SketcherConfig &that) { this->drag = that.drag; + this->aliasing = that.aliasing; this->cv_selected = that.cv_selected; this->pt_selected = that.pt_selected; int m = curves.size(), n = that.curves.size(); @@ -278,6 +281,7 @@ void SketcherConfig::interpolate(SketcherConfig &prev, SketcherConfig &next, this->cv_selected = prev.cv_selected; this->pt_selected = prev.pt_selected; this->drag = prev.drag; + this->aliasing = prev.aliasing; double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); @@ -360,6 +364,7 @@ void Sketcher::save_data(KeyFrame *keyframe) output.tag.set_title("SKETCHER"); output.tag.set_property("DRAG", config.drag); + output.tag.set_property("ALIASING", config.aliasing); output.tag.set_property("CV_SELECTED", config.cv_selected); output.tag.set_property("PT_SELECTED", config.pt_selected); output.append_tag(); @@ -384,6 +389,7 @@ void Sketcher::read_data(KeyFrame *keyframe) while( !(result=input.read_tag()) ) { if( input.tag.title_is("SKETCHER") ) { config.drag = input.tag.get_property("DRAG", config.drag); + config.aliasing = input.tag.get_property("ALIASING", config.aliasing); config.cv_selected = input.tag.get_property("CV_SELECTED", 0); config.pt_selected = input.tag.get_property("PT_SELECTED", 0); } @@ -438,47 +444,58 @@ void Sketcher::draw_point(VFrame *vfrm, SketcherPoint *pt, int color) } -int SketcherVPen::draw_pixel(int x, int y) +int SketcherVPen::draw_mask(int x, int y) { - if( x >= 0 && x < vfrm->get_w() && - y >= 0 && y < vfrm->get_h() ) - msk[vfrm->get_w()*y + x] = 0xff; + int w = vfrm->get_w(), h = vfrm->get_h(); + if( x < 0 || x >= w ) return 1; + if( y < 0 || y >= h ) return 1; + msk[w * y + x] = 0xff; return 0; } -int SketcherPenSquare::draw_pixel(int x, int y) +int SketcherVPen::draw_pixel(float x, float y, float frac, int axis) { + draw_mask(x, y); + return VFrame::draw_pixel(x, y, frac, axis); +} + +int SketcherPenSquare::draw_pixel(float x, float y, float a) +{ + vfrm->set_draw_alpha(a); vfrm->draw_line(x-n, y, x+n, y); for( int i=-n; idraw_line(x-n, y+i, x+n, y+i); - return SketcherVPen::draw_pixel(x, y); + return 0; } -int SketcherPenPlus::draw_pixel(int x, int y) +int SketcherPenPlus::draw_pixel(float x, float y, float a) { + vfrm->set_draw_alpha(a); if( n > 1 ) { vfrm->draw_line(x-n, y, x+n, y); vfrm->draw_line(x, y-n, x, y+n); } else vfrm->draw_pixel(x, y); - return SketcherVPen::draw_pixel(x, y); + return 0; } -int SketcherPenSlant::draw_pixel(int x, int y) +int SketcherPenSlant::draw_pixel(float x, float y, float a) { + vfrm->set_draw_alpha(a); vfrm->draw_line(x-n, y+n, x+n, y-n); vfrm->draw_line(x-n+1, y+n, x+n+1, y-n); vfrm->draw_line(x-n, y+n+1, x+n, y-n+1); - return SketcherVPen::draw_pixel(x, y); + return 0; } -int SketcherPenXlant::draw_pixel(int x, int y) +int SketcherPenXlant::draw_pixel(float x, float y, float a) { + vfrm->set_draw_alpha(a); vfrm->draw_line(x-n, y+n, x+n, y-n); vfrm->draw_line(x-n+1, y+n, x+n+1, y-n); vfrm->draw_line(x-n, y+n+1, x+n, y-n+1); vfrm->draw_line(x-n, y-n, x+n, y+n); vfrm->draw_line(x-n+1, y-n, x+n+1, y+n); vfrm->draw_line(x-n, y-n+1, x+n, y-n+1); - return SketcherVPen::draw_pixel(x, y); + return 0; } @@ -563,6 +580,7 @@ class FillRegion public: SketcherPoint *next(); bool exists() { return stack.size() > 0; } + void draw_pixel(int x, int y) { img->draw_pixel(x, y); } void start_at(int x, int y); void run(); FillRegion(SketcherPoints &pts, SketcherVPen *vpen); @@ -591,25 +609,26 @@ void FillRegion::start_at(int x, int y) void FillRegion::run() { + img->set_draw_alpha(1); while( stack.size() > 0 ) { int y, ilt, irt; pop(y, ilt, irt); int ofs = y*w + ilt; for( int x=ilt; x<=irt; ++x,++ofs ) { + draw_pixel(x, y); if( msk[ofs] ) continue; msk[ofs] = 0xff; - img->draw_pixel(x, y); int lt = x, rt = x; int lofs = ofs; for( int i=lt; --i>=0; ) { + draw_pixel(i, y); if( msk[--lofs] ) break; - img->draw_pixel(i, y); msk[lofs] = 0xff; lt = i; } int rofs = ofs; for( int i=rt; ++i< w; ) { + draw_pixel(i, y); if( msk[++rofs] ) break; - img->draw_pixel(i, y); msk[rofs] = 0xff; rt = i; } if( y+1 < h ) push(y+1, lt, rt); @@ -629,12 +648,13 @@ SketcherPoint *FillRegion::next() return 0; } - -void SketcherCurve::draw(VFrame *img) +void SketcherCurve::draw(VFrame *img, int alias) { if( !points.size() ) return; + img->set_pixel_color(color, (~color>>24)&0xff); const float fmx = 16383; SketcherVPen *vpen = new_vpen(img); + vpen->set_draw_flags(alias); FillRegion fill(points, vpen); SketcherPoint *pnt0 = fill.next(); SketcherPoint *pnt1 = pnt0 ? fill.next() : 0; @@ -694,7 +714,7 @@ void SketcherCurve::draw(VFrame *img) vpen->draw_line(pnt0->x, pnt0->y, pnt1->x, pnt1->y); } else if( pnt0 ) { - vpen->draw_pixel(pnt0->x, pnt0->y); + vpen->draw_pixel(pnt0->x, pnt0->y, 1); } delete vpen; } @@ -740,10 +760,11 @@ int Sketcher::process_realtime(VFrame *input, VFrame *output) int m = cv->points.size(); if( !m ) continue; img->clear_frame(); - img->set_pixel_color(cv->color, (~cv->color>>24)&0xff); - cv->draw(img); + int alias = config.aliasing < 0 ? ALIAS_OFF : + config.aliasing > 0 ? ALIAS_DBL : ALIAS_NRM; + cv->draw(img, alias); overlay_frame->overlay(out, img, 0,0,w,h, 0,0,w,h, - 1.f, TRANSFER_NORMAL, NEAREST_NEIGHBOR); + 1.f, TRANSFER_SRC_OVER, NEAREST_NEIGHBOR); } if( config.drag ) { diff --git a/cinelerra-5.1/plugins/sketcher/sketcher.h b/cinelerra-5.1/plugins/sketcher/sketcher.h index 1ddd5a47..dcf7a6ba 100644 --- a/cinelerra-5.1/plugins/sketcher/sketcher.h +++ b/cinelerra-5.1/plugins/sketcher/sketcher.h @@ -46,6 +46,7 @@ public: int n; uint8_t *msk; + int draw_mask(int x, int y); SketcherVPen(VFrame *vfrm, int n) : VFrame(vfrm->get_data(), -1, vfrm->get_y()-vfrm->get_data(), vfrm->get_u()-vfrm->get_data(), vfrm->get_v()-vfrm->get_data(), @@ -57,40 +58,38 @@ public: } ~SketcherVPen() { delete [] msk; } - void draw_line(float x1, float y1, float x2, float y2) { - VFrame::draw_line(int(x1+.5f),int(y1+.5f), int(x2+.5f),int(y2+.5f)); - } void draw_smooth(float x1, float y1, float x2, float y2, float x3, float y3) { VFrame::draw_smooth(int(x1+.5f),int(y1+.5f), int(x2+.5f),int(y2+.5f), int(x3+.5f),int(y3+.5f)); } - virtual int draw_pixel(int x, int y) = 0; + virtual int draw_pixel(float x, float y, float a) = 0; + int draw_pixel(float x, float y, float frac, int axis); }; class SketcherPenSquare : public SketcherVPen { public: SketcherPenSquare(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {} - int draw_pixel(int x, int y); + int draw_pixel(float x, float y, float a); }; class SketcherPenPlus : public SketcherVPen { public: SketcherPenPlus(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {} - int draw_pixel(int x, int y); + int draw_pixel(float x, float y, float a); }; class SketcherPenSlant : public SketcherVPen { public: SketcherPenSlant(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {} - int draw_pixel(int x, int y); + int draw_pixel(float x, float y, float a); }; class SketcherPenXlant : public SketcherVPen { public: SketcherPenXlant(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {} - int draw_pixel(int x, int y); + int draw_pixel(float x, float y, float a); }; @@ -140,7 +139,7 @@ public: double nearest_point(int &pi, coord x, coord y); SketcherVPen *new_vpen(VFrame *out); - void draw(VFrame *img); + void draw(VFrame *img, int flags); }; class SketcherCurves : public ArrayList { @@ -166,6 +165,7 @@ public: void dump(); int drag; + int aliasing; int cv_selected, pt_selected; }; diff --git a/cinelerra-5.1/plugins/sketcher/sketcherwindow.C b/cinelerra-5.1/plugins/sketcher/sketcherwindow.C index f62802a7..ff97dd14 100644 --- a/cinelerra-5.1/plugins/sketcher/sketcherwindow.C +++ b/cinelerra-5.1/plugins/sketcher/sketcherwindow.C @@ -255,8 +255,52 @@ void SketcherCurveWidth::update(int width) } +SketcherAliasItem::SketcherAliasItem(SketcherAliasing *popup, int v) + : BC_MenuItem(popup->alias_to_text(v)) +{ + this->popup = popup; + this->v = v; +} + +int SketcherAliasItem::handle_event() +{ + popup->set_text(get_text()); + popup->plugin->config.aliasing = v; + popup->gui->send_configure_change(); + return 1; +} + + +SketcherAliasing::SketcherAliasing(SketcherWindow *gui, Sketcher *plugin, + int x, int y) + : BC_PopupMenu(x, y, xS(64), + alias_to_text(plugin->config.aliasing), 1, 0, xS(3)) +{ + this->gui = gui; + this->plugin = plugin; +} +SketcherAliasing::~SketcherAliasing() +{ +} + +void SketcherAliasing::create_objects() +{ + add_item(new SketcherAliasItem(this, -1)); + add_item(new SketcherAliasItem(this, 0)); + add_item(new SketcherAliasItem(this, 1)); +} + +const char *SketcherAliasing::alias_to_text(int alias) +{ + if( alias < 0 ) return _("Off"); + if( alias > 0 ) return _("Dbl"); + return _("On"); +} + + + SketcherWindow::SketcherWindow(Sketcher *plugin) - : PluginClientWindow(plugin, xS(380), yS(620), xS(380), yS(620), 0) + : PluginClientWindow(plugin, xS(400), yS(620), xS(400), yS(620), 0) { this->plugin = plugin; this->title_pen = 0; this->curve_pen = 0; @@ -310,6 +354,10 @@ void SketcherWindow::create_objects() x1 += title_width->get_w() + margin; curve_width = new SketcherCurveWidth(this, x1, y, cv->width); curve_width->create_objects(); + x1 += curve_width->get_w() + margin; + aliasing = new SketcherAliasing(this, plugin, x1, y); + add_subwindow(aliasing); dy = bmax(dy,aliasing->get_h()); + aliasing->create_objects(); y += dy + 2*margin; dy = 0; x1 = get_w()-x - BC_Title::calculate_w(this, curve_text, LARGEFONT); diff --git a/cinelerra-5.1/plugins/sketcher/sketcherwindow.h b/cinelerra-5.1/plugins/sketcher/sketcherwindow.h index 61585201..72fcc166 100644 --- a/cinelerra-5.1/plugins/sketcher/sketcherwindow.h +++ b/cinelerra-5.1/plugins/sketcher/sketcherwindow.h @@ -15,7 +15,6 @@ * 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 __SKETCHERWINDOW_H__ @@ -38,6 +37,8 @@ class SketcherDelCurve; class SketcherCurveUp; class SketcherCurveDn; class SketcherCurveWidth; +class SketcherAliasItem; +class SketcherAliasing; class SketcherCurveList; class SketcherPointX; class SketcherPointY; @@ -168,6 +169,30 @@ public: int width; }; +class SketcherAliasItem : public BC_MenuItem +{ +public: + SketcherAliasItem(SketcherAliasing *popup, int v); + int handle_event(); + + SketcherAliasing *popup; + int v; +}; + +class SketcherAliasing : public BC_PopupMenu +{ +public: + SketcherAliasing(SketcherWindow *gui, Sketcher *plugin, + int x, int y); + ~SketcherAliasing(); + + const char *alias_to_text(int alias); + void create_objects(); + + Sketcher *plugin; + SketcherWindow *gui; +}; + class SketcherCurveList : public BC_ListBox { public: @@ -376,6 +401,7 @@ public: SketcherCurveUp *curve_up; SketcherCurveDn *curve_dn; SketcherCurveWidth *curve_width; + SketcherAliasing *aliasing; SketcherCurveList *curve_list; SketcherResetCurves *reset_curves; diff --git a/cinelerra-5.1/plugins/tracer/tracerwindow.C b/cinelerra-5.1/plugins/tracer/tracerwindow.C index cff76598..ccc04709 100644 --- a/cinelerra-5.1/plugins/tracer/tracerwindow.C +++ b/cinelerra-5.1/plugins/tracer/tracerwindow.C @@ -85,7 +85,7 @@ int TracerPointY::handle_event() } TracerWindow::TracerWindow(Tracer *plugin) - : PluginClientWindow(plugin, xS(400), yS(420), xS(400), yS(420), 0) + : PluginClientWindow(plugin, xS(460), yS(420), xS(460), yS(420), 0) { this->plugin = plugin; this->title_x = 0; this->point_x = 0; @@ -116,18 +116,18 @@ void TracerWindow::create_objects() TracerPoint *pt = hot_point >= 0 ? plugin->config.points[hot_point] : 0; point_x = new TracerPointX(this, x1, y, !pt ? 0 : pt->x); point_x->create_objects(); - x1 += point_x->get_w() + margin; + x1 += point_x->get_w() + margin + xS(20); add_subwindow(new_point = new TracerNewPoint(this, plugin, x1, y)); - x1 += new_point->get_w() + margin; + x1 += new_point->get_w() + margin + xS(30); add_subwindow(point_up = new TracerPointUp(this, x1, y)); y += point_x->get_h() + margin; add_subwindow(title_y = new BC_Title(x, y, _("Y:"))); x1 = x + title_y->get_w() + margin; point_y = new TracerPointY(this, x1, y, !pt ? 0 : pt->y); point_y->create_objects(); - x1 += point_y->get_w() + margin; + x1 += point_y->get_w() + margin + xS(20); add_subwindow(del_point = new TracerDelPoint(this, plugin, x1, y)); - x1 += del_point->get_w() + margin; + x1 += del_point->get_w() + margin + xS(30); add_subwindow(point_dn = new TracerPointDn(this, x1, y)); y += point_y->get_h() + margin + yS(10); @@ -595,7 +595,7 @@ int TracerRadius::handle_event() } TracerNewPoint::TracerNewPoint(TracerWindow *gui, Tracer *plugin, int x, int y) - : BC_GenericButton(x, y, xS(80), _("New")) + : BC_GenericButton(x, y, xS(100), _("New")) { this->gui = gui; this->plugin = plugin; @@ -612,7 +612,7 @@ int TracerNewPoint::handle_event() } TracerDelPoint::TracerDelPoint(TracerWindow *gui, Tracer *plugin, int x, int y) - : BC_GenericButton(x, y, xS(80), C_("Del")) + : BC_GenericButton(x, y, xS(100), C_("Del")) { this->gui = gui; this->plugin = plugin; diff --git a/cinelerra-5.1/po/es.po b/cinelerra-5.1/po/es.po index 2712b260..511d4624 100644 --- a/cinelerra-5.1/po/es.po +++ b/cinelerra-5.1/po/es.po @@ -986,7 +986,7 @@ msgstr "Recursos" #: cinelerra/awindowgui.C:1428 cinelerra/awindowgui.C:2364 #: cinelerra/awindowgui.C:2384 msgid "awindowgui#Title" -msgstr "awindowgui#Título" +msgstr "Título" #: cinelerra/awindowgui.C:1429 cinelerra/awindowgui.C:2365 msgid "Comments" @@ -1991,7 +1991,7 @@ msgstr "Fuente" #: cinelerra/channelinfo.C:347 msgid "channelinfo#Title" -msgstr "channelinfo#Título" +msgstr "Título" #: cinelerra/channelinfo.C:348 cinelerra/dbwindow.C:596 #: cinelerra/recordbatches.C:22 @@ -2188,43 +2188,43 @@ msgstr "Selector de color" #: cinelerra/colorpicker.C:179 msgid "colorpicker#H:" -msgstr "colorpicker#H:" +msgstr "H:" #: cinelerra/colorpicker.C:180 msgid "colorpicker#S:" -msgstr "colorpicker#S:" +msgstr "S:" #: cinelerra/colorpicker.C:181 msgid "colorpicker_value#V:" -msgstr "colorpicker_value#V:" +msgstr "V:" #: cinelerra/colorpicker.C:182 msgid "colorpicker#R:" -msgstr "colorpicker#R:" +msgstr "R:" #: cinelerra/colorpicker.C:183 msgid "colorpicker#G:" -msgstr "colorpicker#G:" +msgstr "G:" #: cinelerra/colorpicker.C:184 msgid "colorpicker#B:" -msgstr "colorpicker#B:" +msgstr "B:" #: cinelerra/colorpicker.C:185 msgid "colorpicker#Y:" -msgstr "colorpicker#Y:" +msgstr "Y:" #: cinelerra/colorpicker.C:186 msgid "colorpicker#U:" -msgstr "colorpicker#U:" +msgstr "U:" #: cinelerra/colorpicker.C:187 msgid "colorpicker_Cr#V:" -msgstr "colorpicker_Cr#V:" +msgstr "V:" #: cinelerra/colorpicker.C:189 msgid "colorpicker#A:" -msgstr "colorpicker#A:" +msgstr "A:" #: cinelerra/colorpicker.C:205 msgid "Hue" @@ -3026,7 +3026,7 @@ msgstr "longitud" #: cinelerra/dbwindow.C:595 msgid "dbwindow#Title" -msgstr "dbwindow#Título" +msgstr "Título" #: cinelerra/dbwindow.C:597 msgid "Access time" @@ -5585,7 +5585,7 @@ msgstr "Aplicar a todos los fotogramas clave seleccionados" #: cinelerra/keyframegui.C:761 msgid "keyframegui#Save" -msgstr "keyframegui#Guardar" +msgstr "Guardar" #: cinelerra/keyframepopup.C:103 msgid "Show Plugin Settings" @@ -10244,7 +10244,7 @@ msgstr "Arrastrar" #: plugins/crikey/crikeywindow.C:610 msgid "crikeywindow#Del" -msgstr "crikeywindow#Borrar" +msgstr "Borrar" #: plugins/crop/crop.C:143 msgid "Crop & Position" @@ -12583,7 +12583,7 @@ msgstr "pluma" #: plugins/sketcher/sketcherwindow.C:859 plugins/sketcher/sketcherwindow.C:1234 msgid "sketcherwindow#Del" -msgstr "sketcherwindow#Supr" +msgstr "Borrar" #: plugins/sketcher/sketcherwindow.C:992 msgid "Type" @@ -12923,7 +12923,7 @@ msgstr "Máscara Alpha" #: plugins/timefront/timefront.C:513 msgid "timefront#Square" -msgstr "timefront#Cuadrado" +msgstr "Cuadrado" #: plugins/timefront/timefront.C:599 msgid "Inversion" @@ -13216,7 +13216,7 @@ msgstr "Rellenar" #: plugins/tracer/tracerwindow.C:615 msgid "tracerwindow#Del" -msgstr "tracerwindow#Supr" +msgstr "Borrar" #: plugins/translate/translatewin.C:61 msgid "In X:"