From 4c207ab325a8e8e6b79a9a18d4647273b5f59f93 Mon Sep 17 00:00:00 2001
From: Good Guy <good1.2guy@gmail.com>
Date: Tue, 7 Jan 2020 17:09:19 -0700
Subject: [PATCH] wintv remote control + kernel patch, add codec fileref, amp
 up OpenEDL, add loadmode edl clip/nested/ref, a52 probe tweak,
 appearanceprefs tweaks

---
 cinelerra-5.1/cinelerra/Makefile              |   2 +
 cinelerra-5.1/cinelerra/appearanceprefs.C     | 141 ++++---
 cinelerra-5.1/cinelerra/appearanceprefs.h     |   8 +
 cinelerra-5.1/cinelerra/appearanceprefs.inc   |   1 +
 cinelerra-5.1/cinelerra/assetedit.C           |   4 +-
 cinelerra-5.1/cinelerra/assetpopup.C          |  83 +++--
 cinelerra-5.1/cinelerra/assetpopup.h          |   1 -
 cinelerra-5.1/cinelerra/awindowgui.C          |   4 +
 cinelerra-5.1/cinelerra/clipedls.h            |   5 +-
 cinelerra-5.1/cinelerra/clippopup.C           |  10 +-
 cinelerra-5.1/cinelerra/convert.C             |   4 +-
 cinelerra-5.1/cinelerra/cwindow.C             |  31 +-
 cinelerra-5.1/cinelerra/cwindow.h             |   9 +-
 cinelerra-5.1/cinelerra/editpopup.C           |  54 +++
 cinelerra-5.1/cinelerra/editpopup.h           |  11 +
 cinelerra-5.1/cinelerra/editpopup.inc         |   1 +
 cinelerra-5.1/cinelerra/edl.C                 |   2 +-
 cinelerra-5.1/cinelerra/edlsession.C          |   2 +-
 cinelerra-5.1/cinelerra/file.C                |   9 +
 cinelerra-5.1/cinelerra/file.inc              |   3 +
 cinelerra-5.1/cinelerra/fileref.C             | 214 +++++++++++
 cinelerra-5.1/cinelerra/fileref.h             |  65 ++++
 cinelerra-5.1/cinelerra/filexml.h             |   3 +-
 cinelerra-5.1/cinelerra/loadfile.C            |  40 +-
 cinelerra-5.1/cinelerra/loadfile.h            |   5 +-
 cinelerra-5.1/cinelerra/loadmode.C            | 149 +++++---
 cinelerra-5.1/cinelerra/loadmode.h            |  20 +-
 cinelerra-5.1/cinelerra/loadmode.inc          |   8 +-
 cinelerra-5.1/cinelerra/main.C                |   3 +-
 cinelerra-5.1/cinelerra/mainindexes.C         |   4 +-
 cinelerra-5.1/cinelerra/mainindexes.h         |   2 +-
 cinelerra-5.1/cinelerra/mainundo.C            |   4 +-
 cinelerra-5.1/cinelerra/mwindow.C             | 345 +++++++++++-------
 cinelerra-5.1/cinelerra/mwindow.h             |  14 +-
 cinelerra-5.1/cinelerra/mwindowedit.C         |  16 +-
 cinelerra-5.1/cinelerra/mwindowgui.C          |  17 +-
 cinelerra-5.1/cinelerra/mwindowgui.h          |   7 +-
 cinelerra-5.1/cinelerra/preferences.C         |   4 +
 cinelerra-5.1/cinelerra/preferences.h         |   1 +
 cinelerra-5.1/cinelerra/proxy.C               |   2 +-
 cinelerra-5.1/cinelerra/record.C              |  90 ++++-
 cinelerra-5.1/cinelerra/record.h              |   7 +-
 cinelerra-5.1/cinelerra/remotecontrol.C       |   5 +-
 cinelerra-5.1/cinelerra/remotecontrol.h       |   2 +-
 cinelerra-5.1/cinelerra/setformat.C           |  11 +-
 cinelerra-5.1/cinelerra/wintv.C               | 274 ++++++++++++++
 cinelerra-5.1/cinelerra/wintv.h               |  93 +++++
 cinelerra-5.1/cinelerra/wintv.inc             |   9 +
 cinelerra-5.1/configure.ac                    |   5 +-
 cinelerra-5.1/guicast/bcfilebox.C             |  17 +-
 cinelerra-5.1/guicast/bcmenuitem.C            |  11 +
 cinelerra-5.1/guicast/bcmenuitem.h            |   4 +
 cinelerra-5.1/guicast/bcmenupopup.C           |  90 +++--
 cinelerra-5.1/guicast/bcmenupopup.h           |   2 +-
 .../plugins/colorbalance/colorbalance.C       |   1 -
 .../plugins/theme_blond/blondtheme.C          |  20 +-
 .../theme_blond/data/loadmode_edl_clip.png    |   1 +
 .../theme_blond/data/loadmode_edl_fileref.png |   1 +
 .../theme_blond/data/loadmode_edl_nested.png  |   1 +
 .../plugins/theme_blond_cv/blondcvtheme.C     |  20 +-
 .../theme_blond_cv/data/loadmode_edl_clip.png |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../data/loadmode_edl_nested.png              |   1 +
 cinelerra-5.1/plugins/theme_blue/bluetheme.C  |  20 +-
 .../theme_blue/data/loadmode_edl_clip.png     |   1 +
 .../theme_blue/data/loadmode_edl_fileref.png  |   1 +
 .../theme_blue/data/loadmode_edl_nested.png   |   1 +
 .../plugins/theme_blue_dot/bluedottheme.C     |  19 +-
 .../theme_blue_dot/data/loadmode_edl_clip.png |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../data/loadmode_edl_nested.png              |   1 +
 .../plugins/theme_bright/brighttheme.C        |  20 +-
 .../theme_bright/data/loadmode_edl_clip.png   |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../theme_bright/data/loadmode_edl_nested.png |   1 +
 .../plugins/theme_cakewalk/cakewalk.C         |  21 +-
 .../theme_cakewalk/data/loadmode_edl_clip.png |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../data/loadmode_edl_nested.png              |   1 +
 .../theme_hulk/data/loadmode_edl_clip.png     |   1 +
 .../theme_hulk/data/loadmode_edl_fileref.png  |   1 +
 .../theme_hulk/data/loadmode_edl_nested.png   |   1 +
 cinelerra-5.1/plugins/theme_hulk/hulktheme.C  |  20 +-
 .../theme_neophyte/data/loadmode_edl_clip.png |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../data/loadmode_edl_nested.png              |   1 +
 .../plugins/theme_neophyte/neophyte.C         |  22 +-
 .../theme_pinklady/data/loadmode_edl_clip.png |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../data/loadmode_edl_nested.png              |   1 +
 .../plugins/theme_pinklady/pinkladytheme.C    |  20 +-
 .../theme_suv/data/loadmode_edl_clip.png      |   1 +
 .../theme_suv/data/loadmode_edl_fileref.png   |   1 +
 .../theme_suv/data/loadmode_edl_nested.png    |   1 +
 cinelerra-5.1/plugins/theme_suv/suv.C         |  20 +-
 .../theme_unflat/data/loadmode_edl_clip.png   |   1 +
 .../data/loadmode_edl_fileref.png             |   1 +
 .../theme_unflat/data/loadmode_edl_nested.png |   1 +
 .../plugins/theme_unflat/unflattheme.C        |  20 +-
 .../thirdparty/src/em28xx-input.patch1        |  67 ++++
 100 files changed, 1802 insertions(+), 449 deletions(-)
 create mode 100644 cinelerra-5.1/cinelerra/fileref.C
 create mode 100644 cinelerra-5.1/cinelerra/fileref.h
 create mode 100644 cinelerra-5.1/cinelerra/wintv.C
 create mode 100644 cinelerra-5.1/cinelerra/wintv.h
 create mode 100644 cinelerra-5.1/cinelerra/wintv.inc
 create mode 120000 cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_nested.png
 create mode 120000 cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_clip.png
 create mode 120000 cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_fileref.png
 create mode 120000 cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_nested.png
 create mode 100644 cinelerra-5.1/thirdparty/src/em28xx-input.patch1

diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile
index e4f782d4..2efc5354 100644
--- a/cinelerra-5.1/cinelerra/Makefile
+++ b/cinelerra-5.1/cinelerra/Makefile
@@ -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 \
diff --git a/cinelerra-5.1/cinelerra/appearanceprefs.C b/cinelerra-5.1/cinelerra/appearanceprefs.C
index 086c15dc..b3718b75 100644
--- a/cinelerra-5.1/cinelerra/appearanceprefs.C
+++ b/cinelerra-5.1/cinelerra/appearanceprefs.C
@@ -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"))
diff --git a/cinelerra-5.1/cinelerra/appearanceprefs.h b/cinelerra-5.1/cinelerra/appearanceprefs.h
index 2099c054..6c2473d6 100644
--- a/cinelerra-5.1/cinelerra/appearanceprefs.h
+++ b/cinelerra-5.1/cinelerra/appearanceprefs.h
@@ -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:
diff --git a/cinelerra-5.1/cinelerra/appearanceprefs.inc b/cinelerra-5.1/cinelerra/appearanceprefs.inc
index 644c2bc1..6b117a93 100644
--- a/cinelerra-5.1/cinelerra/appearanceprefs.inc
+++ b/cinelerra-5.1/cinelerra/appearanceprefs.inc
@@ -44,6 +44,7 @@ class ViewViconModeItem;
 class UseTipWindow;
 class UseWarnIndecies;
 class UseWarnVersion;
