wintv remote control + kernel patch, add codec fileref, amp up OpenEDL, add loadmode...
authorGood Guy <good1.2guy@gmail.com>
Wed, 8 Jan 2020 00:09:19 +0000 (17:09 -0700)
committerGood Guy <good1.2guy@gmail.com>
Wed, 8 Jan 2020 00:09:19 +0000 (17:09 -0700)
100 files changed:
cinelerra-5.1/cinelerra/Makefile
cinelerra-5.1/cinelerra/appearanceprefs.C
cinelerra-5.1/cinelerra/appearanceprefs.h
cinelerra-5.1/cinelerra/appearanceprefs.inc
cinelerra-5.1/cinelerra/assetedit.C
cinelerra-5.1/cinelerra/assetpopup.C
cinelerra-5.1/cinelerra/assetpopup.h
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/clipedls.h
cinelerra-5.1/cinelerra/clippopup.C
cinelerra-5.1/cinelerra/convert.C
cinelerra-5.1/cinelerra/cwindow.C
cinelerra-5.1/cinelerra/cwindow.h
cinelerra-5.1/cinelerra/editpopup.C
cinelerra-5.1/cinelerra/editpopup.h
cinelerra-5.1/cinelerra/editpopup.inc
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/edlsession.C
cinelerra-5.1/cinelerra/file.C
cinelerra-5.1/cinelerra/file.inc
cinelerra-5.1/cinelerra/fileref.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/fileref.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/filexml.h
cinelerra-5.1/cinelerra/loadfile.C
cinelerra-5.1/cinelerra/loadfile.h
cinelerra-5.1/cinelerra/loadmode.C
cinelerra-5.1/cinelerra/loadmode.h
cinelerra-5.1/cinelerra/loadmode.inc
cinelerra-5.1/cinelerra/main.C
cinelerra-5.1/cinelerra/mainindexes.C
cinelerra-5.1/cinelerra/mainindexes.h
cinelerra-5.1/cinelerra/mainundo.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/mwindowgui.C
cinelerra-5.1/cinelerra/mwindowgui.h
cinelerra-5.1/cinelerra/preferences.C
cinelerra-5.1/cinelerra/preferences.h
cinelerra-5.1/cinelerra/proxy.C
cinelerra-5.1/cinelerra/record.C
cinelerra-5.1/cinelerra/record.h
cinelerra-5.1/cinelerra/remotecontrol.C
cinelerra-5.1/cinelerra/remotecontrol.h
cinelerra-5.1/cinelerra/setformat.C
cinelerra-5.1/cinelerra/wintv.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/wintv.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/wintv.inc [new file with mode: 0644]
cinelerra-5.1/configure.ac
cinelerra-5.1/guicast/bcfilebox.C
cinelerra-5.1/guicast/bcmenuitem.C
cinelerra-5.1/guicast/bcmenuitem.h
cinelerra-5.1/guicast/bcmenupopup.C
cinelerra-5.1/guicast/bcmenupopup.h
cinelerra-5.1/plugins/colorbalance/colorbalance.C
cinelerra-5.1/plugins/theme_blond/blondtheme.C
cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_blond_cv/blondcvtheme.C
cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_blue/bluetheme.C
cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_blue_dot/bluedottheme.C
cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_bright/brighttheme.C
cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_cakewalk/cakewalk.C
cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_hulk/hulktheme.C
cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_neophyte/neophyte.C
cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_pinklady/pinkladytheme.C
cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_suv/suv.C
cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_clip.png [new symlink]
cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_fileref.png [new symlink]
cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_nested.png [new symlink]
cinelerra-5.1/plugins/theme_unflat/unflattheme.C
cinelerra-5.1/thirdparty/src/em28xx-input.patch1 [new file with mode: 0644]

index e4f782d..2efc535 100644 (file)
@@ -146,6 +146,7 @@ OBJS := $(OVERLAYS) \
        $(OBJDIR)/file.o \
        $(OBJDIR)/filepng.o \
        $(OBJDIR)/fileppm.o \
+       $(OBJDIR)/fileref.o \
        $(OBJDIR)/filescene.o \
        $(OBJDIR)/filesndfile.o \
        $(OBJDIR)/filetga.o \
@@ -365,6 +366,7 @@ OBJS := $(OVERLAYS) \
        $(OBJDIR)/vwindowgui.o \
        $(OBJDIR)/vwindow.o \
        $(OBJDIR)/wavecache.o \
+       $(OBJDIR)/wintv.o \
        $(OBJDIR)/wwindow.o \
        $(OBJDIR)/zoombar.o \
        $(OBJDIR)/zoompanel.o \
index 086c15d..b3718b7 100644 (file)
@@ -75,9 +75,10 @@ void AppearancePrefs::create_objects()
        int y0 = mwindow->theme->preferencesoptions_y;
        int x = x0, y = y0, x1 = x + xS(100);
 
-       add_subwindow(new BC_Title(x, y, _("Layout:"), LARGEFONT,
+       BC_Title *title;
+       add_subwindow(title = new BC_Title(x, y, _("Layout:"), LARGEFONT,
                resources->text_default));
-       y += ys35;
+       y += title->get_h() + ys10;
        int y1 = y;
 
        ViewTheme *theme;
@@ -114,21 +115,14 @@ void AppearancePrefs::create_objects()
        vicon_color_mode->create_objects();
        y += vicon_color_mode->get_h() + ys5;
        y = bmax(y, y2);        
-
        y += ys10;
        add_subwindow(new BC_Bar(xs5, y, get_w() - xs10));
        y += ys15;
 
-       add_subwindow(new BC_Title(x, y, _("Time Format:"), LARGEFONT,
-               resources->text_default));
-
-       add_subwindow(new BC_Title(x1, y, _("Flags:"), LARGEFONT,
-               resources->text_default));
-
-       y += get_text_height(LARGEFONT) + ys5;
-       y += ys10;
        y1 = y;
-
+       add_subwindow(title = new BC_Title(x, y, _("Time Format:"), LARGEFONT,
+               resources->text_default));
+       y += title->get_h() + ys10;
        add_subwindow(hms = new TimeFormatHMS(pwindow, this,
                pwindow->thread->edl->session->time_format == TIME_HMS,
                x, y));
@@ -153,7 +147,6 @@ void AppearancePrefs::create_objects()
                pwindow->thread->edl->session->time_format == TIME_FEET_FRAMES,
                x, y));
        x += feet->get_w() + xS(15);
-       BC_Title *title;
        add_subwindow(title = new BC_Title(x, y, _("Frames per foot:")));
        x += title->get_w() + margin;
        sprintf(string, "%0.2f", pwindow->thread->edl->session->frames_per_foot);
@@ -164,11 +157,10 @@ void AppearancePrefs::create_objects()
        add_subwindow(seconds = new TimeFormatSeconds(pwindow, this,
                pwindow->thread->edl->session->time_format == TIME_SECONDS,
                x, y));
-       x = x0;
        y += ys35;
-       add_subwindow(new BC_Bar(xs5, y, get_w()/2 - xs30));
-       y += ys15;
-
+       y2 = y;
+       
+       x = x1;  y = y1;
        add_subwindow(new BC_Title(x, y, _("Color:"), LARGEFONT,
                resources->text_default));
        y += ys35;
@@ -177,7 +169,7 @@ void AppearancePrefs::create_objects()
        char hex_color[BCSTRLEN];
        sprintf(hex_color, "%06x", preferences->highlight_inverse);
         add_subwindow(new HighlightInverseColor(pwindow, x, y, hex_color));
-       x2 = x;  x = x0;
+       x2 = x;  x = x1;
        y += ys35;
        add_subwindow(title = new BC_Title(x, y, _("Composer BG Color:")));
        int clr_color = pwindow->thread->edl->session->cwindow_clear_color;
@@ -188,62 +180,82 @@ void AppearancePrefs::create_objects()
        cwdw_bg_color->create_objects();
        y += ys35;
 
-       x = x0;
+       x = x1;
        add_subwindow(title = new BC_Title(x, y, _("YUV color space:")));
        x += title->get_w() + margin;
        add_subwindow(yuv_color_space = new YuvColorSpace(x, y, pwindow));
        yuv_color_space->create_objects();
        y += yuv_color_space->get_h() + ys5;
 
-       x = x0;
+       x = x1;
        add_subwindow(title = new BC_Title(x, y, _("YUV color range:")));
        x += title->get_w() + margin;
        add_subwindow(yuv_color_range = new YuvColorRange(x, y, pwindow));
        yuv_color_range->create_objects();
-       y += yuv_color_range->get_h() + ys5;
+       y += yuv_color_range->get_h() + ys35;
+       if( y2 < y ) y2 = y;
 
-       UseTipWindow *tip_win = new UseTipWindow(pwindow, x1, y1);
-       add_subwindow(tip_win);
-       y1 += tip_win->get_h() + ys5;
-       AutocolorAssets *autocolor_assets = new AutocolorAssets(pwindow, x1, y1);
+       add_subwindow(new BC_Bar(x0, y2, get_w()-x0 - xs30));
+       y += ys15;
+
+       x = x0;  y1 = y;
+       add_subwindow(title = new BC_Title(x, y, _("Warnings:"), LARGEFONT,
+               resources->text_default));
+       y += title->get_h() + ys10;
+       UseWarnIndecies *idx_warn = new UseWarnIndecies(pwindow, x, y);
+       add_subwindow(idx_warn);
+       y += idx_warn->get_h() + ys5;
+       UseWarnVersion *ver_warn = new UseWarnVersion(pwindow, x, y);
+       add_subwindow(ver_warn);
+       y += ver_warn->get_h() + ys5;
+       UseWarnStack *stack_warn = new UseWarnStack(pwindow, x, y);
+       add_subwindow(stack_warn);
+       y += stack_warn->get_h() + ys5;
+       BD_WarnRoot *bdwr_warn = new BD_WarnRoot(pwindow, x, y);
+       add_subwindow(bdwr_warn);
+       y += bdwr_warn->get_h() + ys5;
+
+       x = get_w() / 3 + xs30;
+       y = y1;
+       add_subwindow(title = new BC_Title(x1, y, _("Flags:"), LARGEFONT,
+               resources->text_default));
+       y += title->get_h() + ys10;
+       y1 = y;
+       AutocolorAssets *autocolor_assets = new AutocolorAssets(pwindow, x, y);
        add_subwindow(autocolor_assets);
-       y1 += autocolor_assets->get_h() + ys5;
-       UseWarnIndecies *idx_win = new UseWarnIndecies(pwindow, x1, y1);
-       add_subwindow(idx_win);
-       y1 += idx_win->get_h() + ys5;
-       UseWarnVersion *ver_win = new UseWarnVersion(pwindow, x1, y1);
-       add_subwindow(ver_win);
-       y1 += ver_win->get_h() + ys5;
-       BD_WarnRoot *bdwr_win = new BD_WarnRoot(pwindow, x1, y1);
-       add_subwindow(bdwr_win);
-       y1 += bdwr_win->get_h() + ys5;
-       PopupMenuBtnup *pop_win = new PopupMenuBtnup(pwindow, x1, y1);
+       y += autocolor_assets->get_h() + ys5;
+       PerpetualSession *perpetual = new PerpetualSession(x, y, pwindow);
+       add_subwindow(perpetual);
+       y += perpetual->get_h() + ys5;
+       RectifyAudioToggle *rect_toggle = new RectifyAudioToggle(x, y, pwindow);
+       add_subwindow(rect_toggle);
+       y += rect_toggle->get_h() + ys5;
+       CtrlToggle *ctrl_toggle = new CtrlToggle(x, y, pwindow);
+       add_subwindow(ctrl_toggle);
+       y += ctrl_toggle->get_h() + ys5;
+       ForwardRenderDisplacement *displacement = new ForwardRenderDisplacement(pwindow, x, y);
+       add_subwindow(displacement);
+       y += displacement->get_h() + ys5;
+       UseTipWindow *tip_win = new UseTipWindow(pwindow, x, y);
+       add_subwindow(tip_win);
+       y += tip_win->get_h() + ys5;
+
+       x = 2*get_w() / 3 - xs30;
+       y = y1;
+       add_subwindow(thumbnails = new ViewThumbnails(x, y, pwindow));
+       y += thumbnails->get_h() + ys5;
+       PopupMenuBtnup *pop_win = new PopupMenuBtnup(pwindow, x, y);
        add_subwindow(pop_win);
-       y1 += pop_win->get_h() + ys5;
-       GrabFocusPolicy *grab_input_focus = new GrabFocusPolicy(pwindow, x1, y1);
+       y += pop_win->get_h() + ys5;
+       GrabFocusPolicy *grab_input_focus = new GrabFocusPolicy(pwindow, x, y);
        add_subwindow(grab_input_focus);
-       y1 += grab_input_focus->get_h() + ys5;
-       ActivateFocusPolicy *focus_activate = new ActivateFocusPolicy(pwindow, x1, y1);
+       y += grab_input_focus->get_h() + ys5;
+       ActivateFocusPolicy *focus_activate = new ActivateFocusPolicy(pwindow, x, y);
        add_subwindow(focus_activate);
-       y1 += focus_activate->get_h() + ys5;
-       DeactivateFocusPolicy *focus_deactivate = new DeactivateFocusPolicy(pwindow, x1, y1);
+       y += focus_activate->get_h() + ys5;
+       DeactivateFocusPolicy *focus_deactivate = new DeactivateFocusPolicy(pwindow, x, y);
        add_subwindow(focus_deactivate);
-       y1 += focus_deactivate->get_h() + ys5;
-       ForwardRenderDisplacement *displacement = new ForwardRenderDisplacement(pwindow, x1, y1);
-       add_subwindow(displacement);
-       y1 += displacement->get_h() + ys5;
-       add_subwindow(thumbnails = new ViewThumbnails(x1, y1, pwindow));
-       y1 += thumbnails->get_h() + ys5;
-       PerpetualSession *perpetual = new PerpetualSession(x1, y1, pwindow);
-       add_subwindow(perpetual);
-       y1 += perpetual->get_h() + ys5;
-       CtrlToggle *ctrl_toggle = new CtrlToggle(x1, y1, pwindow);
-       add_subwindow(ctrl_toggle);
-       y1 += ctrl_toggle->get_h() + ys5;
-       RectifyAudioToggle *rect_toggle = new RectifyAudioToggle(x1, y1, pwindow);
-       add_subwindow(rect_toggle);
-       y1 += rect_toggle->get_h() + ys5;
-       if( y < y1 ) y = y1;
+       y += focus_deactivate->get_h() + ys5;
 }
 
 int AppearancePrefs::update(int new_value)
@@ -590,6 +602,19 @@ int UseWarnVersion::handle_event()
        return 1;
 }
 
+UseWarnStack::UseWarnStack(PreferencesWindow *pwindow, int x, int y)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->warn_stack,
+       _("Stack warns if reference not modified"))
+{
+       this->pwindow = pwindow;
+}
+
+int UseWarnStack::handle_event()
+{
+       pwindow->thread->preferences->warn_stack = get_value();
+       return 1;
+}
+
 BD_WarnRoot::BD_WarnRoot(PreferencesWindow *pwindow, int x, int y)
  : BC_CheckBox(x, y, pwindow->thread->preferences->bd_warn_root,
        _("Create Bluray warns if not root"))
index 2099c05..6c2473d 100644 (file)
@@ -255,6 +255,14 @@ public:
        PreferencesWindow *pwindow;
 };
 
+class UseWarnStack : public BC_CheckBox
+{
+public:
+       UseWarnStack(PreferencesWindow *pwindow, int x, int y);
+       int handle_event();
+       PreferencesWindow *pwindow;
+};
+
 class BD_WarnRoot : public BC_CheckBox
 {
 public:
index 644c2bc..6b117a9 100644 (file)
@@ -44,6 +44,7 @@ class ViewViconModeItem;
 class UseTipWindow;
 class UseWarnIndecies;
 class UseWarnVersion;
+class UseWarnStack;
 class BD_WarnRoot;
 class PopupMenuBtnup;
 class GrabFocusPolicy;
index c8ff4a9..6222f1c 100644 (file)
@@ -133,7 +133,7 @@ void AssetEdit::handle_close_event(int result)
 // Omit index status from copy since an index rebuild may have been
 // happening when new_asset was created but not be happening anymore.
                        if( asset ) {
-                               mwindow->remove_asset_from_caches(asset);
+                               mwindow->remove_from_caches(asset);
 //printf("AssetEdit::handle_close_event %d %f\n", __LINE__, asset->get_frame_rate());
                                asset->copy_from(changed_params, 0);
 //printf("AssetEdit::handle_close_event %d %d %d\n", __LINE__, changed_params->bits, asset->bits);
@@ -159,7 +159,7 @@ void AssetEdit::handle_close_event(int result)
                                        indexable->path);
                                remove_file(index_filename);
                                indexable->index_state->index_status = INDEX_NOTTESTED;
-                               mwindow->mainindexes->add_next_asset(0, indexable);
+                               mwindow->mainindexes->add_indexable(indexable);
                                mwindow->mainindexes->start_build();
                        }
                        mwindow->gui->unlock_window();
index f436454..51e3f88 100644 (file)
@@ -146,6 +146,28 @@ int AssetPopup::update()
        format->update();
        int proxy = mwindow->edl->session->awindow_folder == AW_PROXY_FOLDER ? 1 : 0;
        gui->collect_assets(proxy);