+class UseWarnStack;
 class BD_WarnRoot;
 class PopupMenuBtnup;
 class GrabFocusPolicy;
diff --git a/cinelerra-5.1/cinelerra/assetedit.C b/cinelerra-5.1/cinelerra/assetedit.C
index c8ff4a9f..6222f1c6 100644
--- a/cinelerra-5.1/cinelerra/assetedit.C
+++ b/cinelerra-5.1/cinelerra/assetedit.C
@@ -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();
diff --git a/cinelerra-5.1/cinelerra/assetpopup.C b/cinelerra-5.1/cinelerra/assetpopup.C
index f4364542..51e3f886 100644
--- a/cinelerra-5.1/cinelerra/assetpopup.C
+++ b/cinelerra-5.1/cinelerra/assetpopup.C
@@ -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();
diff --git a/cinelerra-5.1/cinelerra/assetpopup.h b/cinelerra-5.1/cinelerra/assetpopup.h
index 5620e561..c948e0e1 100644
--- a/cinelerra-5.1/cinelerra/assetpopup.h
+++ b/cinelerra-5.1/cinelerra/assetpopup.h
@@ -273,7 +273,6 @@ public:
 	AssetSnapshot *asset_snapshot;
 	AssetGrabshot *asset_grabshot;
 	AssetSelectUsed *select_used;
-	int shots_displayed;
 };
 
 class AssetPopupLoadFile : public BC_MenuItem
diff --git a/cinelerra-5.1/cinelerra/awindowgui.C b/cinelerra-5.1/cinelerra/awindowgui.C
index 9cf49999..cabbbc06 100644
--- a/cinelerra-5.1/cinelerra/awindowgui.C
+++ b/cinelerra-5.1/cinelerra/awindowgui.C
@@ -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);
 		}
 	}
diff --git a/cinelerra-5.1/cinelerra/clipedls.h b/cinelerra-5.1/cinelerra/clipedls.h
index e64a0c94..ee2467aa 100644
--- a/cinelerra-5.1/cinelerra/clipedls.h
+++ b/cinelerra-5.1/cinelerra/clipedls.h
@@ -1,6 +1,5 @@
-#ifndef NESTEDEDLS_H
-#define NESTEDEDLS_H
-
+#ifndef __CLIP_EDLS_H__
+#define __CLIP_EDLS_H__
 
 #include "arraylist.h"
 #include "edl.inc"
diff --git a/cinelerra-5.1/cinelerra/clippopup.C b/cinelerra-5.1/cinelerra/clippopup.C
index cbff1d70..65eebb61 100644
--- a/cinelerra-5.1/cinelerra/clippopup.C
+++ b/cinelerra-5.1/cinelerra/clippopup.C
@@ -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;
diff --git a/cinelerra-5.1/cinelerra/convert.C b/cinelerra-5.1/cinelerra/convert.C
index 18791e1e..80694ef6 100644
--- a/cinelerra-5.1/cinelerra/convert.C
+++ b/cinelerra-5.1/cinelerra/convert.C
@@ -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
diff --git a/cinelerra-5.1/cinelerra/cwindow.C b/cinelerra-5.1/cinelerra/cwindow.C
index 0ba2530d..bb8df6ea 100644
--- a/cinelerra-5.1/cinelerra/cwindow.C
+++ b/cinelerra-5.1/cinelerra/cwindow.C
@@ -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; }
diff --git a/cinelerra-5.1/cinelerra/cwindow.h b/cinelerra-5.1/cinelerra/cwindow.h
index 2eaad4b3..643c34bc 100644
--- a/cinelerra-5.1/cinelerra/cwindow.h
+++ b/cinelerra-5.1/cinelerra/cwindow.h
@@ -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
diff --git a/cinelerra-5.1/cinelerra/editpopup.C b/cinelerra-5.1/cinelerra/editpopup.C
index 11299c29..e0c40b9c 100644
--- a/cinelerra-5.1/cinelerra/editpopup.C
+++ b/cinelerra-5.1/cinelerra/editpopup.C
@@ -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')
 {
diff --git a/cinelerra-5.1/cinelerra/editpopup.h b/cinelerra-5.1/cinelerra/editpopup.h
index ce16db69..d8987a7c 100644
--- a/cinelerra-5.1/cinelerra/editpopup.h
+++ b/cinelerra-5.1/cinelerra/editpopup.h
@@ -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
diff --git a/cinelerra-5.1/cinelerra/editpopup.inc b/cinelerra-5.1/cinelerra/editpopup.inc
index c5c69ea8..969625ef 100644
--- a/cinelerra-5.1/cinelerra/editpopup.inc
+++ b/cinelerra-5.1/cinelerra/editpopup.inc
@@ -23,6 +23,7 @@
 #define __EDITPOPUP_INC__
 
 class EditPopup;
+class EditPopupOpenEDL;
 class EditPopupClearSelect;
 class EditPopupCopy;
 class EditPopupCopyPack;
diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C
index b46a4102..c4576c99 100644
--- a/cinelerra-5.1/cinelerra/edl.C
+++ b/cinelerra-5.1/cinelerra/edl.C
@@ -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") ) {
diff --git a/cinelerra-5.1/cinelerra/edlsession.C b/cinelerra-5.1/cinelerra/edlsession.C
index 5aef800d..90a5319c 100644
--- a/cinelerra-5.1/cinelerra/edlsession.C
+++ b/cinelerra-5.1/cinelerra/edlsession.C
@@ -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);
diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C
index fe5b9f59..1fec188e 100644
--- a/cinelerra-5.1/cinelerra/file.C
+++ b/cinelerra-5.1/cinelerra/file.C
@@ -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");
 }
diff --git a/cinelerra-5.1/cinelerra/file.inc b/cinelerra-5.1/cinelerra/file.inc
index 3d5f07ad..748ce065 100644
--- a/cinelerra-5.1/cinelerra/file.inc
+++ b/cinelerra-5.1/cinelerra/file.inc
@@ -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
index 00000000..ab8ecd7f
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/fileref.C
@@ -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
index 00000000..7f4d67f2
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/fileref.h
@@ -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
diff --git a/cinelerra-5.1/cinelerra/filexml.h b/cinelerra-5.1/cinelerra/filexml.h
index 602a411e..eb0b514a 100644
--- a/cinelerra-5.1/cinelerra/filexml.h
+++ b/cinelerra-5.1/cinelerra/filexml.h
@@ -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;
 };
diff --git a/cinelerra-5.1/cinelerra/loadfile.C b/cinelerra-5.1/cinelerra/loadfile.C
index c65a9a28..1b86ae7b 100644
--- a/cinelerra-5.1/cinelerra/loadfile.C
+++ b/cinelerra-5.1/cinelerra/loadfile.C
@@ -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;
diff --git a/cinelerra-5.1/cinelerra/loadfile.h b/cinelerra-5.1/cinelerra/loadfile.h
index ef1a8e05..ba0974aa 100644
--- a/cinelerra-5.1/cinelerra/loadfile.h
+++ b/cinelerra-5.1/cinelerra/loadfile.h
@@ -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;
 };
diff --git a/cinelerra-5.1/cinelerra/loadmode.C b/cinelerra-5.1/cinelerra/loadmode.C
index 04b35ee6..04193b23 100644
--- a/cinelerra-5.1/cinelerra/loadmode.C
+++ b/cinelerra-5.1/cinelerra/loadmode.C
@@ -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;
 }
 