+       int enable_open = 0;
+       int assets_total = mwindow->session->drag_assets->size();
+       Indexable *idxbl = !assets_total ? 0 :
+               mwindow->session->drag_assets->get(0);
+       if( idxbl ) {
+               if( idxbl->is_asset ) {
+                       Asset *asset = (Asset *)idxbl;
+                       if( asset->format == FILE_REF )
+                               enable_open = 1;
+               }
+               else
+                       enable_open = 1;
+       }
+       open_edl->set_enabled(enable_open);
+       int enable_close = mwindow->stack.size() > 0 ? 1 : 0;
+       close_edl->set_enabled(enable_close);
+       int enable_clip = 0;
+       for( int i=0; !enable_clip && i<assets_total; ++i ) {
+               Indexable *idxbl = mwindow->session->drag_assets->get(i);
+               if( !idxbl->is_asset ) enable_clip = 1;
+       }
+       to_clip->set_enabled(enable_clip);
        return 0;
 }
 
@@ -195,16 +217,36 @@ 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");
+       if( !assets_total ) return 1;
+       popup->unlock_window();
+       EDL *edl = 0;
+       Indexable *idxbl = mwindow->session->drag_assets->get(0);
+       if( idxbl->is_asset ) {
+               Asset *asset = (Asset *)idxbl;
+               if( asset->format == FILE_REF ) {
+                       FileXML xml_file;
+                       const char *filename = asset->path;
+                       if( xml_file.read_from_file(filename, 1) ) {
+                               eprintf(_("Error: unable to open:\n  %s"), filename);
+                               return 1;
+                       }
+                       edl = new EDL;
+                       edl->create_objects();
+                       if( edl->load_xml(&xml_file, LOAD_ALL) ) {
+                               eprintf(_("Error: unable to load:\n  %s"), filename);
+                               edl->remove_user();
+                               return 1;
+                       }
+               }
+       }
+       else {
+               edl = (EDL *)idxbl;
        }
+       if( edl )
+               mwindow->stack_push(edl, idxbl);
+       else
+               eprintf(_("media is not EDL:\n%s"), idxbl->path);
+       popup->lock_window("AssetPopupOpenEDL::handle_event");
        return 1;
 }
 
@@ -484,10 +526,6 @@ AssetListMenu::AssetListMenu(MWindow *mwindow, AWindowGUI *gui)
 
 AssetListMenu::~AssetListMenu()
 {
-       if( !shots_displayed ) {
-               delete asset_snapshot;
-               delete asset_grabshot;
-       }
 }
 
 void AssetListMenu::create_objects()
@@ -519,7 +557,7 @@ void AssetListMenu::create_objects()
        grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("jpeg"), GRABSHOT_JPEG));
        grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("tiff"), GRABSHOT_TIFF));
        grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("ppm"),  GRABSHOT_PPM));
-       update_titles(shots_displayed = 1);
+       update_titles(1);
 }
 
 AssetPopupLoadFile::AssetPopupLoadFile(MWindow *mwindow, AWindowGUI *gui)
@@ -542,16 +580,10 @@ int AssetPopupLoadFile::handle_event()
 void AssetListMenu::update_titles(int shots)
 {
        format->update();
-       if( shots && !shots_displayed ) {
-               shots_displayed = 1;
-               add_item(asset_snapshot);
-               add_item(asset_grabshot);
-       }
-       else if( !shots && shots_displayed ) {
-               shots_displayed = 0;
-               remove_item(asset_snapshot);
-               remove_item(asset_grabshot);
-       }
+       int enable_close = mwindow->stack.size() > 0 ? 1 : 0;
+       close_edl->set_enabled(enable_close);
+       asset_snapshot->set_enabled(shots);
+       asset_grabshot->set_enabled(shots);
 }
 
 AssetListCopy::AssetListCopy(MWindow *mwindow, AWindowGUI *gui)
@@ -755,7 +787,8 @@ void AssetPasteDialog::handle_done_event(int result)
        MWindow *mwindow = paste->mwindow;
        mwindow->interrupt_indexes();
        mwindow->gui->lock_window("AssetPasteDialog::handle_done_event");
-       result = mwindow->load_filenames(&path_list, LOADMODE_RESOURCESONLY, 0);
+       result = mwindow->load_filenames(&path_list,
+               LOADMODE_RESOURCESONLY, LOADMODE_EDL_CLIP, 0);
        mwindow->gui->unlock_window();
        path_list.remove_all_objects();
        mwindow->save_backup();
index 5620e56..c948e0e 100644 (file)
@@ -273,7 +273,6 @@ public:
        AssetSnapshot *asset_snapshot;
        AssetGrabshot *asset_grabshot;
        AssetSelectUsed *select_used;
-       int shots_displayed;
 };
 
 class AssetPopupLoadFile : public BC_MenuItem
index 9cf4999..cabbbc0 100644 (file)
@@ -2068,6 +2068,10 @@ void AWindowGUI::update_asset_list()
                if( !exists ) {
                        AssetPicon *picon = new AssetPicon(mwindow,
                                this, current);
+                       if( current->format == FILE_REF ) {
+                               int color = picon->get_color();
+                               picon->set_color(color ^ 0x5599CC);
+                       }
                        new_assets.append(picon);
                }
        }
index e64a0c9..ee2467a 100644 (file)
@@ -1,6 +1,5 @@
-#ifndef NESTEDEDLS_H
-#define NESTEDEDLS_H
-
+#ifndef __CLIP_EDLS_H__
+#define __CLIP_EDLS_H__
 
 #include "arraylist.h"
 #include "edl.inc"
index cbff1d7..65eebb6 100644 (file)
@@ -129,6 +129,12 @@ int ClipPopup::update()
 {
        format->update();
        gui->collect_assets();
+       EDL *clip = !mwindow->session->drag_clips->size() ? 0 :
+               mwindow->session->drag_clips->get(0);
+       int enable_open = clip ? 1 : 0;
+       open_edl->set_enabled(enable_open);
+       int enable_close = mwindow->stack.size() > 0 ? 1 : 0;
+       close_edl->set_enabled(enable_close);
        return 0;
 }
 
@@ -416,6 +422,8 @@ void ClipListMenu::create_objects()
 void ClipListMenu::update()
 {
        format->update();
+       int enable_close = mwindow->stack.size() > 0 ? 1 : 0;
+       close_edl->set_enabled(enable_close);
 }
 
 
@@ -456,7 +464,7 @@ int ClipPopupOpenEDL::handle_event()
        if( clips_total ) {
                popup->unlock_window();
                EDL *clip = mwindow->session->drag_clips->values[0];
-               mwindow->stack_push(clip);
+               mwindow->stack_push(clip, 0);
                popup->lock_window("ClipPopupOpenEDL::handle_event");
        }
        return 1;
index 18791e1..80694ef 100644 (file)
@@ -259,7 +259,7 @@ int ConvertRender::add_original(EDL *edl, Indexable *idxbl)
 // render not needed if can use copy
                                if( ret == FILE_OK ) {
                                        if( match_format(file.asset) ) {
-                                               mwindow->mainindexes->add_next_asset(0, convert);
+                                               mwindow->mainindexes->add_indexable(convert);
                                                mwindow->mainindexes->start_build();
                                                needed = 0;
                                        }
@@ -512,7 +512,7 @@ void ConvertRender::create_copy(int i)
        RenderPackage *package = dispatcher.get_package(0);
        if( !renderer.render_package(package) ) {
                Asset *asset = mwindow->edl->assets->update(needed_copy);
-               mwindow->mainindexes->add_next_asset(0, asset);
+               mwindow->mainindexes->add_indexable(asset);
                mwindow->mainindexes->start_build();
        }
        else
index 0ba2530..bb8df6e 100644 (file)
@@ -50,6 +50,7 @@
 #include "trackcanvas.h"
 #include "tracks.h"
 #include "transportque.h"
+#include "wintv.h"
 
 #include <unistd.h>
 
@@ -273,7 +274,10 @@ CWindowRemoteHandler::
 CWindowRemoteHandler(RemoteControl *remote_control)
  : RemoteHandler(remote_control->gui, RED)
 {
+       this->remote_control = remote_control;
+       this->mwindow = remote_control->mwindow_gui->mwindow;
        last_key = -1;
+       key = -1;
 }
 
 CWindowRemoteHandler::
@@ -281,24 +285,27 @@ CWindowRemoteHandler::
 {
 }
 
+int CWindowRemoteHandler::process_key(int key)
+{
+       return remote_process_key(remote_control, key);
+}
+
 int CWindowRemoteHandler::remote_process_key(RemoteControl *remote_control, int key)
 {
-       MWindowGUI *mwindow_gui = remote_control->mwindow_gui;
-       EDL *edl = mwindow_gui->mwindow->edl;
+       EDL *edl = mwindow->edl;
        if( !edl ) return 0;
-       PlayTransport *transport = mwindow_gui->mbuttons->transport;
+       PlayTransport *transport = mwindow->gui->mbuttons->transport;
        if( !transport->get_edl() ) return 0;
        PlaybackEngine *engine = transport->engine;
        double position = engine->get_tracking_position();
        double length = edl->tracks->total_length();
-       int next_command = -1, lastkey = last_key;
-       last_key = key;
+       int next_command = -1;
 
        switch( key ) {
        case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8':
-               if( lastkey == 'e' ) {
-                       mwindow_gui->mwindow->select_asset(key-'1', 1);
+               if( last_key == 'e' ) {
+                       mwindow->select_asset(key-'1', 1);
                        break;
                } // fall through
        case '0': case '9':
@@ -316,18 +323,18 @@ int CWindowRemoteHandler::remote_process_key(RemoteControl *remote_control, int
        case KPRECD:  next_command = SLOW_REWIND;       break;
        case KPAUSE:  next_command = SLOW_FWD;          break;
        case ' ':  next_command = NORMAL_FWD;           break;
-       case 'a':  gui->tile_windows(0);                return 1;
-       case 'b':  gui->tile_windows(1);                return 1;
-       case 'c':  gui->tile_windows(2);                return 1;
+       case 'a':  remote_control->gui->tile_windows(0);  return 1;
+       case 'b':  remote_control->gui->tile_windows(1);  return 1;
+       case 'c':  remote_control->gui->tile_windows(2);  return 1;
 #ifdef HAVE_DVB
        case 'd':
-               mwindow_gui->channel_info->toggle_scan();
+               mwindow->gui->channel_info->toggle_scan();
                return 1;
 #endif
        case 'e':
                break;
        case 'f': {
-               CWindowCanvas *canvas = mwindow_gui->mwindow->cwindow->gui->canvas;
+               CWindowCanvas *canvas = mwindow->cwindow->gui->canvas;
                int on = canvas->get_fullscreen() ? 0 : 1;
                canvas->Canvas::set_fullscreen(on, 0);
                return 1; }
index 2eaad4b..643c34b 100644 (file)
@@ -82,12 +82,15 @@ public:
 
 class CWindowRemoteHandler : public RemoteHandler
 {
-       int last_key;
 public:
-       int remote_process_key(RemoteControl *remote_control, int key);
-
        CWindowRemoteHandler(RemoteControl *remote_control);
        ~CWindowRemoteHandler();
+       int process_key(int key);
+       int remote_process_key(RemoteControl *remote_control, int key);
+
+       int key, last_key;
+       RemoteControl *remote_control;
+       MWindow *mwindow;
 };
 
 #endif
index 11299c2..e0c40b9 100644 (file)
@@ -29,6 +29,7 @@
 #include "edl.h"
 #include "edlsession.h"
 #include "file.h"
+#include "filexml.h"
 #include "keys.h"
 #include "language.h"
 #include "localsession.h"
@@ -55,6 +56,7 @@ EditPopup::EditPopup(MWindow *mwindow, MWindowGUI *gui)
        plugin = 0;
        pluginset = 0;
        position = 0;
+       open_edl = 0;
 }
 
 EditPopup::~EditPopup()
@@ -63,6 +65,7 @@ EditPopup::~EditPopup()
 
 void EditPopup::create_objects()
 {
+       add_item(open_edl = new EditPopupOpenEDL(mwindow, this));
        add_item(new EditPopupClearSelect(mwindow, this));
        add_item(new EditPopupCopy(mwindow, this));
        add_item(new EditPopupCut(mwindow, this));
@@ -83,9 +86,60 @@ int EditPopup::activate_menu(Track *track, Edit *edit,
        this->pluginset = pluginset;
        this->plugin = plugin;
        this->position = position;
+       int enable = !edit ? 0 :
+               edit->nested_edl ? 1 :
+               !edit->asset ? 0 :
+               edit->asset->format == FILE_REF ? 1 : 0;
+       open_edl->set_enabled(enable);
        return BC_PopupMenu::activate_menu();
 }
 
+EditPopupOpenEDL::EditPopupOpenEDL(MWindow *mwindow, EditPopup *popup)
+ : BC_MenuItem(_("Open EDL"))
+{
+       this->mwindow = mwindow;
+       this->popup = popup;
+       set_ctrl(1);
+       set_shift(1);
+}
+
+int EditPopupOpenEDL::handle_event()
+{
+       Edit *edit = popup->edit;
+       if( !edit ) return 1;
+       EDL *edl = 0;
+       Indexable *idxbl = 0;
+       if( edit->asset && edit->asset->format == FILE_REF ) {
+               FileXML xml_file;
+               const char *filename = edit->asset->path;
+               if( xml_file.read_from_file(filename, 1) ) {
+                       eprintf(_("Error: unable to open:\n  %s"), filename);
+                       return 1;
+               }
+               edl = new EDL;
+               edl->create_objects();
+               if( edl->load_xml(&xml_file, LOAD_ALL) ) {
+                       eprintf(_("Error: unable to load:\n  %s"), filename);
+                       edl->remove_user();
+                       return 1;
+               }
+               idxbl = edit->asset;
+       }
+       else if( edit->nested_edl ) {
+               edl = edit->nested_edl;
+               edl->add_user();
+               idxbl = edl;
+       }
+       else {
+               char edit_title[BCTEXTLEN];
+               edit->get_title(edit_title);
+               eprintf(_("Edit is not EDL: %s"), edit_title);
+               return 1;
+       }
+       mwindow->stack_push(edl, idxbl);
+       return 1;
+}
+
 EditPopupClearSelect::EditPopupClearSelect(MWindow *mwindow, EditPopup *popup)
  : BC_MenuItem(_("Clear Select"),_("Ctrl-Shift-A"),'A')
 {
index ce16db6..d8987a7 100644 (file)
@@ -50,6 +50,17 @@ public:
        Plugin *plugin;
        PluginSet *pluginset;
        double position;
+       EditPopupOpenEDL *open_edl;
+};
+
+class EditPopupOpenEDL : public BC_MenuItem
+{
+public:
+       EditPopupOpenEDL(MWindow *mwindow, EditPopup *popup);
+       int handle_event();
+
+       MWindow *mwindow;
+       EditPopup *popup;
 };
 
 class EditPopupClearSelect : public BC_MenuItem
index c5c69ea..969625e 100644 (file)
@@ -23,6 +23,7 @@
 #define __EDITPOPUP_INC__
 
 class EditPopup;
+class EditPopupOpenEDL;
 class EditPopupClearSelect;
 class EditPopupCopy;
 class EditPopupCopyPack;
index b46a410..c4576c9 100644 (file)
@@ -212,7 +212,7 @@ int EDL::read_xml(FileXML *file, uint32_t load_flags)
                                file->tag.title_is("/CLIP_EDL") ||
                                file->tag.title_is("/NESTED_EDL") ||
                                file->tag.title_is("/VWINDOW_EDL") ) {
-                               result = 1;
+                               break;
                        }
                        else
                        if( file->tag.title_is("CLIPBOARD") ) {
index 5aef800..90a5319 100644 (file)
@@ -501,7 +501,7 @@ int EDLSession::save_defaults(BC_Hash *defaults)
 void EDLSession::boundaries()
 {
        Workarounds::clamp(audio_tracks, 0, (int)BC_INFINITY);
-       Workarounds::clamp(audio_channels, 1, MAXCHANNELS - 1);
+       Workarounds::clamp(audio_channels, 0, MAXCHANNELS - 1);
        Workarounds::clamp(sample_rate, 1, 1000000);
        Workarounds::clamp(video_tracks, 0, (int)BC_INFINITY);
        Workarounds::clamp(video_channels, 1, MAXCHANNELS - 1);
index fe5b9f5..1fec188 100644 (file)
@@ -54,6 +54,7 @@
 #undef HAVE_STDLIB_H // automake conflict
 #include "filepng.h"
 #include "fileppm.h"
+#include "fileref.h"
 #include "filescene.h"
 #include "filesndfile.h"
 #include "filetga.h"
@@ -577,6 +578,9 @@ int File::open_file(Preferences *preferences,
                file = new FileDV(this->asset, this);
                break;
 #endif
+       case FILE_REF:
+               file = new FileREF(this->asset, this);
+               break;
 // try plugins
        default:
                return 1;
@@ -1213,6 +1217,7 @@ int File::strtoformat(const char *format)
        if( !strcasecmp(format, _(RAWDV_NAME)) ) return FILE_RAWDV;
        if( !strcasecmp(format, _(FFMPEG_NAME)) ) return FILE_FFMPEG;
        if( !strcasecmp(format, _(DBASE_NAME)) ) return FILE_DB;
+       if( !strcasecmp(format, _(REF_NAME)) ) return FILE_REF;
 
        return 0;
 }
@@ -1253,6 +1258,7 @@ const char* File::formattostr(int format)
        case FILE_RAWDV:        return _(RAWDV_NAME);
        case FILE_FFMPEG:       return _(FFMPEG_NAME);
        case FILE_DB:           return _(DBASE_NAME);
+       case FILE_REF:          return _(REF_NAME);
        }
        return _("Unknown");
 }
@@ -1344,6 +1350,7 @@ int File::get_best_colormodel(Asset *asset, int driver)
        case FILE_DB:           return FileDB::get_best_colormodel(asset, driver);
 #endif
        case FILE_FFMPEG:       return FileFFMPEG::get_best_colormodel(asset, driver);
+       case FILE_REF:          return FileREF::get_best_colormodel(asset, driver);
        }
 
        return BC_RGB888;
@@ -1478,6 +1485,7 @@ const char* File::get_tag(int format)
        case FILE_VMPEG:        return "m2v";
        case FILE_WAV:          return "wav";
        case FILE_FFMPEG:       return "ffmpg";
+       case FILE_REF:          return "ref";
        }
        return 0;
 }
@@ -1515,6 +1523,7 @@ const char* File::get_prefix(int format)
        case FILE_CR2_LIST:     return "CR2_LIST";
        case FILE_GIF_LIST:     return "GIF_LIST";
        case FILE_DB:           return "DB";
+       case FILE_REF:          return "REF";
        }
        return _("UNKNOWN");
 }