diff --git a/cinelerra-5.1/cinelerra/loadmode.h b/cinelerra-5.1/cinelerra/loadmode.h
index 2f358fca..61009f4e 100644
--- a/cinelerra-5.1/cinelerra/loadmode.h
+++ b/cinelerra-5.1/cinelerra/loadmode.h
@@ -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;
 };
diff --git a/cinelerra-5.1/cinelerra/loadmode.inc b/cinelerra-5.1/cinelerra/loadmode.inc
index d0b7aaee..e53fc3e2 100644
--- a/cinelerra-5.1/cinelerra/loadmode.inc
+++ b/cinelerra-5.1/cinelerra/loadmode.inc
@@ -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
diff --git a/cinelerra-5.1/cinelerra/main.C b/cinelerra-5.1/cinelerra/main.C
index 4b04a11b..42207c55 100644
--- a/cinelerra-5.1/cinelerra/main.C
+++ b/cinelerra-5.1/cinelerra/main.C
@@ -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));
diff --git a/cinelerra-5.1/cinelerra/mainindexes.C b/cinelerra-5.1/cinelerra/mainindexes.C
index 05812bb7..1cdf9223 100644
--- a/cinelerra-5.1/cinelerra/mainindexes.C
+++ b/cinelerra-5.1/cinelerra/mainindexes.C
@@ -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
diff --git a/cinelerra-5.1/cinelerra/mainindexes.h b/cinelerra-5.1/cinelerra/mainindexes.h
index 810dcd87..070a5fe1 100644
--- a/cinelerra-5.1/cinelerra/mainindexes.h
+++ b/cinelerra-5.1/cinelerra/mainindexes.h
@@ -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();
diff --git a/cinelerra-5.1/cinelerra/mainundo.C b/cinelerra-5.1/cinelerra/mainundo.C
index ba9b6c33..520bc2ee 100644
--- a/cinelerra-5.1/cinelerra/mainundo.C
+++ b/cinelerra-5.1/cinelerra/mainundo.C
@@ -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);
diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C
index 75e3bb14..78bc2bec 100644
--- a/cinelerra-5.1/cinelerra/mwindow.C
+++ b/cinelerra-5.1/cinelerra/mwindow.C
@@ -130,6 +130,7 @@
 #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 ) {
diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h
index a38d057d..b7034d8d 100644
--- a/cinelerra-5.1/cinelerra/mwindow.h
+++ b/cinelerra-5.1/cinelerra/mwindow.h
@@ -102,6 +102,7 @@
 #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
diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C
index 94d8c4b5..f32413ac 100644
--- a/cinelerra-5.1/cinelerra/mwindowedit.C
+++ b/cinelerra-5.1/cinelerra/mwindowedit.C
@@ -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;
 	}
 