index 3d5f07a..748ce06 100644 (file)
@@ -89,6 +89,7 @@
 #define FILE_DB                 37
 #define FILE_PPM                38
 #define FILE_PPM_LIST           39
+#define FILE_REF                40
 
 // For formats supported by plugins, the format number is the plugin number in the
 // plugin list ORed with 0x8000.
@@ -124,6 +125,7 @@ N_("TGA Sequence")
 N_("TIFF")
 N_("TIFF Sequence")
 N_("Unknown sound")
+N_("Reference to EDL")
 #endif
 
 #define AC3_NAME               "AC3"
@@ -160,6 +162,7 @@ N_("Unknown sound")
 #define TIFF_NAME              "TIFF"
 #define VMPEG_NAME             "MPEG Video"    // For encoding only
 #define WAV_NAME               "Microsoft WAV"
+#define REF_NAME               "Reference EDL"
 
 #define BITSLINEAR8    8
 #define BITSLINEAR16   16
diff --git a/cinelerra-5.1/cinelerra/fileref.C b/cinelerra-5.1/cinelerra/fileref.C
new file mode 100644 (file)
index 0000000..ab8ecd7
--- /dev/null
@@ -0,0 +1,214 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2020 William Morrow
+ *
+ * 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 "asset.h"
+#include "arender.h"
+#include "cache.h"
+#include "filebase.h"
+#include "file.h"
+#include "fileref.h"
+#include "language.h"
+#include "mainerror.h"
+#include "renderengine.h"
+#include "samples.h"
+#include "edlsession.h"
+#include "tracks.h"
+#include "transportque.h"
+#include "vframe.h"
+#include "vrender.h"
+#include "filexml.h"
+
+
+FileREF::FileREF(Asset *asset, File *file)
+ : FileBase(asset, file)
+{
+       is_open = 0;
+       audio_position = 0;
+       video_position = 0;
+       samples_position = -1;
+       samples_length = -1;
+       channel = 0;
+       layer = 0;
+       ref = 0;
+       command = 0;
+       render_engine = 0;
+       acache = 0;
+       vcache = 0;
+       temp = 0;
+       for( int i=0; i<MAX_CHANNELS; ++i ) samples[i] = 0;
+}
+
+FileREF::~FileREF()
+{
+       close_file();
+}
+
+int FileREF::open_file(int rd, int wr)
+{
+       if( is_open ) return 1;
+       if(wr) {
+               eprintf(_("Reference files cant be created by rendering\n"));
+               return 1;
+       }
+       if(rd) {
+               FileXML file_xml;
+               if( file_xml.read_from_file(asset->path) ) return 1;
+//             file_xml.check_version();
+               if( ref ) ref->remove_user();
+               ref = new EDL;
+               ref->create_objects();
+               ref->load_xml(&file_xml, LOAD_ALL);
+               command = new TransportCommand();
+               command->reset();
+               command->get_edl()->copy_all(ref);
+               command->command = NORMAL_FWD;
+               command->change_type = CHANGE_ALL;
+               command->realtime = 0;
+               samples_position = -1;
+               samples_length = -1;
+               audio_position = 0;
+               render_engine = new RenderEngine(0, file->preferences, 0, 0);
+               render_engine->set_acache(acache = new CICache(file->preferences));
+               render_engine->set_vcache(vcache = new CICache(file->preferences));
+               render_engine->arm_command(command);
+               is_open = 1;
+       }
+       return 0;
+}
+
+int FileREF::close_file()
+{
+       if( !is_open ) return 1;
+       if( ref ) ref->remove_user();
+       ref = 0;
+       delete render_engine;  render_engine = 0;
+       delete command;  command = 0;
+       delete acache;   acache = 0;
+       delete vcache;   vcache = 0;
+       delete temp;     temp = 0;
+       for( int i=0; i<MAX_CHANNELS; ++i ) {
+               delete samples[i];  samples[i] = 0;
+       }
+       audio_position = 0;
+       video_position = 0;
+       channel = 0;
+       samples_position = -1;
+       samples_length = -1;
+       layer = 0;
+       is_open = 0;
+       return 0;
+}
+
+int64_t FileREF::get_video_position()
+{
+       return video_position;
+}
+
+int64_t FileREF::get_audio_position()
+{
+       return audio_position;
+}
+
+int FileREF::set_video_position(int64_t pos)
+{
+       this->video_position = pos;
+       return 0;
+}
+int FileREF::set_layer(int layer)
+{
+       this->layer = layer;
+       return 0;
+}
+
+int FileREF::set_audio_position(int64_t pos)
+{
+       this->audio_position = pos;
+       return 0;
+}
+int FileREF::set_channel(int channel)
+{
+       this->channel = channel;
+       return 0;
+}
+
+int FileREF::read_samples(double *buffer, int64_t len)
+{
+       int result = len > 0 ? 0 : 1;
+       if( !render_engine || !render_engine->arender ) result = 1;
+       if( !result ) {
+               if( samples_length != len ) {
+                       samples_length = -1;
+                       for( int i=0; i<MAX_CHANNELS; ++i ) {
+                               delete samples[i];  samples[i] = 0;
+                       }
+               }
+               if( samples_length < 0 ) {
+                       samples_length = len;
+                       int ch = 0, channels = asset->channels;
+                       while( ch < channels ) samples[ch++] = new Samples(samples_length);
+                       samples_position = -1;
+               }
+               if( samples_position != audio_position ) {
+                       result = render_engine->arender->process_buffer(samples, len, audio_position);
+                       samples_position = audio_position;
+               }
+       }
+       Samples *cbfr = samples[channel];
+       double *data = cbfr ? cbfr->get_data() : 0;
+       if( !data ) result = 1;
+       int64_t sz = len*(sizeof(*buffer));
+       if( !result )
+               memcpy(buffer, data, sz);
+       else
+               memset(buffer, 0, sz);
+       return result;
+}
+
+int FileREF::read_frame(VFrame *frame)
+{
+        int result = render_engine && render_engine->vrender ? 0 : 1;
+       EDLSession *render_session = render_engine->get_edl()->session;
+       int color_model = render_session->color_model;
+       int out_w = render_session->output_w, out_h = render_session->output_h;
+       VFrame *vframe = frame;
+       if( color_model != frame->get_color_model() ||
+           out_w != frame->get_w() || out_h != frame->get_h() ) {
+               VFrame::get_temp(temp, out_w, out_h, color_model);
+               vframe = temp;
+       }
+       if( !result )
+               result = render_engine->vrender->process_buffer(vframe, video_position++, 0);
+       if( vframe != frame )
+               frame->transfer_from(vframe);
+       return result;
+}
+
+int FileREF::colormodel_supported(int colormodel)
+{
+       return colormodel;
+}
+
+
+int FileREF::get_best_colormodel(Asset *asset, int driver)
+{
+       return BC_RGBA_FLOAT;
+}
+
diff --git a/cinelerra-5.1/cinelerra/fileref.h b/cinelerra-5.1/cinelerra/fileref.h
new file mode 100644 (file)
index 0000000..7f4d67f
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef __FILEREF_H__
+#define __FILEREF_H__
+/*
+ * CINELERRA
+ * Copyright (C) 2020 William Morrow
+ *
+ * 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 "asset.inc"
+#include "cache.inc"
+#include "filebase.h"
+#include "file.inc"
+#include "renderengine.inc"
+#include "samples.inc"
+#include "transportque.inc"
+#include "vframe.inc"
+
+
+class FileREF : public FileBase
+{
+public:
+       FileREF(Asset *asset, File *file);
+       ~FileREF();
+
+       int open_file(int rd, int wr);
+       int64_t get_video_position();
+       int64_t get_audio_position();
+       int set_video_position(int64_t pos);
+       int set_layer(int layer);
+       int set_audio_position(int64_t pos);
+       int set_channel(int channel);
+       int read_samples(double *buffer, int64_t len);
+       int read_frame(VFrame *frame);
+       int colormodel_supported(int colormodel);
+       static int get_best_colormodel(Asset *asset, int driver);
+       int close_file();
+
+       EDL *ref;
+       TransportCommand *command;
+       Samples *samples[MAX_CHANNELS];
+       int64_t samples_position, samples_length;
+       int64_t audio_position;
+       int64_t video_position;
+       int channel, layer;
+       RenderEngine *render_engine;
+       CICache *acache, *vcache;
+       VFrame *temp;
+       int is_open;
+};
+
+#endif
index 602a411..eb0b514 100644 (file)
@@ -27,6 +27,7 @@
 #include <limits.h>
 
 #include "arraylist.h"
+#include "bcwindowbase.inc"
 #include "mutex.h"
 #include "keyframe.inc"
 #include "filexml.inc"
@@ -165,7 +166,7 @@ public:
        long output_length;
        char *output;
        char left_delimiter, right_delimiter;
-       char filename[MAX_TITLE];
+       char filename[BCTEXTLEN];
        static const char *xml_header;
        static const int xml_header_size;
 };
index c65a9a2..1b86ae7 100644 (file)
@@ -79,6 +79,8 @@ LoadFileThread::LoadFileThread(MWindow *mwindow, Load *load)
        this->mwindow = mwindow;
        this->load = load;
        this->window = 0;
+       load_mode = LOADMODE_REPLACE;
+       edl_mode = LOADMODE_EDL_CLIP;
 }
 
 LoadFileThread::~LoadFileThread()
@@ -92,7 +94,8 @@ BC_Window* LoadFileThread::new_gui()
 
        sprintf(default_path, "~");
        mwindow->defaults->get("DEFAULT_LOADPATH", default_path);
-       load_mode = mwindow->defaults->get("LOAD_MODE", LOADMODE_REPLACE);
+       load_mode = mwindow->defaults->get("LOAD_MODE", load_mode);
+       edl_mode = mwindow->defaults->get("LOAD_EDL_MODE", edl_mode);
 
        mwindow->gui->lock_window("LoadFileThread::new_gui");
        window = new LoadFileWindow(mwindow, this, default_path);
@@ -113,10 +116,9 @@ void LoadFileThread::handle_done_event(int result)
 
 void LoadFileThread::load_apply()
 {
-       mwindow->defaults->update("DEFAULT_LOADPATH",
-               window->get_submitted_path());
-       mwindow->defaults->update("LOAD_MODE",
-               load_mode);
+       mwindow->defaults->update("DEFAULT_LOADPATH", window->get_submitted_path());
+       mwindow->defaults->update("LOAD_MODE", load_mode);
+       mwindow->defaults->update("LOAD_EDL_MODE", edl_mode);
 
        ArrayList<char*> path_list;
        path_list.set_array_delete();
@@ -137,7 +139,7 @@ void LoadFileThread::load_apply()
 
        mwindow->interrupt_indexes();
        mwindow->gui->lock_window("LoadFileThread::run");
-       mwindow->load_filenames(&path_list, load_mode, 0);
+       mwindow->load_filenames(&path_list, load_mode, edl_mode, 0);
        mwindow->gui->mainmenu->add_load(path_list.values[0]);
        mwindow->gui->unlock_window();
        path_list.remove_all_objects();
@@ -146,7 +148,8 @@ void LoadFileThread::load_apply()
 
        mwindow->restart_brender();
 
-       if(load_mode == LOADMODE_REPLACE || load_mode == LOADMODE_REPLACE_CONCATENATE)
+       if( load_mode == LOADMODE_REPLACE ||
+           load_mode == LOADMODE_REPLACE_CONCATENATE )
                mwindow->session->changes_made = 0;
        else
                mwindow->session->changes_made = 1;
@@ -185,9 +188,13 @@ void LoadFileWindow::create_objects()
 
        int x = get_w() / 2 - LoadMode::calculate_w(this, mwindow->theme) / 2;
        int y = get_y_margin();
-       loadmode = new LoadMode(mwindow, this, x, y, &thread->load_mode, 0, 1);
+       loadmode = new LoadMode(mwindow, this, x, y,
+               &thread->load_mode, &thread->edl_mode, 0, 1);
        loadmode->create_objects();
-       add_subwindow(load_file_apply = new LoadFileApply(this));
+       const char *apply =  _("Apply");
+       x = 3*get_w()/4 - BC_GenericButton::calculate_w(this, apply)/2;
+       y = get_h() - BC_CancelButton::calculate_h() - yS(16);
+       add_subwindow(load_file_apply = new LoadFileApply(this, x, y, apply));
 
        show_window(1);
        unlock_window();
@@ -201,19 +208,18 @@ int LoadFileWindow::resize_event(int w, int h)
        int x = w / 2 - LoadMode::calculate_w(this, mwindow->theme) / 2;
        int y = get_y_margin();
        loadmode->reposition_window(x, y);
-       x = (w - BC_GenericButton::calculate_w(this, _("Apply")))/2;
-       y = h - BC_GenericButton::calculate_h() - 15;
+       const char *apply =  load_file_apply->get_text();
+       x = 3*get_w()/4 - BC_GenericButton::calculate_w(this, apply)/2;
+       y = get_h() - BC_CancelButton::calculate_h() - yS(16);
        load_file_apply->reposition_window(x, y);
        flush();
        return 1;
 }
 
 
-LoadFileApply::LoadFileApply(LoadFileWindow *load_file_window)
- : BC_GenericButton( (load_file_window->get_w() -
-               BC_GenericButton::calculate_w(load_file_window, _("Apply")))/2,
-       load_file_window->get_h() - BC_GenericButton::calculate_h() - 15,
-       _("Apply"))
+LoadFileApply::LoadFileApply(LoadFileWindow *load_file_window,
+               int x, int y, const char *text)
+ : BC_GenericButton(x, y, text)
 {
        this->load_file_window = load_file_window;
 }
@@ -261,6 +267,7 @@ int LoadPrevious::handle_event()
        path_list.set_array_delete();
        char *out_path;
        int load_mode = mwindow->defaults->get("LOAD_MODE", LOADMODE_REPLACE);
+       int edl_mode = mwindow->defaults->get("LOAD_EDL_MODE", LOADMODE_EDL_CLIP);
 
        path_list.append(out_path = new char[strlen(path) + 1]);
        strcpy(out_path, path);
@@ -270,6 +277,7 @@ int LoadPrevious::handle_event()
        path_list.remove_all_objects();
 
        mwindow->defaults->update("LOAD_MODE", load_mode);
+       mwindow->defaults->update("LOAD_EDL_MODE", edl_mode);
        mwindow->save_backup();
        mwindow->session->changes_made = 0;
        return 1;
index ef1a8e0..ba0974a 100644 (file)
@@ -63,7 +63,7 @@ public:
 
        MWindow *mwindow;
        Load *load;
-       int load_mode;
+       int load_mode, edl_mode;
        LoadFileWindow *window;
 };
 
@@ -115,7 +115,8 @@ public:
 class LoadFileApply : public BC_GenericButton
 {
 public:
-       LoadFileApply(LoadFileWindow *load_file_window);
+       LoadFileApply(LoadFileWindow *load_file_window,
+               int x, int y, const char *text);
        int handle_event();
        LoadFileWindow *load_file_window;
 };
index 04b35ee..04193b2 100644 (file)
@@ -25,6 +25,9 @@
 #include "mwindow.h"
 #include "theme.h"
 
+#define LOADMODE_LOAD_TEXT _("Load strategy:")
+#define LOADMODE_EDL_TEXT _("EDL strategy:")
+
 // Must match macros
 static const char *mode_images[] =
 {
@@ -35,7 +38,9 @@ static const char *mode_images[] =
        "loadmode_cat",
        "loadmode_paste",
        "loadmode_resource",
-       "loadmode_nested"
+       "loadmode_edl_clip",
+       "loadmode_edl_nested",
+       "loadmode_edl_fileref",
 };
 
 static const char *mode_text[] =
@@ -47,7 +52,9 @@ static const char *mode_text[] =
        N_("Concatenate to existing tracks"),
        N_("Paste over selection/at insertion point"),
        N_("Create new resources only"),
-       N_("Nest sequence")
+       N_("EDL as Clip"),
+       N_("EDL as Nested"),
+       N_("EDL as Reference"),
 };
 
 
@@ -58,53 +65,52 @@ LoadModeItem::LoadModeItem(const char *text, int value)
 }
 
 
-LoadModeToggle::LoadModeToggle(int x, int y, LoadMode *window,
-               int value, const char *images, const char *tooltip)
- : BC_Toggle(x, y, window->mwindow->theme->get_image_set(images),
-               *window->output == value)
+LoadModeToggle::LoadModeToggle(int x, int y, LoadMode *window, int id,
+               int *output, const char *images, const char *tooltip)
+ : BC_Toggle(x, y, window->mwindow->theme->get_image_set(images), *output)
 {
        this->window = window;
-       this->value = value;
+       this->id = id;
+       this->output = output;
        set_tooltip(tooltip);
 }
 
 int LoadModeToggle::handle_event()
 {
-       *window->output = value;
+       *output = id;
        window->update();
        return 1;
 }
 
 
 
-LoadMode::LoadMode(MWindow *mwindow,
-               BC_WindowBase *window, int x, int y, int *output,
-               int use_nothing, int use_nested, int line_wrap)
+LoadMode::LoadMode(MWindow *mwindow, BC_WindowBase *window,
+               int x, int y, int *load_mode, int *edl_mode,
+               int use_nothing, int line_wrap)
 {
        this->mwindow = mwindow;
        this->window = window;
        this->x = x;
        this->y = y;
-       this->output = output;
+       this->load_mode = load_mode;
+       this->edl_mode = edl_mode;
        this->use_nothing = use_nothing;
-       this->use_nested = use_nested;
        this->line_wrap = line_wrap;
        for( int i=0; i<TOTAL_LOADMODES; ++i ) mode[i] = 0;
+       load_title = 0;
+       edl_title = 0;
 }
 
 LoadMode::~LoadMode()
 {
-       delete title;
-       delete textbox;
-       delete listbox;
        load_modes.remove_all_objects();
        for( int i=0; i<TOTAL_LOADMODES; ++i ) delete mode[i];
 }
 
-const char *LoadMode::mode_to_text()
+const char *LoadMode::mode_to_text(int mode)
 {
        for( int i=0; i<load_modes.total; ++i ) {
-               if( load_modes[i]->value == *output )
+               if( load_modes[i]->value == mode )
                        return load_modes[i]->get_text();
        }
        return _("Unknown");
@@ -115,16 +121,29 @@ void LoadMode::load_mode_geometry(BC_WindowBase *gui, Theme *theme,
                int *pw, int *ph)
 {
        int pad = 5;
-       const char *title_text = _("Insertion strategy:");
-       int mw = BC_Title::calculate_w(gui, title_text);
-       int mh = BC_Title::calculate_h(gui, title_text);
+       const char *load_text = LOADMODE_LOAD_TEXT;
+       int mw = BC_Title::calculate_w(gui, load_text);
+       int mh = BC_Title::calculate_h(gui, load_text);
        int ix = mw + 2*pad, iy = 0, x1 = ix;
        int ww = theme->loadmode_w + 24;
        if( mw < ww ) mw = ww;
 
        for( int i=0; i<TOTAL_LOADMODES; ++i ) {
-               if( i == LOADMODE_NOTHING && !use_nothing) continue;
-               if( i == LOADMODE_NESTED && !use_nested) continue;
+               switch( i ) {
+               case LOADMODE_NOTHING:
+                       if( !use_nothing) continue;
+                       break;
+               case LOADMODE_EDL_CLIP:
+               case LOADMODE_EDL_NESTED:
+               case LOADMODE_EDL_FILEREF:
+                       if( !use_nested ) continue;
+                       if( iy ) break;
+                       ix = 0;  iy = mh + pad;
+                       const char *edl_text = LOADMODE_EDL_TEXT;
+                       ix += bmax(BC_Title::calculate_w(gui, load_text),
+                                  BC_Title::calculate_w(gui, edl_text)) + 2*pad;
+                       break;
+               }
                int text_line, w, h, toggle_x, toggle_y;
                int text_x, text_y, text_w, text_h;
                BC_Toggle::calculate_extents(gui,
@@ -164,16 +183,31 @@ int LoadMode::calculate_h(BC_WindowBase *gui, Theme *theme,
 void LoadMode::create_objects()
 {
        int pad = 5;
-       const char *title_text = _("Insertion strategy:");
-       window->add_subwindow(title = new BC_Title(x, y, title_text));
-       int mw = title->get_w(), mh = title->get_h();
+       load_title = new BC_Title(x, y, LOADMODE_LOAD_TEXT);
+       window->add_subwindow(load_title);
+       int mw = load_title->get_w(), mh = load_title->get_h();
        int ix = mw + 2*pad, iy = 0, x1 = ix;
        int ww = mwindow->theme->loadmode_w + 24;
        if( mw < ww ) mw = ww;
 
        for( int i=0; i<TOTAL_LOADMODES; ++i ) {
-               if( i == LOADMODE_NOTHING && !use_nothing) continue;
-               if( i == LOADMODE_NESTED && !use_nested) continue;
+               int *mode_set = load_mode;
+               switch( i ) {
+               case LOADMODE_NOTHING:
+                       if( !use_nothing) continue;
+                       break;
+               case LOADMODE_EDL_CLIP:
+               case LOADMODE_EDL_NESTED:
+               case LOADMODE_EDL_FILEREF:
+                       if( !edl_mode ) continue;
+                       mode_set = edl_mode;
+                       if( iy ) break;
+                       ix = 0;  iy = mh + pad;
+                       edl_title = new BC_Title(x+ix, y+iy, LOADMODE_EDL_TEXT);
+                       window->add_subwindow(edl_title);
+                       ix += bmax(load_title->get_w(), edl_title->get_w()) + 2*pad;
+                       break;
+               }
                load_modes.append(new LoadModeItem(_(mode_text[i]), i));
                int text_line, w, h, toggle_x, toggle_y;
                int text_x, text_y, text_w, text_h;
@@ -182,8 +216,8 @@ void LoadMode::create_objects()
                        &text_line, &w, &h, &toggle_x, &toggle_y,
                        &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
                if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
-               mode[i] = new LoadModeToggle(x+ix, y+iy, this,
-                       i, mode_images[i], _(mode_text[i]));
+               mode[i] = new LoadModeToggle(x+ix, y+iy, this, i,
+                       mode_set, mode_images[i], _(mode_text[i]));
                window->add_subwindow(mode[i]);
                if( (ix+=w) > mw ) mw = ix;
                if( (h+=iy) > mh ) mh = h;
@@ -191,7 +225,7 @@ void LoadMode::create_objects()
        }
 
        ix = 0;  iy = mh+pad;
-       const char *mode_text = mode_to_text();
+       const char *mode_text = mode_to_text(*load_mode);
        textbox = new BC_TextBox(x+ix, y+iy,
                mwindow->theme->loadmode_w, 1, mode_text);
        window->add_subwindow(textbox);
@@ -199,21 +233,34 @@ void LoadMode::create_objects()
        listbox = new LoadModeListBox(window, this, x+ix, y+iy);
        window->add_subwindow(listbox);
        mh = iy + textbox->get_h();
+       update();
 }
 
 int LoadMode::reposition_window(int x, int y)
 {
        this->x = x;  this->y = y;
-       title->reposition_window(x, y);
-       int mw = title->get_w(), mh = title->get_h();
-       int pad = 5;
+       load_title->reposition_window(x, y);
+       int mw = load_title->get_w(), mh = load_title->get_h();
+       int pad = xS(5);
        int ix = mw + 2*pad, iy = 0, x1 = ix;
-       int ww = mwindow->theme->loadmode_w + 24;
+       int ww = mwindow->theme->loadmode_w + xS(24);
        if( mw < ww ) mw = ww;
 
        for( int i=0; i<TOTAL_LOADMODES; ++i ) {
-               if( i == LOADMODE_NOTHING && !use_nothing) continue;
-               if( i == LOADMODE_NESTED && !use_nested) continue;
+               switch( i ) {
+               case LOADMODE_NOTHING:
+                       if( !use_nothing) continue;
+                       break;
+               case LOADMODE_EDL_CLIP:
+               case LOADMODE_EDL_NESTED:
+               case LOADMODE_EDL_FILEREF:
+                       if( !edl_mode ) continue;
+                       if( iy ) break;
+                       ix = 0;  iy = mh + pad;
+                       edl_title->reposition_window(x+ix, y+iy);
+                       ix += bmax(load_title->get_w(), edl_title->get_w()) + 2*pad;
+                       break;
+               }
                int text_line, w, h, toggle_x, toggle_y;
                int text_x, text_y, text_w, text_h;
                BC_Toggle::calculate_extents(window,
@@ -238,7 +285,7 @@ int LoadMode::get_h()
 {
        int result = 0;
        load_mode_geometry(window, mwindow->theme,
-                       use_nothing, use_nested, line_wrap, 0, &result);
+                       use_nothing, edl_mode!=0, line_wrap, 0, &result);
        return result;
 }
 
@@ -256,9 +303,18 @@ void LoadMode::update()
 {
        for( int i=0; i<TOTAL_LOADMODES; ++i ) {
                if( !mode[i] ) continue;
-               mode[i]->set_value(*output == i);
+               int v = 0;
+               if( *load_mode == i ) v = 1;
+               if( edl_mode && *edl_mode == i ) v = 1;
+               mode[i]->set_value(v);
        }
-       textbox->update(mode_to_text());
+       for( int k=0; k<load_modes.total; ++k ) {
+               int i = load_modes[k]->value, v = 0;
+               if( *load_mode == i ) v = 1;
+               if( edl_mode && *edl_mode == i ) v = 1;
+               load_modes[k]->set_selected(v);
+       }
+       textbox->update(mode_to_text(*load_mode));
 }
 
 int LoadMode::set_line_wrap(int v)
@@ -270,7 +326,7 @@ int LoadMode::set_line_wrap(int v)
 
 LoadModeListBox::LoadModeListBox(BC_WindowBase *window, LoadMode *loadmode,
                int x, int y)
- : BC_ListBox(x, y, loadmode->mwindow->theme->loadmode_w, 150, LISTBOX_TEXT,
+ : BC_ListBox(x, y, loadmode->mwindow->theme->loadmode_w, yS(150), LISTBOX_TEXT,
        (ArrayList<BC_ListBoxItem *>*)&loadmode->load_modes, 0, 0, 1, 0, 1)
 {
        this->window = window;
@@ -284,10 +340,13 @@ LoadModeListBox::~LoadModeListBox()
 int LoadModeListBox::handle_event()
 {
        LoadModeItem *item = (LoadModeItem *)get_selection(0, 0);
-       if( item ) {
-               *(loadmode->output) = item->value;
-               loadmode->update();
-       }
+       if( !item ) return 1;
+       int mode = item->value;
+       if( mode < LOADMODE_EDL_CLIP )
+               *loadmode->load_mode = mode;
+       else if( loadmode->edl_mode )
+               *loadmode->edl_mode = mode;
+       loadmode->update();
        return 1;
 }
 
index 2f358fc..61009f4 100644 (file)
@@ -37,19 +37,19 @@ public:
 class LoadModeToggle : public BC_Toggle
 {
 public:
-       LoadModeToggle(int x, int y, LoadMode *window,
-               int value, const char *images, const char *tooltip);
+       LoadModeToggle(int x, int y, LoadMode *window, int value,
+               int *output, const char *images, const char *tooltip);
        int handle_event();
        LoadMode *window;
-       int value;
+       int id, *output;
 };
 
 class LoadMode
 {
 public:
-       LoadMode(MWindow *mwindow,
-               BC_WindowBase *window, int x, int y, int *output,
-               int use_nothing=1, int use_nested=0, int line_wrap=0);
+       LoadMode(MWindow *mwindow, BC_WindowBase *window,
+               int x, int y, int *load_mode, int *edl_mode=0,
+               int use_nothing=1, int line_wrap=0);
        ~LoadMode();
        void create_objects();
        int reposition_window(int x, int y);
@@ -64,17 +64,17 @@ public:
        int get_x();
        int get_y();
 
-       const char *mode_to_text();
+       const char *mode_to_text(int mode);
        void update();
        int set_line_wrap(int v);
 
-       BC_Title *title;
+       BC_Title *load_title, *edl_title;
        BC_TextBox *textbox;
        LoadModeListBox *listbox;
        MWindow *mwindow;
        BC_WindowBase *window;
-       int x, y, *output;
-       int use_nothing, use_nested, line_wrap;
+       int x, y, *load_mode, *edl_mode;
+       int use_nothing, line_wrap;
        LoadModeToggle *mode[TOTAL_LOADMODES];
        ArrayList<LoadModeItem*> load_modes;
 };
index d0b7aae..e53fc3e 100644 (file)
@@ -32,6 +32,7 @@ class LoadModeListBox;
 
 // Load modes for loading files, importing recordings, importing effects
 // Be sure to change mode_images in LoadMode::create_objects if you change this.
+// insertion modes
 #define LOADMODE_NOTHING 0
 #define LOADMODE_REPLACE 1
 #define LOADMODE_REPLACE_CONCATENATE 2
@@ -39,7 +40,10 @@ class LoadModeListBox;
 #define LOADMODE_CONCATENATE 4
 #define LOADMODE_PASTE 5
 #define LOADMODE_RESOURCESONLY 6
-#define LOADMODE_NESTED 7
-#define TOTAL_LOADMODES 8
+// edl load modes
+#define LOADMODE_EDL_CLIP 7
+#define LOADMODE_EDL_NESTED 8
+#define LOADMODE_EDL_FILEREF 9
+#define TOTAL_LOADMODES 10
 
 #endif
index 4b04a11..42207c5 100644 (file)
@@ -106,7 +106,8 @@ public:
 //PRINT_TRACE
                mwindow->gui->lock_window("main");
 //PRINT_TRACE
-               mwindow->load_filenames(filenames, LOADMODE_REPLACE);
+               mwindow->load_filenames(filenames,
+                       LOADMODE_REPLACE, LOADMODE_EDL_CLIP);
 //PRINT_TRACE
                if( filenames->size() == 1 )
                        mwindow->gui->mainmenu->add_load(filenames->get(0));
index 05812bb..1cdf922 100644 (file)
@@ -67,9 +67,9 @@ MainIndexes::~MainIndexes()
        delete index_lock;
 }
 
-void MainIndexes::add_next_asset(File *file, Indexable *indexable)
+void MainIndexes::add_indexable(Indexable *indexable)
 {
-       next_lock->lock("MainIndexes::add_next_asset");
+       next_lock->lock("MainIndexes::add_indexable");
 
 SET_TRACE
 // Test current asset
index 810dcd8..070a5fe 100644 (file)
@@ -39,7 +39,7 @@ public:
        MainIndexes(MWindow *mwindow);
        ~MainIndexes();
 
-       void add_next_asset(File *file, Indexable *indexable);
+       void add_indexable(Indexable *indexable);
 
        void start_loop();
        void stop_loop();
index ba9b6c3..520bc2e 100644 (file)
@@ -267,11 +267,11 @@ int MainUndo::load_from_undo(FileXML *file, uint32_t load_flags)
        }
        mwindow->edl->load_xml(file, load_flags);
        for( Asset *asset=mwindow->edl->assets->first; asset; asset=asset->next ) {
-               mwindow->mainindexes->add_next_asset(0, asset);
+               mwindow->mainindexes->add_indexable(asset);
        }
        for( int i=0; i<mwindow->edl->nested_edls.size(); ++i ) {
                EDL *nested_edl = mwindow->edl->nested_edls[i];
-               mwindow->mainindexes->add_next_asset(0, nested_edl);
+               mwindow->mainindexes->add_indexable(nested_edl);
        }
        mwindow->mainindexes->start_build();
        mwindow->update_plugin_guis(1);
index 75e3bb1..78bc2be 100644 (file)
 #include "vwindowgui.h"
 #include "vwindow.h"
 #include "wavecache.h"
+#include "wintv.h"
 #include "wwindow.h"
 #include "zoombar.h"
 #include "zwindow.h"
@@ -242,6 +243,7 @@ MWindow::MWindow()
        speed_edl = 0;
        beeper = 0;
        shuttle = 0;
+       wintv = 0;
        mixers_align = 0;
 }
 
@@ -265,6 +267,9 @@ MWindow::~MWindow()
        delete create_bd;       create_bd = 0;
        delete create_dvd;      create_dvd = 0;
        delete shuttle;         shuttle = 0;
+#ifdef HAVE_WINTV
+       delete wintv;           wintv = 0;
+#endif
        delete batch_render;    batch_render = 0;
        delete convert_render;  convert_render = 0;
        delete render;          render = 0;
@@ -1579,6 +1584,7 @@ void MWindow::init_exportedl()
        exportedl = new ExportEDL(this);
 }
 
+
 void MWindow::init_shuttle()
 {
 #ifdef HAVE_SHUTTLE
@@ -1594,6 +1600,15 @@ void MWindow::init_shuttle()
        }
 #endif
 }
+void MWindow::init_wintv()
+{
+#ifdef HAVE_WINTV
+       wintv = WinTV::probe(this);
+       if( wintv )
+               wintv->start();
+#endif
+}
+
 
 void MWindow::init_brender()
 {
@@ -1912,14 +1927,11 @@ void Beeper::tone(double freq, double secs, double gain)
 
 
 int MWindow::load_filenames(ArrayList<char*> *filenames,
-       int load_mode,
-       int update_filename)
+               int load_mode, int edl_mode, int update_filename)
 {
        ArrayList<EDL*> new_edls;
        ArrayList<Asset*> new_assets;
        ArrayList<File*> new_files;
-       const int debug = 0;
-if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 //     save_defaults();
        gui->start_hourglass();
@@ -1929,11 +1941,9 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
        gui->unlock_window();
        stop_playback(1);
        gui->lock_window("MWindow::load_filenames 0");
-
-if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
        undo_before();
 
-
+const int debug = 0;
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 // Define new_edls and new_assets to load
@@ -1944,12 +1954,11 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                File *new_file = new File;
                Asset *new_asset = new Asset(filenames->get(i));
                EDL *new_edl = new EDL;
-               char string[BCTEXTLEN];
-
                new_edl->create_objects();
                new_edl->copy_session(edl, -1);
                new_file->set_program(edl->session->program_no);
 
+               char string[BCTEXTLEN];
                sprintf(string, _("Loading %s"), new_asset->path);
                gui->show_message(string);
 
@@ -1958,43 +1967,40 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                result = 1;
                switch( ftype ) {
 // Convert media file to EDL
-               case FILE_OK:
+               case FILE_OK: {
 // Warn about odd image dimensions
                        if( new_asset->video_data &&
                            ((new_asset->width % 2) || (new_asset->height % 2)) ) {
-                               char string[BCTEXTLEN];
-                               sprintf(string, _("%s's resolution is %dx%d.\n"
+                               eprintf(_("%s's resolution is %dx%d.\n"
                                        "Images with odd dimensions may not decode properly."),
                                        new_asset->path, new_asset->width, new_asset->height);
-                               MainError::show_error(string);
                        }
 
                        if( new_asset->program >= 0 &&
                            edl->session->program_no != new_asset->program ) {
-                               char string[BCTEXTLEN];
-                               sprintf(string, _("%s's index was built for program number %d\n"
+                               eprintf(_("%s's index was built for program number %d\n"
                                        "Playback preference is %d.\n  Using program %d."),
                                        new_asset->path, new_asset->program,
                                        edl->session->program_no, new_asset->program);
-                               MainError::show_error(string);
                        }
 
-                       if( load_mode != LOADMODE_RESOURCESONLY ) {
-                               RecordLabels *labels = edl->session->label_cells ?
-                                       new RecordLabels(new_file) : 0;
-                               asset_to_edl(new_edl, new_asset, labels);
-                               new_edls.append(new_edl);
-                               new_edl->add_user();
-                               delete labels;
-                       }
-                       else {
+                       if( load_mode == LOADMODE_RESOURCESONLY ) {
                                new_assets.append(new_asset);
                                new_asset->add_user();
+                               result = 0;
+                               break;
                        }
 
-// Set filename to nothing for assets since save EDL would overwrite them.
+                       RecordLabels *labels = edl->session->label_cells ?
+                               new RecordLabels(new_file) : 0;
+                       asset_to_edl(new_edl, new_asset, labels);
+                       new_edls.append(new_edl);
+                       new_edl->add_user();
+                       delete labels;
+
                        if( load_mode == LOADMODE_REPLACE ||
                            load_mode == LOADMODE_REPLACE_CONCATENATE ) {
+// Set filename to nothing for assets since save EDL would overwrite them.
                                set_filename("");
 // Reset timeline position
                                for( int i=0; i<TOTAL_PANES; ++i ) {
@@ -2002,16 +2008,15 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                        new_edl->local_session->track_start[i] = 0;
                                }
                        }
-
                        result = 0;
-                       break;
+                       break; }
 
-// File not found
-               case FILE_NOT_FOUND:
+               case FILE_NOT_FOUND: {
+                       eprintf(_("Failed to open %s"), new_asset->path);
                        sprintf(string, _("Failed to open %s"), new_asset->path);
                        gui->show_message(string, theme->message_error);
                        gui->update_default_message();
-                       break;
+                       break; }
 
 // Unknown format
                case FILE_UNRECOGNIZED_CODEC: {
@@ -2038,11 +2043,6 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 // Prompt user
                        if( result ) {
-                               char string[BCTEXTLEN];
-                               FileSystem fs;
-                               fs.extract_name(string, new_asset->path);
-
-                               strcat(string, _("'s format couldn't be determined."));
                                new_asset->audio_data = 1;
                                new_asset->format = FILE_PCM;
                                new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
@@ -2052,6 +2052,9 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                new_asset->signed_ = defaults->get("SIGNED_", 1);
                                new_asset->header = defaults->get("HEADER", 0);
 
+                               FileSystem fs;
+                               fs.extract_name(string, new_asset->path);
+                               strcat(string, _("'s format couldn't be determined."));
                                FileFormat fwindow(this);
                                fwindow.create_objects(new_asset, string);
                                result = fwindow.run_window();
@@ -2064,7 +2067,6 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                defaults->update("HEADER", new_asset->header);
                                save_defaults();
                        }
-
 // Append to list
                        if( !result ) {
 // Recalculate length
@@ -2085,14 +2087,15 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                        new_asset->add_user();
                                }
                        }
-                       else {
-                               result = 1;
-                       }
                        break; }
 
                case FILE_IS_XML: {
                        FileXML xml_file;
-                       xml_file.read_from_file(filenames->get(i));
+                       const char *filename = filenames->get(i);
+                       if( xml_file.read_from_file(filename, 1) ) {
+                               eprintf(_("Error: unable to open:\n  %s"), filename);
+                               break;
+                       }
                        const char *cin_version = 0;
                        while( !xml_file.read_tag() ) {
                                if( xml_file.tag.title_is("EDL") ) {
@@ -2102,61 +2105,75 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                        }
                        xml_file.rewind();
                        if( !cin_version ) {
-                               eprintf(_("XML file %s\n not from cinelerra."),filenames->get(i));
+                               eprintf(_("XML file %s\n not from cinelerra."),filename);
                                char string[BCTEXTLEN];
-                               sprintf(string,_("Unknown %s"), filenames->get(i));
+                               sprintf(string,_("Unknown %s"), filename);
                                gui->show_message(string);
-                               result = 1;
                                break;
                        }
                        if( strcmp(cin_version, CINELERRA_VERSION) &&
                            strcmp(cin_version, "Unify") &&
                            strcmp(cin_version, "5.1") ) {
-                               char string[BCTEXTLEN];
-                               snprintf(string, sizeof(string),
-                                        _("Warning: XML from cinelerra version %s\n"
+                               eprintf(_("Warning: XML from cinelerra version %s\n"
                                        "Session data may be incompatible."), cin_version);
-                               show_warning(&preferences->warn_version, string);
                        }
-                       if( load_mode == LOADMODE_NESTED ) {
-// Load temporary EDL for nesting.
-                               EDL *nested_edl = new EDL;
-                               nested_edl->create_objects();
-                               nested_edl->load_xml(&xml_file, LOAD_ALL);
-                               int groups = nested_edl->regroup(session->group_number);
-                               session->group_number += groups;
-                               new_edl->create_nested(nested_edl);
-                               new_edl->set_path(filenames->get(i));
-                               nested_edl->Garbage::remove_user();
+                       if( new_edl->load_xml(&xml_file, LOAD_ALL) ) {
+                               eprintf(_("Error: unable to load:\n  %s"), filename);
+                               break;
                        }
-                       else {
-// Load EDL for pasting
-                               new_edl->load_xml(&xml_file, LOAD_ALL);
-                               int groups = new_edl->regroup(session->group_number);
-                               session->group_number += groups;
-                               test_plugins(new_edl, filenames->get(i));
-
-                               if( load_mode == LOADMODE_REPLACE ||
-                                   load_mode == LOADMODE_REPLACE_CONCATENATE ) {
-                                       strcpy(session->filename, filenames->get(i));
-                                       strcpy(new_edl->local_session->clip_title,
-                                               filenames->get(i));
-                                       if(update_filename)
-                                               set_filename(new_edl->local_session->clip_title);
-                               }
-                               else if( load_mode == LOADMODE_RESOURCESONLY ) {
-                                       strcpy(new_edl->local_session->clip_title,
-                                               filenames->get(i));
-                                       struct stat st;
-                                       time_t t = !stat(filenames->get(i),&st) ?
-                                               st.st_mtime : time(&t);
-                                       ctime_r(&t, new_edl->local_session->clip_notes);
+                       test_plugins(new_edl, filename);
+                       int groups = new_edl->regroup(session->group_number);
+                       session->group_number += groups;
+                       switch( edl_mode ) {
+                       case LOADMODE_EDL_CLIP: {
+                               sprintf(new_edl->local_session->clip_title, _("Clip %d"),
+                                       session->clip_number++);
+                               char string[BCSTRLEN];
+                               time_t t;  time(&t);
+                               ctime_r(&t, string);
+                               snprintf(new_edl->local_session->clip_notes,
+                                       sizeof(new_edl->local_session->clip_notes),
+                                       +("%sFrom: %s"), string, filename);
+                               switch( load_mode ) {
+                               case LOADMODE_REPLACE:
+                               case LOADMODE_REPLACE_CONCATENATE:
+                                       strcpy(session->filename, filename);
+                                       if( update_filename ) set_filename(filename);
+                                       break;
                                }
+                               result = 0;
+                               break; }
+                       case LOADMODE_EDL_NESTED: {
+                                EDL *nested_edl = new EDL;
+                               nested_edl->create_objects();
+                               nested_edl->copy_session(edl, -1);
+                                nested_edl->create_nested(new_edl);
+                                nested_edl->set_path(filename);
+                                new_edl->remove_user();
+                               new_edl = nested_edl;
+                               result = 0;
+                               break; }
+                       case LOADMODE_EDL_FILEREF: {
+                               result = create_ref(new_asset, new_edl);
+                               if( result ) break;
+                               new_assets.append(new_asset);
+                               new_asset->add_user();
+                               new_edl->remove_user();
+                               new_edl = new EDL;
+                               new_edl->create_objects();
+                               new_edl->copy_session(edl, -1);
+                               asset_to_edl(new_edl, new_asset);
+                               delete new_file;
+                               new_file = new File;
+                               result = new_file->open_file(preferences, new_asset, 1, 0);
+                               break; }
                        }
-
-                       new_edls.append(new_edl);
-                       new_edl->add_user();
-                       result = 0;
+                       if( !result ) {
+                               new_edls.append(new_edl);
+                               new_edl->add_user();
+                       }
+                       else
+                               eprintf(_("Error: Unable to load xml:\n  %s"), new_asset->path);
                        break; }
                }
 
@@ -2169,21 +2186,18 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
-
        if(!result) {
                gui->reset_default_message();
                gui->default_message();
        }
 
-
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 // Paste them.
 // Don't back up here.
        if( new_edls.size() ) {
 // For pasting, clear the active region
-               if( load_mode == LOADMODE_PASTE ||
-                   load_mode == LOADMODE_NESTED ) {
+               if( load_mode == LOADMODE_PASTE ) {
                        double start = edl->local_session->get_selectionstart();
                        double end = edl->local_session->get_selectionend();
                        if(!EQUIV(start, end))
@@ -2198,10 +2212,15 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                edl->session->autos_follow_edits,
                                0); // overwrite
                }
-               else if( load_mode == LOADMODE_NEW_TRACKS )
+               else if( load_mode == LOADMODE_NEW_TRACKS &&
+                        edl_mode != LOADMODE_EDL_CLIP )
                        paste_edls(&new_edls, load_mode, 0, -1, 0, 0, 0, 0);
-               else
+               else if( load_mode != LOADMODE_RESOURCESONLY ||
+                        edl_mode == LOADMODE_EDL_CLIP )
                        paste_edls(&new_edls, load_mode, 0, -1, 1, 1, 1, 0);
+               else
+                       paste_edls(&new_edls, LOADMODE_NOTHING, 0, -1, 0, 0, 0, 0);
+
        }
 
 // Add new assets to EDL and schedule assets for index building.
@@ -2209,7 +2228,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
        for( int i=0; i<new_edls.size(); ++i ) {
                EDL *new_edl = new_edls[i];
                for( int j=0; j<new_edl->nested_edls.size(); ++j ) {
-                       mainindexes->add_next_asset(0, new_edl->nested_edls[j]);
+                       mainindexes->add_indexable(new_edl->nested_edls[j]);
                        edl->nested_edls.update_index(new_edl->nested_edls[j]);
                        got_indexes = 1;
                }
@@ -2218,18 +2237,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
        for( int i=0; i<new_assets.size(); ++i ) {
                Asset *new_asset = new_assets[i];
-
-               File *new_file = 0;
-               int got_it = 0;
-               for( int j=0; j<new_files.size(); ++j ) {
-                       new_file = new_files[j];
-                       if( !strcmp(new_file->asset->path, new_asset->path) ) {
-                               got_it = 1;
-                               break;
-                       }
-               }
-
-               mainindexes->add_next_asset(got_it ? new_file : 0, new_asset);
+               mainindexes->add_indexable(new_asset);
                edl->assets->update(new_asset);
                got_indexes = 1;
        }
@@ -2260,10 +2268,10 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                track = track->next;
        }
 
-       // if just opening one new resource in replace mode
-       if( ftype != FILE_IS_XML &&
-           ( load_mode == LOADMODE_REPLACE ||
-             load_mode == LOADMODE_REPLACE_CONCATENATE ) ) {
+       // opening new session
+       if( ( load_mode == LOADMODE_REPLACE ||
+             load_mode == LOADMODE_REPLACE_CONCATENATE ) &&
+           (ftype != FILE_IS_XML || edl_mode != LOADMODE_EDL_CLIP) ) {
                select_asset(0, 0);
                edl->session->proxy_scale = 1;
                edl->session->proxy_disabled_scale = 1;
@@ -2557,7 +2565,7 @@ int MWindow::to_proxy(Asset *asset, int new_scale, int new_use_scaler)
        return !result ? proxy_render.needed_proxies.size() : -1;
 }
 
-void MWindow::test_plugins(EDL *new_edl, char *path)
+void MWindow::test_plugins(EDL *new_edl, const char *path)
 {
        char string[BCTEXTLEN];
 
@@ -2675,6 +2683,7 @@ void MWindow::create_objects(int want_gui,
        strcat(string, "/" FONT_SEARCHPATH);
        BC_Resources::init_fontconfig(string);
        if(debug) PRINT_TRACE
+       init_wintv();
 
 // Default project created here
        init_edl();
@@ -3821,8 +3830,24 @@ void MWindow::update_project(int load_mode)
        if(debug) PRINT_TRACE
 }
 
-void MWindow::stack_push(EDL *new_edl)
+void MWindow::stack_push(EDL *new_edl, Indexable *idxbl)
 {
+       int got_indexes = 0;
+       for( int i=0; i<new_edl->nested_edls.size(); ++i ) {
+               EDL *nested_edl = new_edl->nested_edls[i];
+               mainindexes->add_indexable(nested_edl);
+               edl->nested_edls.update_index(nested_edl);
+               got_indexes = 1;
+       }
+       for( Asset *asset=new_edl->assets->first; asset; asset=asset->next ) {
+               mainindexes->add_indexable(asset);
+               edl->assets->update(asset);
+               got_indexes = 1;
+       }
+// Start examining next batch of index files
+       if( got_indexes )
+               mainindexes->start_build();
+
 // needs gui lock
        gui->lock_window("MWindow::stack_push");
        if( stack.size() < 9 ) {
@@ -3832,6 +3857,15 @@ void MWindow::stack_push(EDL *new_edl)
                item.edl = edl;
                item.new_edl = new_edl;
                item.undo = undo;
+               item.idxbl = idxbl;
+               item.mtime = 0;
+               if( idxbl && idxbl->is_asset ) {
+                       struct stat st;
+                       Asset *asset = (Asset *)idxbl;
+                       if( asset->format == FILE_REF &&
+                           !stat(asset->path, &st) )
+                               item.mtime = st.st_mtime;
+               }
                edl = new_edl;
                edl->add_user();
                strcpy(session->filename, edl->path);
@@ -3848,7 +3882,6 @@ void MWindow::stack_pop()
 // 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 )
@@ -3857,26 +3890,32 @@ void MWindow::stack_pop()
        edl = item.edl;
        delete undo;
        undo = item.undo;
+       Indexable *idxbl = item.idxbl;
+       int64_t mtime = item.mtime;
        stack.remove();
+       if( idxbl ) {
+               gui->unlock_window();
+               remove_from_caches(idxbl);
+               remove_indexfile(idxbl);
+               mainindexes->add_indexable(idxbl);
+               mainindexes->start_build();
+               awindow->gui->async_update_assets();
+               gui->lock_window("MWindow::stack_pop");
+       }
        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;
+       if( mtime && idxbl && idxbl->is_asset ) {
+               struct stat st;
+               Asset *asset = (Asset *)idxbl;
+               if( asset->format == FILE_REF && !stat(asset->path, &st) &&
+                   item.mtime == st.st_mtime ) {
+                       char text[BCTEXTLEN];
+                       snprintf(text, sizeof(text),
+                                _("Warning: Asset not updated: %s"), asset->path);
+                       show_warning(&preferences->warn_stack, text);
+               }
        }
 }
 
@@ -3903,7 +3942,7 @@ void MWindow::clip_to_media()
                EDL *nested = edl->new_nested_edl(clip, path);
                edl->clips.remove(clip);
                clip->remove_user();
-               mainindexes->add_next_asset(0, nested);
+               mainindexes->add_indexable(nested);
        }
        undo_after(_("clip2media"), LOAD_ALL);
        mainindexes->start_build();
@@ -3941,6 +3980,32 @@ void MWindow::media_to_clip()
        awindow->gui->async_update_assets();
 }
 
+int MWindow::create_ref(Asset *asset, EDL *ref)
+{
+       asset->format = FILE_REF;
+       double secs = ref->tracks->total_length();
+       int audio_channels = ref->session->audio_channels;
+       asset->audio_data = audio_channels > 0 ? 1 : 0;
+       asset->channels = audio_channels;
+       asset->sample_rate = ref->session->sample_rate;
+       asset->audio_length = audio_channels > 0 && secs > 0 ?
+                secs * asset->sample_rate : 0;
+       strcpy(asset->acodec, _("reference"));
+
+       int video_layers = ref->session->video_channels;
+       asset->video_data = video_layers > 0 ? 1 : 0;
+       asset->layers = video_layers > 0 ? 1 : 0;
+       asset->actual_width = ref->session->output_w;
+       asset->actual_height = ref->session->output_h;
+       asset->width = asset->actual_width;
+       asset->height = asset->actual_height;
+       asset->frame_rate = ref->session->frame_rate;
+       asset->video_length = video_layers > 0 && secs > 0 ?
+               secs * asset->frame_rate : 0;
+       strcpy(asset->vcodec, _("reference"));
+       return 0;
+}
+
 void MWindow::update_preferences(Preferences *prefs)
 {
        if( prefs != preferences )
@@ -4001,11 +4066,11 @@ void MWindow::rebuild_indices()
                                asset->reset_audio();
                        }
                        asset->reset_video();
-                       remove_asset_from_caches(asset);
+                       remove_from_caches(asset);
 //                     File file; // re-probe the asset
 //                     file.open_file(preferences, asset, 1, 0);
                }
-               mainindexes->add_next_asset(0, indexable);
+               mainindexes->add_indexable(indexable);
        }
 // still in render engine
        sync_parameters(CHANGE_ALL);
@@ -4058,7 +4123,7 @@ void MWindow::load_backup()
        path_list.append(out_path = new char[strlen(backup_path) + 1]);
        strcpy(out_path, backup_path);
 
-       load_filenames(&path_list, LOADMODE_REPLACE, 0);
+       load_filenames(&path_list, LOADMODE_REPLACE, LOADMODE_EDL_CLIP, 0);
        edl->local_session->clip_title[0] = 0;
 // This is unique to backups since the path of the backup is different than the
 // path of the project.
@@ -4267,7 +4332,7 @@ void MWindow::save_project(const char *dir, int save_mode, int overwrite, int re
                gui->lock_window("MWindow::save_project");
                ArrayList<char*> filenames;
                filenames.append(filename);
-               load_filenames(&filenames, LOADMODE_REPLACE);
+               load_filenames(&filenames);
                gui->unlock_window();
        }
 }
@@ -4342,10 +4407,22 @@ void MWindow::reset_caches()
        }
 }
 
-void MWindow::remove_asset_from_caches(Asset *asset)
+void MWindow::remove_from_caches(Indexable *idxbl)
 {
-       frame_cache->remove_asset(asset);
-       wave_cache->remove_asset(asset);
+       frame_cache->remove_item(idxbl);
+       wave_cache->remove_item(idxbl);
+       if( gui->render_engine &&
+           gui->render_engine_id == idxbl->id ) {
+               delete gui->render_engine;
+               gui->render_engine = 0;
+       }
+       if( gui->resource_thread->render_engine_id == idxbl->id ) {
+               gui->resource_thread->render_engine_id = -1;
+               delete gui->resource_thread->render_engine;
+               gui->resource_thread->render_engine = 0;
+       }
+       if( !idxbl->is_asset ) return;
+       Asset *asset = (Asset *)idxbl;
        audio_cache->delete_entry(asset);
        video_cache->delete_entry(asset);
        if( cwindow->playback_engine && cwindow->playback_engine->audio_cache )
@@ -4406,7 +4483,7 @@ void MWindow::remove_assets_from_project(int push_undo, int redraw, int delete_i
 
                for(int i = 0; i < drag_assets->total; i++) {
                        Indexable *indexable = drag_assets->get(i);
-                       if(indexable->is_asset) remove_asset_from_caches((Asset*)indexable);
+                       if(indexable->is_asset) remove_from_caches(indexable);
                }
 
                if( delete_indexes ) {
index a38d057..b7034d8 100644 (file)
 #include "zwindow.inc"
 #include "wwindow.inc"
 #include "wavecache.inc"
+#include "wintv.inc"
 
 #define FONT_SEARCHPATH "fonts"
 
@@ -109,7 +110,9 @@ class StackItem
 {
 public:
        EDL *edl, *new_edl;
+       Indexable *idxbl;
        MainUndo *undo;
+       int64_t mtime;
 };
 
 class Stack : public ArrayList<StackItem>
@@ -170,11 +173,11 @@ public:
 // Total horizontal pixels in timeline
        int get_tracks_width();
 // session stack
-       void stack_push(EDL *edl);
+       void stack_push(EDL *edl, Indexable *idxbl);
        void stack_pop();
-       void forget_nested_edl(EDL *nested);
        void clip_to_media();
        void media_to_clip();
+       int create_ref(Asset *asset, EDL *ref);
 // Show windows
        void show_vwindow();
        void show_awindow();
@@ -269,12 +272,13 @@ public:
        void tile_mixers();
        int load_filenames(ArrayList<char*> *filenames,
                int load_mode = LOADMODE_REPLACE,
+               int edl_mode = LOADMODE_EDL_CLIP,
 // Cause the project filename on the top of the window to be updated.
 // Not wanted for loading backups.
                int update_filename = 1);
 
 // Print out plugins which are referenced in the EDL but not loaded.
-       void test_plugins(EDL *new_edl, char *path);
+       void test_plugins(EDL *new_edl, const char *path);
 
        int interrupt_indexes();  // Stop index building
 
@@ -512,7 +516,7 @@ public:
        void rebuild_indices();
 // Asset removal from caches
        void reset_caches();
-       void remove_asset_from_caches(Asset *asset);
+       void remove_from_caches(Indexable *idxbl);
        void remove_assets_from_project(int push_undo, int redraw, int delete_indexes,
                ArrayList<Indexable*> *drag_assets /* mwindow->session->drag_assets */,
                ArrayList<EDL*> *drag_clips /* mwindow->session->drag_clips */);