diff --git a/cinelerra-5.1/cinelerra/mwindowgui.C b/cinelerra-5.1/cinelerra/mwindowgui.C
index 65ad9750..69204d9c 100644
--- a/cinelerra-5.1/cinelerra/mwindowgui.C
+++ b/cinelerra-5.1/cinelerra/mwindowgui.C
@@ -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__);
diff --git a/cinelerra-5.1/cinelerra/mwindowgui.h b/cinelerra-5.1/cinelerra/mwindowgui.h
index 4ba7c16e..4ac94fed 100644
--- a/cinelerra-5.1/cinelerra/mwindowgui.h
+++ b/cinelerra-5.1/cinelerra/mwindowgui.h
@@ -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
diff --git a/cinelerra-5.1/cinelerra/preferences.C b/cinelerra-5.1/cinelerra/preferences.C
index 02bccb13..30a99ca3 100644
--- a/cinelerra-5.1/cinelerra/preferences.C
+++ b/cinelerra-5.1/cinelerra/preferences.C
@@ -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);
diff --git a/cinelerra-5.1/cinelerra/preferences.h b/cinelerra-5.1/cinelerra/preferences.h
index bbd41964..3b46f5f9 100644
--- a/cinelerra-5.1/cinelerra/preferences.h
+++ b/cinelerra-5.1/cinelerra/preferences.h
@@ -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;
diff --git a/cinelerra-5.1/cinelerra/proxy.C b/cinelerra-5.1/cinelerra/proxy.C
index 522287bd..3165ad0e 100644
--- a/cinelerra-5.1/cinelerra/proxy.C
+++ b/cinelerra-5.1/cinelerra/proxy.C
@@ -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
diff --git a/cinelerra-5.1/cinelerra/record.C b/cinelerra-5.1/cinelerra/record.C
index c788340e..c2aab72b 100644
--- a/cinelerra-5.1/cinelerra/record.C
+++ b/cinelerra-5.1/cinelerra/record.C
@@ -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
diff --git a/cinelerra-5.1/cinelerra/record.h b/cinelerra-5.1/cinelerra/record.h
index 76e1bd52..480b3329 100644
--- a/cinelerra-5.1/cinelerra/record.h
+++ b/cinelerra-5.1/cinelerra/record.h
@@ -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
diff --git a/cinelerra-5.1/cinelerra/remotecontrol.C b/cinelerra-5.1/cinelerra/remotecontrol.C
index bb61eb27..de2bc271 100644
--- a/cinelerra-5.1/cinelerra/remotecontrol.C
+++ b/cinelerra-5.1/cinelerra/remotecontrol.C
@@ -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;
diff --git a/cinelerra-5.1/cinelerra/remotecontrol.h b/cinelerra-5.1/cinelerra/remotecontrol.h
index d2b96ed6..1a50d999 100644
--- a/cinelerra-5.1/cinelerra/remotecontrol.h
+++ b/cinelerra-5.1/cinelerra/remotecontrol.h
@@ -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();
diff --git a/cinelerra-5.1/cinelerra/setformat.C b/cinelerra-5.1/cinelerra/setformat.C
index ba894a86..cfd43685 100644
--- a/cinelerra-5.1/cinelerra/setformat.C
+++ b/cinelerra-5.1/cinelerra/setformat.C
@@ -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
index 00000000..5e067936
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/wintv.C
@@ -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
index 00000000..cefb6440
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/wintv.h
@@ -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
index 00000000..744a6ac3
--- /dev/null
+++ b/cinelerra-5.1/cinelerra/wintv.inc
@@ -0,0 +1,9 @@
+#ifndef __WINTV_INC__
+#define __WINTV_INC__
+
+class WinTV;
+class WinTVRemote;
+class WinTVCWindowHandler;
+class WinTVRecordHandler;
+
+#endif
diff --git a/cinelerra-5.1/configure.ac b/cinelerra-5.1/configure.ac
index 4c1b8f07..e2360c0a 100644
--- a/cinelerra-5.1/configure.ac
+++ b/cinelerra-5.1/configure.ac
@@ -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"
diff --git a/cinelerra-5.1/guicast/bcfilebox.C b/cinelerra-5.1/guicast/bcfilebox.C
index 9b3b6c89..cbb5168e 100644
--- a/cinelerra-5.1/guicast/bcfilebox.C
+++ b/cinelerra-5.1/guicast/bcfilebox.C
@@ -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;
 }
 
diff --git a/cinelerra-5.1/guicast/bcmenuitem.C b/cinelerra-5.1/guicast/bcmenuitem.C
index 6653b14f..f672e773 100644
--- a/cinelerra-5.1/guicast/bcmenuitem.C
+++ b/cinelerra-5.1/guicast/bcmenuitem.C
@@ -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;
diff --git a/cinelerra-5.1/guicast/bcmenuitem.h b/cinelerra-5.1/guicast/bcmenuitem.h
index 5c04b0fa..e167b983 100644
--- a/cinelerra-5.1/guicast/bcmenuitem.h
+++ b/cinelerra-5.1/guicast/bcmenuitem.h
@@ -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
diff --git a/cinelerra-5.1/guicast/bcmenupopup.C b/cinelerra-5.1/guicast/bcmenupopup.C
index 2c72354e..c35b2fa5 100644
--- a/cinelerra-5.1/guicast/bcmenupopup.C
+++ b/cinelerra-5.1/guicast/bcmenupopup.C
@@ -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;
 }