@@ -766,6 +770,7 @@ public:
        void init_preferences();
        void init_signals();
        void init_shuttle();
+       void init_wintv();
        void init_theme();
        void init_compositor();
        void init_levelwindow();
@@ -791,6 +796,7 @@ public:
        int screens;
        int in_destructor;
        Shuttle *shuttle;
+       WinTV *wintv;
 };
 
 #endif
index 94d8c4b..f32413a 100644 (file)
@@ -1377,7 +1377,7 @@ if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
        for( int i=0; i<new_assets->total; ++i ) {
                Indexable *indexable = new_assets->get(i);
                if( indexable->is_asset ) {
-                       remove_asset_from_caches((Asset*)indexable);
+                       remove_from_caches(indexable);
                }
                EDL *new_edl = new EDL;
                new_edl->create_objects();
@@ -1551,8 +1551,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
        else
 // Recycle existing tracks of master EDL
        if( load_mode == LOADMODE_CONCATENATE ||
-           load_mode == LOADMODE_PASTE ||
-           load_mode == LOADMODE_NESTED ) {
+           load_mode == LOADMODE_PASTE ) {
                Track *current = first_track ? first_track : edl->tracks->first;
                for( ; current; current=NEXT ) {
                        if( current->record ) {
@@ -1589,13 +1588,15 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
 // Add assets and prepare index files
                for( Asset *new_asset=new_edl->assets->first;
                     new_asset; new_asset=new_asset->next ) {
-                       mainindexes->add_next_asset(0, new_asset);
+                       mainindexes->add_indexable(new_asset);
                }
 // Capture index file status from mainindex test
                edl->update_assets(new_edl);
 //PRINT_TRACE
 // Get starting point of insertion.  Need this to paste labels.
                switch( load_mode ) {
+               case LOADMODE_NOTHING:
+                       continue;
                case LOADMODE_REPLACE:
                        current_position = 0;
                        break;
@@ -1614,7 +1615,6 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
                        break;
 
                case LOADMODE_PASTE:
-               case LOADMODE_NESTED:
                        destination_track = 0;
                        if( i == 0 ) {
                                for( int j=0; j<destination_tracks.total; ++j ) {
@@ -1634,7 +1634,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
                    load_mode != LOADMODE_ASSETSONLY ) {
 // Insert labels
                        if( edit_labels ) {
-                               if( load_mode == LOADMODE_PASTE || load_mode == LOADMODE_NESTED )
+                               if( load_mode == LOADMODE_PASTE )
                                        edl->labels->insert_labels(new_edl->labels,
                                                destination_tracks.total ? paste_position[0] : 0.0,
                                                edl_length, 1);
@@ -1675,7 +1675,6 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
                                                break;
 
                                        case LOADMODE_PASTE:
-                                       case LOADMODE_NESTED:
                                                current_position = paste_position[destination_track];
                                                paste_position[destination_track] += new_track->get_length();
                                                break;
@@ -1702,8 +1701,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
                        }
                }
 
-               if( load_mode == LOADMODE_PASTE ||
-                   load_mode == LOADMODE_NESTED )
+               if( load_mode == LOADMODE_PASTE )
                        current_position += edl_length;
        }
 
index 65ad975..69204d9 100644 (file)
@@ -59,6 +59,7 @@
 #include "record.h"
 #include "recordgui.h"
 #include "renderengine.h"
+#include "remotecontrol.h"
 #include "resourcethread.h"
 #include "samplescroll.h"
 #include "shbtnprefs.h"
@@ -72,6 +73,7 @@
 #include "transitionpopup.h"
 #include "vwindowgui.h"
 #include "vwindow.h"
+#include "wintv.h"
 #include "zoombar.h"
 
 #define PANE_DRAG_MARGIN MAX(mwindow->theme->pane_w, mwindow->theme->pane_h)
@@ -163,8 +165,19 @@ void MWindowGUI::create_objects()
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
        set_icon(mwindow->theme->get_image("mwindow_icon"));
        remote_control = new RemoteControl(this);
-       cwindow_remote_handler = new CWindowRemoteHandler(remote_control);
-       record_remote_handler = new RecordRemoteHandler(remote_control);
+#ifdef HAVE_WINTV
+       WinTV *wintv = mwindow->wintv;
+       if( wintv ) {
+               cwindow_remote_handler = (RemoteHandler*)
+                       new WinTVCWindowHandler(wintv, remote_control);
+               record_remote_handler = (RemoteHandler*)
+                       new WinTVRecordHandler(wintv, remote_control);
+       }
+#endif
+       if( !cwindow_remote_handler ) cwindow_remote_handler =
+               (RemoteHandler*)new CWindowRemoteHandler(remote_control);
+       if( !record_remote_handler  ) record_remote_handler =
+               (RemoteHandler*)new RecordRemoteHandler(remote_control);
        mwindow->reset_android_remote();
 
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
index 4ba7c16..4ac94fe 100644 (file)
@@ -42,7 +42,6 @@
 #include "pluginpopup.inc"
 #include "record.inc"
 #include "remotecontrol.h"
-#include "record.inc"
 #include "renderengine.inc"
 #include "resourcepixmap.h"
 #include "resourcethread.inc"
@@ -56,6 +55,7 @@
 #include "trackpopup.inc"
 #include "trackscroll.inc"
 #include "transitionpopup.inc"
+#include "wintv.inc"
 #include "zoombar.inc"
 
 
@@ -270,8 +270,9 @@ public:
 // remote control
        AndroidControl *android_control;
        RemoteControl *remote_control;
-       CWindowRemoteHandler *cwindow_remote_handler;
-       RecordRemoteHandler *record_remote_handler;
+       WinTV *wintv;
+       RemoteHandler *cwindow_remote_handler;
+       RemoteHandler *record_remote_handler;
 };
 
 #endif
index 02bccb1..30a99ca 100644 (file)
@@ -91,6 +91,7 @@ Preferences::Preferences()
        memset(&use_hw_dev, 0, sizeof(use_hw_dev));
        warn_indexes = 1;
        warn_version = 1;
+       warn_stack = 1;
        bd_warn_root = 1;
        popupmenu_btnup = 1;
        grab_input_focus = 1;
@@ -213,6 +214,7 @@ void Preferences::copy_from(Preferences *that)
        strcpy(use_hw_dev, &that->use_hw_dev[0]);
        warn_indexes = that->warn_indexes;
        warn_version = that->warn_version;
+       warn_stack = that->warn_stack;
        bd_warn_root = that->bd_warn_root;
        popupmenu_btnup = that->popupmenu_btnup;
        grab_input_focus = that->grab_input_focus;
@@ -358,6 +360,7 @@ int Preferences::load_defaults(BC_Hash *defaults)
        defaults->get("USE_HW_DEV", use_hw_dev);
        warn_indexes = defaults->get("WARN_INDEXES", warn_indexes);
        warn_version = defaults->get("WARN_VERSION", warn_version);
+       warn_stack = defaults->get("WARN_STACK", warn_stack);
        bd_warn_root = defaults->get("BD_WARN_ROOT", bd_warn_root);
        popupmenu_btnup = defaults->get("POPUPMENU_BTNUP", popupmenu_btnup);
        grab_input_focus = defaults->get("GRAB_FOCUS", grab_input_focus);
@@ -502,6 +505,7 @@ int Preferences::save_defaults(BC_Hash *defaults)
        defaults->update("USE_HW_DEV", use_hw_dev);
        defaults->update("WARN_INDEXES", warn_indexes);
        defaults->update("WARN_VERSION", warn_version);
+       defaults->update("WARN_STACK", warn_stack);
        defaults->update("BD_WARN_ROOT", bd_warn_root);
        defaults->update("POPUPMENU_BTNUP", popupmenu_btnup);
        defaults->update("GRAB_FOCUS", grab_input_focus);
index bbd4196..3b46f5f 100644 (file)
@@ -118,6 +118,7 @@ public:
 // warning
        int warn_indexes;
        int warn_version;
+       int warn_stack;
        int bd_warn_root;
 // grab input focus on enter notify
        int grab_input_focus;
index 522287b..3165ad0 100644 (file)
@@ -739,7 +739,7 @@ void ProxyClient::process_package(LoadPackage *ptr)
                if( !scale ) scale = 1;
                asset->width = asset->actual_width * scale;
                asset->height = asset->actual_height * scale;
-               mwindow->mainindexes->add_next_asset(0, asset);
+               mwindow->mainindexes->add_indexable(asset);
                mwindow->mainindexes->start_build();
        }
        else
index c788340..c2aab72 100644 (file)
@@ -75,6 +75,7 @@
 #include "tracks.h"
 #include "videoconfig.h"
 #include "videodevice.h"
+#include "wintv.h"
 
 #include <string.h>
 #include <sys/types.h>
@@ -404,7 +405,7 @@ void Record::run()
                        Asset *asset = batch->asset;
                        if( batch->recorded ) {
                                EDL *new_edl = new EDL;
-                               mwindow->remove_asset_from_caches(asset);
+                               mwindow->remove_from_caches(asset);
                                new_edl->create_objects();
                                new_edl->copy_session(mwindow->edl);
                                mwindow->asset_to_edl(new_edl, asset, batch->labels);
@@ -553,7 +554,7 @@ int Record::delete_output_file()
                record_gui->update_batches();
                Asset *asset = batch->asset;
                remove_file(asset->path);
-               mwindow->remove_asset_from_caches(asset);
+               mwindow->remove_from_caches(asset);
                delete_index_file(asset);
                batch->clear_notice();
                record_gui->update_batches();
@@ -1525,6 +1526,7 @@ void Record::update_skimming(int v) {}
 RecordRemoteHandler::RecordRemoteHandler(RemoteControl *remote_control)
  : RemoteHandler(remote_control->gui, GREEN)
 {
+       this->remote_control = remote_control;
 }
 
 RecordRemoteHandler::~RecordRemoteHandler()
@@ -1755,13 +1757,13 @@ void Record::add_key(int ch)
                                BIGFONT, WHITE, BLACK, 0, 3., 2.);
 }
 
-int RecordRemoteHandler::remote_process_key(RemoteControl *remote_control, int key)
+int RecordRemoteHandler::process_key(int key)
 {
        Record *record = remote_control->mwindow_gui->record;
-       return record->remote_process_key(remote_control, key);
+       return record->record_process_key(remote_control, key);
 }
 
-int Record::remote_process_key(RemoteControl *remote_control, int key)
+int Record::record_process_key(RemoteControl *remote_control, int key)
 {
        int ch = key;
 
@@ -1841,6 +1843,83 @@ int Record::remote_process_key(RemoteControl *remote_control, int key)
        return 1;
 }
 
+int Record::wintv_process_code(int code)
+{
+#ifdef HAVE_WINTV
+       WinTV *wintv = (WinTV *)mwindow->gui->cwindow_remote_handler;
+       switch( code ) {
+       case WTV_OK:   break;
+       case WTV_LT:   break;
+       case WTV_UP:   break;
+       case WTV_RT:   break;
+       case WTV_DN:   break;
+       case WTV_HOME: {
+                RecordMonitorCanvas *canvas = record_monitor->window->canvas;
+                int on = canvas->get_fullscreen() ? 0 : 1;
+                canvas->Canvas::set_fullscreen(on, 0);
+                break; }
+       case WTV_BACK: // toggle metering audio
+                set_audio_metering(metering_audio ? 0 : 1);
+                break;
+       case WTV_VOLUP: {
+               double gain = adevice->get_play_gain() * 1.25;
+               set_play_gain(gain);
+               break; }
+       case WTV_VOLDN: {
+               double gain = adevice->get_play_gain() * 0.75;
+               set_play_gain(gain);
+               break; }
+       case WTV_CH_UP:
+                channel_up();
+                break;
+       case WTV_CH_DN:
+                channel_down();
+                break;
+       case WTV_0:
+               if( wintv->last_code == WTV_0 ) {
+                       clear_keybfr();
+                       break;
+               } // fall thru
+       case WTV_1: case WTV_2: case WTV_3: case WTV_4:
+       case WTV_5: case WTV_6: case WTV_7: case WTV_8:
+       case WTV_9: {
+               int ch = code - WTV_0 + '0';
+               add_key(ch);
+               break; }
+       case WTV_TEXT: // add decimal point
+               add_key('.');
+               break;
+       case WTV_CC: // change channel
+               set_channel_name(keybfr);
+               clear_keybfr();
+               break;
+       case WTV_BOX:
+                display_channel_schedule();
+               break;
+       case WTV_START: break;
+       case WTV_REV:   break;
+       case WTV_STOP:  break;
+       case WTV_PLAY:  break;
+       case WTV_FWD:   break;
+       case WTV_END:   break;
+       case WTV_MUTE: // toggle mute audio
+               if( !monitor_audio ) {
+                       set_mute_gain(1);
+                       set_play_gain(play_gain);
+               }
+               set_audio_monitoring(monitor_audio ? 0 : 1);
+               break;
+       case WTV_PREV:
+                display_channel_info();
+                break;
+       default:
+               printf("wintv record: unknown code: %04x\n", code);
+               break;
+       }
+#endif
+       return 0;
+}
+
 #ifdef HAVE_COMMERCIAL
 int Record::start_commercial_capture()
 {
@@ -2078,4 +2157,5 @@ run()
        remote_color(record->status_color);
 }
 
+// HAVE_COMMERCIAL
 #endif
index 76e1bd5..480b332 100644 (file)
@@ -233,7 +233,8 @@ public:
        int commercial_jobs();
        void clear_keybfr();
        void add_key(int ch);
-       int remote_process_key(RemoteControl *remote_control, int key);
+       int record_process_key(RemoteControl *remote_control, int key);
+       int wintv_process_code(int code);
        int spawn(const char *fmt, ...);
        void display_video_text(int x, int y, const char *text, int font,
                int bg_color, int color, int alpha, double secs, double scale);
@@ -360,11 +361,13 @@ public:
 class RecordRemoteHandler : public RemoteHandler
 {
 public:
-       int remote_process_key(RemoteControl *remote_control, int key);
+       int process_key(int key);
        int spawn(const char *fmt, ...);
 
        RecordRemoteHandler(RemoteControl *remote_control);
        ~RecordRemoteHandler();
+
+       RemoteControl *remote_control;
 };
 
 class RecordCutAdsStatus : public Thread
index bb61eb2..de2bc27 100644 (file)
@@ -84,7 +84,7 @@ int RemoteControl::deactivate()
 int RemoteControl::remote_key(int key)
 {
        if( !is_active() ) return 0;
-       return handler->remote_process_key(this, key);
+       return handler->process_key(key);
 }
 
 void RemoteControl::set_color(int color)
@@ -172,8 +172,7 @@ int RemoteGUI::keypress_event()
        return result;
 }
 
-RemoteHandler::
-RemoteHandler(RemoteGUI *gui, int color)
+RemoteHandler::RemoteHandler(RemoteGUI *gui, int color)
 {
        this->gui = gui;
        this->color = color;
index d2b96ed..1a50d99 100644 (file)
@@ -45,7 +45,7 @@ public:
        int color;
 
        void activate() { gui->set_active(this); }
-       virtual int remote_process_key(RemoteControl *remote_control, int key) { return -1; }
+       virtual int process_key(int key) { return -1; }
 
        RemoteHandler(RemoteGUI *gui, int color);
        virtual ~RemoteHandler();
index ba894a8..cfd4368 100644 (file)
@@ -316,7 +316,7 @@ void SetFormatWindow::create_objects()
                _("Channels:")));
        add_subwindow(channels = new SetChannelsTextBox(thread,
                mwindow->theme->setformat_x2, y));