diff --git a/cinelerra-5.1/guicast/bcmenupopup.h b/cinelerra-5.1/guicast/bcmenupopup.h
index acd48d5e..f5024a6d 100644
--- a/cinelerra-5.1/guicast/bcmenupopup.h
+++ b/cinelerra-5.1/guicast/bcmenupopup.h
@@ -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];
diff --git a/cinelerra-5.1/plugins/colorbalance/colorbalance.C b/cinelerra-5.1/plugins/colorbalance/colorbalance.C
index 338466ca..8d0dc3a9 100644
--- a/cinelerra-5.1/plugins/colorbalance/colorbalance.C
+++ b/cinelerra-5.1/plugins/colorbalance/colorbalance.C
@@ -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) \
diff --git a/cinelerra-5.1/plugins/theme_blond/blondtheme.C b/cinelerra-5.1/plugins/theme_blond/blondtheme.C
index 38daf1e4..71c647ae 100644
--- a/cinelerra-5.1/plugins/theme_blond/blondtheme.C
+++ b/cinelerra-5.1/plugins/theme_blond/blondtheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blond/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blond_cv/blondcvtheme.C b/cinelerra-5.1/plugins/theme_blond_cv/blondcvtheme.C
index 97b9f400..c4666b70 100644
--- a/cinelerra-5.1/plugins/theme_blond_cv/blondcvtheme.C
+++ b/cinelerra-5.1/plugins/theme_blond_cv/blondcvtheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blond_cv/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blue/bluetheme.C b/cinelerra-5.1/plugins/theme_blue/bluetheme.C
index e06eb81c..adbc6003 100644
--- a/cinelerra-5.1/plugins/theme_blue/bluetheme.C
+++ b/cinelerra-5.1/plugins/theme_blue/bluetheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blue/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_blue_dot/bluedottheme.C b/cinelerra-5.1/plugins/theme_blue_dot/bluedottheme.C
index def4e988..e00a45e8 100644
--- a/cinelerra-5.1/plugins/theme_blue_dot/bluedottheme.C
+++ b/cinelerra-5.1/plugins/theme_blue_dot/bluedottheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_blue_dot/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_bright/brighttheme.C b/cinelerra-5.1/plugins/theme_bright/brighttheme.C
index 1a270fcd..132e70c4 100644
--- a/cinelerra-5.1/plugins/theme_bright/brighttheme.C
+++ b/cinelerra-5.1/plugins/theme_bright/brighttheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_bright/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_cakewalk/cakewalk.C b/cinelerra-5.1/plugins/theme_cakewalk/cakewalk.C
index 7145dd5c..bb3a0018 100644
--- a/cinelerra-5.1/plugins/theme_cakewalk/cakewalk.C
+++ b/cinelerra-5.1/plugins/theme_cakewalk/cakewalk.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_cakewalk/data/loadmode_edl_nested.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_hulk/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_hulk/hulktheme.C b/cinelerra-5.1/plugins/theme_hulk/hulktheme.C
index 5618ba8d..be173bcd 100644
--- a/cinelerra-5.1/plugins/theme_hulk/hulktheme.C
+++ b/cinelerra-5.1/plugins/theme_hulk/hulktheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_neophyte/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_neophyte/neophyte.C b/cinelerra-5.1/plugins/theme_neophyte/neophyte.C
index b6ca90fe..8cb04d01 100644
--- a/cinelerra-5.1/plugins/theme_neophyte/neophyte.C
+++ b/cinelerra-5.1/plugins/theme_neophyte/neophyte.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_pinklady/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_pinklady/pinkladytheme.C b/cinelerra-5.1/plugins/theme_pinklady/pinkladytheme.C
index e206eed1..bca5c59b 100644
--- a/cinelerra-5.1/plugins/theme_pinklady/pinkladytheme.C
+++ b/cinelerra-5.1/plugins/theme_pinklady/pinkladytheme.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_suv/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_suv/suv.C b/cinelerra-5.1/plugins/theme_suv/suv.C
index fc3e618a..73ea0a2f 100644
--- a/cinelerra-5.1/plugins/theme_suv/suv.C
+++ b/cinelerra-5.1/plugins/theme_suv/suv.C
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_clip.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_fileref.png
@@ -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
index 00000000..f8538581
--- /dev/null
+++ b/cinelerra-5.1/plugins/theme_unflat/data/loadmode_edl_nested.png
@@ -0,0 +1 @@
+loadmode_nested.png
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/theme_unflat/unflattheme.C b/cinelerra-5.1/plugins/theme_unflat/unflattheme.C
index 33953a6b..4f537a16 100644
--- a/cinelerra-5.1/plugins/theme_unflat/unflattheme.C
+++ b/cinelerra-5.1/plugins/theme_unflat/unflattheme.C
@@ -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
index 00000000..1a19f0c7
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/em28xx-input.patch1
@@ -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)
-- 
2.26.2