-       add_subwindow(new BC_ITumbler(channels, 1, MAXCHANNELS,
+       add_subwindow(new BC_ITumbler(channels, 0, MAXCHANNELS,
                mwindow->theme->setformat_x2 + channels->get_w(), y));
 
        y += mwindow->theme->setformat_margin;
@@ -513,19 +513,14 @@ SetChannelsTextBox::SetChannelsTextBox(SetFormatThread *thread, int x, int y)
 }
 int SetChannelsTextBox::handle_event()
 {
-       int new_channels = CLIP(atoi(get_text()), 1, MAXCHANNELS);
-
+       int new_channels = CLIP(atoi(get_text()), 0, MAXCHANNELS);
        thread->new_settings->session->audio_channels = new_channels;
-
-
-       if(new_channels > 0)
-       {
+       if(new_channels > 0) {
                memcpy(thread->new_settings->session->achannel_positions,
                        &thread->mwindow->preferences->channel_positions[new_channels - 1],
                        sizeof(thread->new_settings->session->achannel_positions));
        }
 
-
        thread->window->canvas->draw();
        return 1;
 }
diff --git a/cinelerra-5.1/cinelerra/wintv.C b/cinelerra-5.1/cinelerra/wintv.C
new file mode 100644 (file)
index 0000000..5e06793
--- /dev/null
@@ -0,0 +1,274 @@
+#ifdef HAVE_WINTV
+
+#include "channelinfo.h"
+#include "cwindow.h"
+#include "cwindowgui.h"
+#include "edl.h"
+#include "mbuttons.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "language.h"
+#include "playbackengine.h"
+#include "playtransport.h"
+#include "record.h"
+#include "recordgui.h"
+#include "recordmonitor.h"
+#include "remotecontrol.h"
+#include "tracks.h"
+#include "wintv.h"
+
+#include <dirent.h>
+#include <linux/input.h>
+
+WinTV::WinTV(MWindow *mwindow, int ifd)
+{
+       this->mwindow = mwindow;
+       this->ifd = ifd;
+
+       ev = new input_event;
+       memset(ev, 0, sizeof(*ev));
+       ev->code = -1;
+       done = -1;
+       last_code = -1;
+       code = -1;
+}
+
+WinTV::~WinTV()
+{
+       stop();
+       delete ev;
+}
+
+void WinTV::stop()
+{
+       if( ifd >= 0 ) {
+               ioctl(ifd, EVIOCGRAB, 0);
+               close(ifd);
+               ifd = -1;
+       }
+       if( running() && !done ) {
+               done = 1;
+               cancel();
+               join();
+       }
+}
+
+void WinTV::start()
+{
+       ioctl(ifd, EVIOCGRAB, 1);
+       done = 0;
+       Thread::start();
+}
+
+int WinTV::open_usb_input(int vendor, int product, int &version)
+{
+       int ret = -1;
+       const char *dev_input = "/dev/input";
+       DIR *dir = opendir(dev_input);
+       if( !dir ) return ret;
+
+       struct dirent64 *dp;
+       struct input_id dev_id;
+       while( (dp = readdir64(dir)) != 0 ) {
+               char *fn = dp->d_name;
+               if( !strcmp(fn, ".") || !strcmp(fn, "..") ) continue;
+               char path[PATH_MAX];  struct stat st;
+               snprintf(path, PATH_MAX, "%s/%s", dev_input, fn);
+               if( stat(path, &st) < 0 ) continue;
+               if( S_ISDIR(st.st_mode) ) continue;
+               int fd = open(path, O_RDONLY);
+               if( fd < 0 ) continue;
+               if( !ioctl(fd, EVIOCGID, &dev_id) ) {
+                       if( dev_id.bustype == BUS_USB &&
+                           dev_id.vendor == vendor &&
+                           dev_id.product == product ) {
+                               version = dev_id.version;
+                               ret = fd;
+                               break;
+                       }
+               }
+               close(fd);
+       }
+       closedir(dir);
+       return ret;
+}
+
+WinTV *WinTV::probe(MWindow *mwindow)
+{
+       int ver = -1;
+       int ifd = open_usb_input(0x2040, 0x826d, ver);
+       if( ifd < 0 ) return 0;
+       printf("detected hauppauge WinTV Model 1657, ver=0x%04x\n", ver);
+       return new WinTV(mwindow, ifd);
+}
+
+void WinTV::run()
+{
+       enable_cancel();
+       while( !done ) {
+               int ret = read(ifd, ev, sizeof(*ev));
+               if( done ) break;
+               if( ret != sizeof(*ev) ) {
+                       if( ret < 0 ) { perror("read event"); break; }
+                       fprintf(stderr, "bad read: %d\n", ret);
+                       break;
+               }
+               handle_event();
+       }
+}
+
+int WinTV::check_menu_keys(int code)
+{
+       int result = 1;
+       switch( code ) {
+       case WTV_POWER:
+               mwindow->quit();
+               break;
+       case WTV_TV: {
+               Record *record = mwindow->gui->record;
+                if( !record->running() )
+                        record->start();
+                else
+                        record->record_gui->interrupt_thread->start(0);
+                break; }
+       case WTV_MENU:
+#ifdef HAVE_DVB
+               mwindow->gui->channel_info->toggle_scan();
+#endif
+               break;
+       case WTV_RED: {
+               RemoteControl *remote_control = mwindow->gui->remote_control;
+               if( !remote_control->deactivate() )
+                        remote_control->activate();
+               break; }
+       default:
+               result = 0;
+       }
+       return result;
+}
+
+void WinTV::handle_event()
+{
+       switch(ev->type) {
+       case EV_KEY: {
+               if( !ev->value ) break;
+               this->last_code = this->code;
+               this->code = ev->code;
+               if( check_menu_keys(code) ) break;
+               RemoteHandler *handler = mwindow->gui->remote_control->handler;
+               if( handler )
+                       handler->process_key(ev->code);
+               break; }
+       case EV_SYN:
+       case EV_MSC:
+               break;
+       default: {
+               time_t t = ev->time.tv_sec;
+               struct tm *tp = localtime(&t);
+               printf("wintv event: %4d/%02d/%02d %02d:%02d:%02d.%03d = (%d, %d, 0x%x)\n",
+                       tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday,
+                       tp->tm_hour, tp->tm_min, tp->tm_sec,
+                       (int)ev->time.tv_usec/1000, ev->type, ev->code, ev->value);
+               break; }
+       }
+}
+
+
+int WinTVCWindowHandler::wintv_process_code(int code)
+{
+        MWindow *mwindow = wintv->mwindow;
+        EDL *edl = mwindow->edl;
+        if( !edl ) return 0;
+        PlayTransport *transport = mwindow->gui->mbuttons->transport;
+        if( !transport->get_edl() ) return 0;
+        PlaybackEngine *engine = transport->engine;
+        double position = engine->get_tracking_position();
+        double length = edl->tracks->total_length();
+        int next_command = -1;
+
+       switch( code ) {
+       case WTV_OK:
+               break;
+// select window tile config = BACK 1,2,3
+       case WTV_1: case WTV_2: case WTV_3:
+               if( mwindow->wintv->last_code == WTV_BACK ) {
+                       RemoteGUI *rgui = mwindow->gui->cwindow_remote_handler->gui;
+                       rgui->tile_windows(code - WTV_1);
+                       return 1;
+               } // fall thru
+// select asset program config = TEXT 1,2,3,4,5,6
+       case WTV_4: case WTV_5: case WTV_6:
+               if( mwindow->wintv->last_code == WTV_TEXT ) {
+                       mwindow->select_asset(code - WTV_1, 1);
+                       break;
+               } // fall thru
+// select position in 10 percent units
+       case WTV_7: case WTV_8: case WTV_9:
+       case WTV_0:
+               position = length * (code - WTV_0)/10.0;
+               break;
+// jump +- 10/60 secs
+       case WTV_LT:  position -= 10.0;  break;
+       case WTV_UP:  position += 60.0;  break;
+       case WTV_RT:  position += 10.0;  break;
+       case WTV_DN:  position -= 60.0;  break;
+       case WTV_BACK: return 1;
+       case WTV_HOME: {
+                CWindowCanvas *canvas = mwindow->cwindow->gui->canvas;
+                int on = canvas->get_fullscreen() ? 0 : 1;
+                canvas->Canvas::set_fullscreen(on, 0);
+                return 1; }
+       case WTV_VOLUP: return 1;
+       case WTV_VOLDN: return 1;
+       case WTV_CH_UP: return 1;
+       case WTV_CH_DN: return 1;
+       case WTV_TEXT:  return 1;
+       case WTV_CC:    return 1;
+       case WTV_BOX:   return 1;
+       case WTV_START: next_command = SLOW_REWIND;  break;
+       case WTV_REV:   next_command = FAST_REWIND;  break;
+       case WTV_STOP:  next_command = STOP;         break;
+       case WTV_PLAY:  next_command = NORMAL_FWD;   break;
+       case WTV_FWD:   next_command = FAST_FWD;     break;
+       case WTV_END:   next_command = SLOW_FWD;     break;
+       case WTV_MUTE:  return 1;
+       default:
+               printf("wintv cwindow: unknown code: %04x\n", code);
+               return -1;
+       }
+
+       if( next_command < 0 ) {
+               if( position < 0 ) position = 0;
+               transport->change_position(position);
+        }
+       else
+               transport->handle_transport(next_command);
+       return 0;
+}
+
+int WinTVCWindowHandler::process_key(int key)
+{
+       return wintv_process_code(key);
+}
+
+int WinTVRecordHandler::process_key(int key)
+{
+       Record *record = wintv->mwindow->gui->record;
+       return record->wintv_process_code(key);
+}
+
+
+WinTVRecordHandler::WinTVRecordHandler(WinTV *wintv, RemoteControl *remote_control)
+ : RemoteHandler(remote_control->gui, GREEN)
+{
+       this->wintv = wintv;
+}
+
+WinTVCWindowHandler::WinTVCWindowHandler(WinTV *wintv, RemoteControl *remote_control)
+ : RemoteHandler(remote_control->gui, BLUE)
+{
+       this->wintv = wintv;
+}
+
+// HAVE_WINTV
+#endif
diff --git a/cinelerra-5.1/cinelerra/wintv.h b/cinelerra-5.1/cinelerra/wintv.h
new file mode 100644 (file)
index 0000000..cefb644
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef __WINTV_H__
+#define __WINTV_H__
+// as of 2020/01/06 using kernel version 5.3.16
+//  a patch is needed for: drivers/media/usb/em28xx/em28xx-rc.ko
+//  prototype in thirdparty/src/em28xx-input.patch1
+//#define HAVE_WINTV
+#ifdef HAVE_WINTV
+
+#include "remotecontrol.h"
+#include "thread.h"
+
+#define WTV_OK          0x0160
+#define WTV_LT          0x0069
+#define WTV_UP          0x0067
+#define WTV_RT          0x006a
+#define WTV_DN          0x006c
+#define WTV_HOME        0x0162
+#define WTV_BACK        0x00ae
+#define WTV_MENU        0x008b
+#define WTV_TV          0x0179
+#define WTV_POWER       0x0074
+#define WTV_VOLUP       0x0073
+#define WTV_VOLDN       0x0072
+#define WTV_CH_UP       0x0192
+#define WTV_CH_DN       0x0193
+#define WTV_1           0x0201
+#define WTV_2           0x0202
+#define WTV_3           0x0203
+#define WTV_4           0x0204
+#define WTV_5           0x0205
+#define WTV_6           0x0206
+#define WTV_7           0x0207
+#define WTV_8           0x0208
+#define WTV_9           0x0209
+#define WTV_TEXT        0x0184
+#define WTV_0           0x0200
+#define WTV_CC          0x0172
+#define WTV_BOX         0x0080
+#define WTV_START       0x0195
+#define WTV_REV         0x00a8
+#define WTV_STOP        0x0077
+#define WTV_PLAY        0x00cf
+#define WTV_FWD         0x00d0
+#define WTV_END         0x0197
+#define WTV_MUTE        0x0071
+#define WTV_PREV        0x019c
+#define WTV_RED         0x00a7
+
+struct input_event;
+
+class WinTV : public Thread
+{
+public:
+       WinTV(MWindow *mwindow, int ifd);
+       ~WinTV();
+
+       void stop();
+       void start();
+       static int open_usb_input(int vendor, int product, int &version);
+       static WinTV *probe(MWindow *mwindow);
+       void run();
+       void handle_event();
+       int check_menu_keys(int code);
+       virtual int process_code() { return 1; }
+
+       MWindow *mwindow;
+       input_event *ev;
+       int done, ifd;
+       int last_code, code;
+};
+
+class WinTVCWindowHandler : public RemoteHandler
+{
+public:
+       WinTVCWindowHandler(WinTV *wintv, RemoteControl *remote_control);
+       int wintv_process_code(int code);
+       int process_key(int key);
+
+       WinTV *wintv;
+};
+
+class WinTVRecordHandler : public RemoteHandler
+{
+public:
+       WinTVRecordHandler(WinTV *wintv, RemoteControl *remote_control);
+       int wintv_process_code(int code);
+       int process_key(int key);
+
+       WinTV *wintv;
+};
+
+#endif
+#endif
diff --git a/cinelerra-5.1/cinelerra/wintv.inc b/cinelerra-5.1/cinelerra/wintv.inc
new file mode 100644 (file)
index 0000000..744a6ac
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __WINTV_INC__
+#define __WINTV_INC__
+
+class WinTV;
+class WinTVRemote;
+class WinTVCWindowHandler;
+class WinTVRecordHandler;
+
+#endif
index 4c1b8f0..e2360c0 100644 (file)
@@ -56,6 +56,7 @@ CHECK_WITH([libzmpeg],[build libzmpeg],[LIBZMPEG],[yes])
 CHECK_WITH([commercial],[enable commercial capture],[COMMERCIAL],[yes])
 CHECK_WITH([thirdparty],[use thirdparty build],[CIN_3RDPARTY],[yes])
 CHECK_WITH([shuttle],[shuttle device],[SHUTTLE],[yes])
+CHECK_WITH([wintv],[usb 2040:826d wintv device],[WINTV],[yes])
 CHECK_WITH([vaapi],[video acceleration api],[VAAPI],[yes])
 CHECK_WITH([vdpau],[video decode+presentation api for unix],[VDPAU],[yes])
 CHECK_WITH([nv],[nvenc/nvdec ffnvcodec api],[NV],[yes])
@@ -591,7 +592,7 @@ CHECK_HEADERS([dav1d], [libdav1d headers], [dav1d/dav1d.h])
 CHECK_LIB([libwebp], [webp], [WebPGetEncoderVersion])
 CHECK_HEADERS([libwebp], [libwebp headers], [webp/encode.h])
 CHECK_LIB([a52dec], [a52], [a52_init])
-CHECK_HEADERS([a52dec], [a52 headers], [a52.h])
+CHECK_HEADERS([a52dec], [a52 headers], [stdint.h a52.h])
 CHECK_LIB([encore], [encore], [encore])
 CHECK_HEADERS([encore], [encore headers], [encore.h])
 CHECK_LIB([giflib], [gif], [DGifOpen])
@@ -886,7 +887,7 @@ fi
 for v in GL XFT XXF86VM OSS ALSA FIREWIRE DV DVB \
         VIDEO4LINUX2 ESOUND PACTL OPENEXR LV2 \
         COMMERCIAL LIBZMPEG SHUTTLE SHUTTLE_USB \
-        VAAPI VDPAU CUDA NV; do
+        VAAPI VDPAU CUDA NV WINTV; do
   eval vv="\$WANT_$v"
   if test "x$vv" != "xno"; then
     CFG_CFLAGS+=" -DHAVE_$v"
index 9b3b6c8..cbb5168 100644 (file)
@@ -1330,24 +1330,19 @@ int BC_FileBox::get_y_margin()
 char* BC_FileBox::get_path(int selection)
 {
        if(selection == 0)
-       {
                return get_submitted_path();
-       }
-       else
-       {
-               BC_ListBoxItem *item = listbox->get_selection(
-                       column_of_type(FILEBOX_NAME), selection - 1);
-               if(item)
-               {
-                       fs->join_names(string, directory, item->get_text());
-                       return string;
-               }
+       BC_ListBoxItem *item = listbox->get_selection(
+               column_of_type(FILEBOX_NAME), selection - 1);
+       if( item ) {
+               fs->join_names(string, directory, item->get_text());
+               return string;
        }
        return 0;
 }
 
 char* BC_FileBox::get_submitted_path()
 {
+       update_paths(textbox->get_text());
        return submitted_path;
 }
 
index 6653b14..f672e77 100644 (file)
@@ -61,6 +61,7 @@ BC_MenuItem::BC_MenuItem(const char *text, const char *hotkey_text, int hotkey)
        alt_hotkey = 0;
        ctrl_hotkey = 0;
        menu_popup = 0;
+       enabled = 1;
 }
 
 BC_MenuItem::~BC_MenuItem()
@@ -135,6 +136,16 @@ int BC_MenuItem::deactivate_submenus(BC_MenuPopup *exclude)
        return 0;
 }
 
+int BC_MenuItem::get_enabled(int v)
+{
+       return enabled;
+}
+void BC_MenuItem::set_enabled(int v)
+{
+       enabled = v;
+}
+
+
 int BC_MenuItem::activate_submenu()
 {
        int new_x, new_y;
index 5c04b0f..e167b98 100644 (file)
@@ -67,6 +67,8 @@ public:
        BC_WindowBase* get_top_level();
        BC_PopupMenu* get_popup_menu();
        BC_SubMenu *get_submenu();
+       int get_enabled(int v);
+       void set_enabled(int v);
 
 private:
        BC_WindowBase *top_level;
@@ -80,6 +82,8 @@ private:
        int down;
 // check box
        int checked;
+// not drawn if not enabled
+       int enabled;
 // title
        char *text;
 // text of hotkey
index 2c72354..c35b2fa 100644 (file)
@@ -144,14 +144,16 @@ int BC_MenuPopup::total_items()
        return menu_items.size();
 }
 
+
 int BC_MenuPopup::dispatch_button_press()
 {
        int result = 0;
        if(popup)
        {
-               for(int i = 0; i < menu_items.total && !result && popup; i++)
-               {
-                       result = menu_items.values[i]->dispatch_button_press();
+               for(int i = 0; i < menu_items.total && !result && popup; i++) {
+                       BC_MenuItem *item = menu_items[i];
+                       if( !item->enabled ) continue;
+                       result = item->dispatch_button_press();
                }
                if(result) draw_items();
        }
@@ -163,9 +165,10 @@ int BC_MenuPopup::dispatch_button_release()
        int result = 0, redraw = 0;
        if(popup)
        {
-               for(int i = 0; i < menu_items.total && !result && popup; i++)
-               {
-                       result = menu_items.values[i]->dispatch_button_release(redraw);
+               for(int i = 0; i < menu_items.total && !result && popup; i++) {
+                       BC_MenuItem *item = menu_items[i];
+                       if( !item->enabled ) continue;
+                       result = item->dispatch_button_release(redraw);
                }
                if(redraw) draw_items();
        }
@@ -175,9 +178,10 @@ int BC_MenuPopup::dispatch_button_release()
 int BC_MenuPopup::dispatch_key_press()
 {
        int result = 0;
-       for(int i = 0; i < menu_items.total && !result; i++)
-       {
-               result = menu_items.values[i]->dispatch_key_press();
+       for(int i = 0; i < menu_items.total && !result; i++) {
+               BC_MenuItem *item = menu_items[i];
+               if( !item->enabled ) continue;
+               result = item->dispatch_key_press();
        }
        return result;
 }
@@ -189,9 +193,10 @@ int BC_MenuPopup::dispatch_motion_event()
        if(popup)
        {
 // Try submenus and items
-               for(i = 0; i < menu_items.total; i++)
-               {
-                       result |= menu_items.values[i]->dispatch_motion_event(redraw);
+               for(i = 0; i < menu_items.total; i++) {
+                       BC_MenuItem *item = menu_items[i];
+                       if( !item->enabled ) continue;
+                       result |= item->dispatch_motion_event(redraw);
                }
 
                if(redraw) draw_items();
@@ -221,9 +226,10 @@ int BC_MenuPopup::dispatch_translation_event()
                this->x = new_x;
                this->y = new_y;
 
-               for(int i = 0; i < menu_items.total; i++)
-               {
-                       menu_items.values[i]->dispatch_translation_event();
+               for(int i = 0; i < menu_items.total; i++) {
+                       BC_MenuItem *item = menu_items[i];
+                       if( !item->enabled ) continue;
+                       item->dispatch_translation_event();
                }
        }
        return 0;
@@ -236,9 +242,10 @@ int BC_MenuPopup::dispatch_cursor_leave()
 
        if(popup)
        {
-               for(int i = 0; i < menu_items.total; i++)
-               {
-                       result |= menu_items.values[i]->dispatch_cursor_leave();
+               for(int i = 0; i < menu_items.total; i++) {
+                       BC_MenuItem *item = menu_items[i];
+                       if( !item->enabled ) continue;
+                       result |= item->dispatch_cursor_leave();
                }
                if(result) draw_items();
        }
@@ -323,9 +330,10 @@ int BC_MenuPopup::activate_menu(int x,
 
 int BC_MenuPopup::deactivate_submenus(BC_MenuPopup *exclude)
 {
-       for(int i = 0; i < menu_items.total; i++)
-       {
-               menu_items.values[i]->deactivate_submenus(exclude);
+       for(int i = 0; i < menu_items.total; i++) {
+               BC_MenuItem *item = menu_items[i];
+               if( !item->enabled ) continue;
+               item->deactivate_submenus(exclude);
        }
        return 0;
 }
@@ -361,9 +369,10 @@ int BC_MenuPopup::draw_items()
                        BLACK);
        }
 
-       for(int i = 0; i < menu_items.total; i++)
-       {
-               menu_items.values[i]->draw();
+       for(int i = 0; i < menu_items.total; i++) {
+               BC_MenuItem *item = menu_items[i];
+               if( !item->enabled ) continue;
+               item->draw();
        }
        popup->flash();
 
@@ -382,27 +391,27 @@ int BC_MenuPopup::get_dimensions()
 // pad for border
        h = yS(2);
 // Set up parameters in each item and get total h.
-       for(i = 0; i < menu_items.total; i++)
-       {
-               text_w = xs10 + top_level->get_text_width(MEDIUMFONT, menu_items.values[i]->text);
-               if(menu_items.values[i]->checked) text_w += check->get_w() + xS(1);
+       for(i = 0; i < menu_items.total; i++) {
+               BC_MenuItem *item = menu_items[i];
+               if( !item->enabled ) continue;
+               text_w = xs10 + top_level->get_text_width(MEDIUMFONT, item->text);
+               if(item->checked) text_w += check->get_w() + xS(1);
 
-               key_w = xs10 + top_level->get_text_width(MEDIUMFONT, menu_items.values[i]->hotkey_text);
+               key_w = xs10 + top_level->get_text_width(MEDIUMFONT, item->hotkey_text);
                if(text_w > widest_text) widest_text = text_w;
                if(key_w > widest_key) widest_key = key_w;
 
-               if(!strcmp(menu_items.values[i]->text, "-"))
-                       menu_items.values[i]->h = ys5;
-               else
-               {
-                       menu_items.values[i]->h = item_bg[0] ? item_bg[0]->get_h() :
+               if(!strcmp(item->text, "-"))
+                       item->h = ys5;
+               else {
+                       item->h = item_bg[0] ? item_bg[0]->get_h() :
                                top_level->get_text_height(MEDIUMFONT) + ys4;
                }
 
-               menu_items.values[i]->y = h;
-               menu_items.values[i]->highlighted = 0;
-               menu_items.values[i]->down = 0;
-               h += menu_items.values[i]->h;
+               item->y = h;
+               item->highlighted = 0;
+               item->down = 0;
+               h += item->h;
        }
        w = widest_text + widest_key + xs20;
 
@@ -429,8 +438,9 @@ int BC_MenuPopup::cursor_inside()
        if( !popup ) return 0;
        if( popup->cursor_above() ) return 1;
        for( int i=0; i<menu_items.size(); ++i ) {
-               if( !menu_items[i]->submenu ) continue;
-               if( menu_items[i]->submenu->cursor_inside() ) return 1;
+               BC_MenuItem *item = menu_items[i];
+               if( !item->enabled || !item->submenu ) continue;
+               if( item->submenu->cursor_inside() ) return 1;
        }
        return 0;
 }
index acd48d5..f5024a6 100644 (file)
@@ -87,7 +87,7 @@ private:
 // Popup window that only exists when menu is down.
        BC_Popup *popup;
        int active;
-       int type;
+       int type, disabled;
 // Images for backgrounds
        BC_Pixmap *window_bg;
        BC_Pixmap *item_bg[3];
index 338466c..8d0dc3a 100644 (file)
@@ -238,7 +238,6 @@ void ColorBalanceEngine::run()
        magenta_f = plugin->calculate_transfer(plugin->config.magenta); \
        yellow_f = plugin->calculate_transfer(plugin->config.yellow); \
  \
-printf("PROCESS_F %f\n", cyan_f); \
        for(j = row_start; j < row_end; j++) \
        { \
                for(k = 0; k < input->get_w() * components; k += components) \
index 38daf1e..71c647a 100644 (file)
@@ -192,14 +192,28 @@ void BlondTheme::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index 97b9f40..c4666b7 100644 (file)
@@ -474,17 +474,31 @@ void BlondCVTheme::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->bar_data = new_image("bar", "bar.png");
 
-
        resources->min_menu_w = 0;
        resources->menu_popup_bg = 0;  // if (0) use menu_light, menu_up, menu_shadow
        resources->menu_item_bg = 0;   // if (0) use menu_light, menu_highlighted, menu_down, menu_shadow
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index e06eb81..adbc600 100644 (file)
@@ -191,14 +191,28 @@ void BlueDotTheme::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index def4e98..e00a45e 100644 (file)
@@ -204,13 +204,28 @@ void BlueDotTheme::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
+               "loadmode_edl_fileref");
 
 //There are differences here, but we won't change until the end.
 //Specific to BD
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index 1a270fc..132e70c 100644 (file)
@@ -198,14 +198,28 @@ void BrightTheme::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index 7145dd5..bb3a001 100644 (file)
@@ -199,14 +199,29 @@ void CAKEWALKTHEME::initialize()
   "loadmode_dn.png",
   "loadmode_checkedhi.png",
   "loadmode_resource");
- new_toggle(
-  "loadmode_nested.png",
+
+ new_toggle("loadmode_edl_clip.png",
+  "loadmode_up.png",
+  "loadmode_hi.png",
+  "loadmode_checked.png",
+  "loadmode_dn.png",
+  "loadmode_checkedhi.png",
+  "loadmode_edl_clip");
+ new_toggle("loadmode_edl_nested.png",
+  "loadmode_up.png",
+  "loadmode_hi.png",
+  "loadmode_checked.png",
+  "loadmode_dn.png",
+  "loadmode_checkedhi.png",
+  "loadmode_edl_nested");
+ new_toggle("loadmode_edl_fileref.png",
   "loadmode_up.png",
   "loadmode_hi.png",
   "loadmode_checked.png",
   "loadmode_dn.png",
   "loadmode_checkedhi.png",
-  "loadmode_nested");
+  "loadmode_edl_fileref");
+
  resources->filebox_icons_images = new_button(
   "icons.png",
   "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index 5618ba8..be173bc 100644 (file)
@@ -191,14 +191,28 @@ void HULKTHEME::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index b6ca90f..8cb04d0 100644 (file)
@@ -287,14 +287,32 @@ void NEOPHYTETHEME::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
+
+       new_toggle(
+               "loadmode_edl_clip.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_clip");
        new_toggle(
-               "loadmode_nested.png",
+               "loadmode_edl_nested.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
+               "loadmode_edl_nested");
+       new_toggle(
+               "loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
+
        resources->filebox_icons_images = new_button(
                "icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index e206eed..bca5c59 100644 (file)
@@ -191,14 +191,28 @@ void PINKLADY::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index fc3e618..73ea0a2 100644 (file)
@@ -187,14 +187,28 @@ void SUV::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_clip.png b/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_clip.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_fileref.png b/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_fileref.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_nested.png b/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_nested.png
new file mode 120000 (symlink)
index 0000000..f853858
--- /dev/null
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
index 33953a6..4f537a1 100644 (file)
@@ -192,14 +192,28 @@ void UNFLATTHEME::initialize()
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
                "loadmode_resource");
-       new_toggle("loadmode_nested.png",
+
+       new_toggle("loadmode_edl_clip.png",
                "loadmode_up.png",
                "loadmode_hi.png",
                "loadmode_checked.png",
                "loadmode_dn.png",
                "loadmode_checkedhi.png",
-               "loadmode_nested");
-
+               "loadmode_edl_clip");
+       new_toggle("loadmode_edl_nested.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_nested");
+       new_toggle("loadmode_edl_fileref.png",
+               "loadmode_up.png",
+               "loadmode_hi.png",
+               "loadmode_checked.png",
+               "loadmode_dn.png",
+               "loadmode_checkedhi.png",
+               "loadmode_edl_fileref");
 
        resources->filebox_icons_images = new_button("icons.png",
                "fileboxbutton_up.png",
diff --git a/cinelerra-5.1/thirdparty/src/em28xx-input.patch1 b/cinelerra-5.1/thirdparty/src/em28xx-input.patch1
new file mode 100644 (file)
index 0000000..1a19f0c
--- /dev/null
@@ -0,0 +1,67 @@
+diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
+index 5aa15a7..a27a621 100644
+--- a/drivers/media/usb/em28xx/em28xx-input.c
++++ b/drivers/media/usb/em28xx/em28xx-input.c
+@@ -63,8 +63,10 @@ struct em28xx_IR {
+       /* poll decoder */
+       int polling;
++      int keypressed;
+       struct delayed_work work;
+       unsigned int full_code:1;
++      unsigned int last_toggle_bit;
+       unsigned int last_readcount;
+       u64 rc_proto;
+@@ -331,8 +333,34 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
+               dprintk("ir->get_key() failed: %d\n", result);
+               return;
+       }
+-
+-      if (unlikely(poll_result.read_count != ir->last_readcount)) {
++      if (ir->dev->model == EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595) {
++              if (likely(poll_result.toggle_bit == ir->last_toggle_bit &&
++                         poll_result.read_count == ir->last_readcount))
++                      return;
++              dprintk("%s: toggle: %d, count: %d, key 0x%04x\n", __func__,
++                      poll_result.toggle_bit, poll_result.read_count,
++                      poll_result.scancode);
++              ir->rc->input_dev->evbit[0] &= ~BIT_MASK(EV_REP);
++              if( poll_result.read_count & 1 ) {
++                      if (!ir->keypressed) {
++                              ir->keypressed = true;
++                              if( poll_result.toggle_bit == ir->last_toggle_bit )
++                                      return;
++                              ir->rc->keypressed = false;
++                              rc_keydown_notimeout(ir->rc,
++                                      poll_result.protocol,
++                                      poll_result.scancode,
++                                      poll_result.toggle_bit);
++                              ir->rc->keypressed = false;
++                      }
++              }
++              else if (ir->keypressed) {
++                      ir->keypressed = false;
++                      ir->rc->keypressed = true;
++                      rc_keyup(ir->rc);
++              }
++      }
++      else if (unlikely(poll_result.read_count != ir->last_readcount)) {
+               dprintk("%s: toggle: %d, count: %d, key 0x%04x\n", __func__,
+                       poll_result.toggle_bit, poll_result.read_count,
+                       poll_result.scancode);
+@@ -357,10 +385,11 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
+                        * non-zero read count as opposed to a readcount
+                        * that is incrementing
+                        */
+-                      ir->last_readcount = 0;
+-              else
+-                      ir->last_readcount = poll_result.read_count;
++                      poll_result.read_count = 0;
+       }
++
++      ir->last_toggle_bit = poll_result.toggle_bit;
++      ir->last_readcount = poll_result.read_count;
+ }
+ static void em28xx_ir_work(struct work_struct *work)