add haupauge-1657 dual usb capture support, add deinterlace to recordmonitor, asset...
authorGood Guy <[email protected]>
Thu, 26 Dec 2019 02:57:42 +0000 (19:57 -0700)
committerGood Guy <[email protected]>
Thu, 26 Dec 2019 02:57:42 +0000 (19:57 -0700)
15 files changed:
cinelerra-5.1/cinelerra/assetpopup.C
cinelerra-5.1/cinelerra/assetpopup.h
cinelerra-5.1/cinelerra/assetpopup.inc
cinelerra-5.1/cinelerra/clippopup.C
cinelerra-5.1/cinelerra/clippopup.h
cinelerra-5.1/cinelerra/clippopup.inc
cinelerra-5.1/cinelerra/devicedvbinput.C
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindowgui.C
cinelerra-5.1/cinelerra/record.C
cinelerra-5.1/cinelerra/record.h
cinelerra-5.1/cinelerra/recordgui.C
cinelerra-5.1/cinelerra/recordgui.h
cinelerra-5.1/cinelerra/recordmonitor.C

index d8142f02606b69a93f8c47de21974fdae712b72a..f4364542542808acfe1a6276a8f2c19ffd8b6cdd 100644 (file)
@@ -77,6 +77,7 @@ void AssetPopup::create_objects()
        add_item(info = new AssetPopupInfo(mwindow, this));
        add_item(format = new AWindowListFormat(mwindow, gui));
        add_item(open_edl = new AssetPopupOpenEDL(mwindow, this));
+       add_item(close_edl = new AssetPopupCloseEDL(mwindow, gui));
        add_item(to_clip = new AssetPopupToClip(mwindow, this));
        add_item(sort = new AssetPopupSort(mwindow, this));
        add_item(index = new AssetPopupBuildIndex(mwindow, this));
@@ -207,6 +208,26 @@ int AssetPopupOpenEDL::handle_event()
        return 1;
 }
 
+AssetPopupCloseEDL::AssetPopupCloseEDL(MWindow *mwindow, AWindowGUI *gui)
+ : BC_MenuItem(_("Close EDL"))
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+}
+AssetPopupCloseEDL::~AssetPopupCloseEDL()
+{
+}
+
+int AssetPopupCloseEDL::handle_event()
+{
+       gui->unlock_window();
+       mwindow->gui->lock_window("AssetPopupCloseEDL::handle_event");
+       mwindow->stack_pop();
+       mwindow->gui->unlock_window();
+       gui->lock_window("AssetPopupCloseEDL::handle_event");
+       return 1;
+}
+
 
 AssetPopupToClip::AssetPopupToClip(MWindow *mwindow, AssetPopup *popup)
  : BC_MenuItem(_("EDL to clip"))
@@ -473,6 +494,7 @@ void AssetListMenu::create_objects()
 {
        add_item(load_file = new AssetPopupLoadFile(mwindow, gui));
        add_item(format = new AWindowListFormat(mwindow, gui));
+       add_item(close_edl = new AssetPopupCloseEDL(mwindow, gui));
        add_item(select_used = new AssetSelectUsed(mwindow, gui));
        BC_SubMenu *submenu;
        select_used->add_submenu(submenu = new BC_SubMenu());
index 22624e474bc0bc83633ad00d90f4e6939108cb2d..5620e561b1274eb74569de88cdbc1832c91c224d 100644 (file)
@@ -53,6 +53,7 @@ public:
        AssetPopupInfo *info;
        AWindowListFormat *format;
        AssetPopupOpenEDL *open_edl;
+       AssetPopupCloseEDL *close_edl;
        AssetPopupToClip *to_clip;
        AssetPopupSort *sort;
        AssetPopupBuildIndex *index;
@@ -88,6 +89,18 @@ public:
        AssetPopup *popup;
 };
 
+class AssetPopupCloseEDL : public BC_MenuItem
+{
+public:
+       AssetPopupCloseEDL(MWindow *mwindow, AWindowGUI *gui);
+       ~AssetPopupCloseEDL();
+
+       int handle_event();
+
+       MWindow *mwindow;
+       AWindowGUI *gui;
+};
+
 class AssetPopupToClip : public BC_MenuItem
 {
 public:
@@ -256,6 +269,7 @@ public:
        AWindowGUI *gui;
        AssetPopupLoadFile *load_file;
        AWindowListFormat *format;
+       AssetPopupCloseEDL *close_edl;
        AssetSnapshot *asset_snapshot;
        AssetGrabshot *asset_grabshot;
        AssetSelectUsed *select_used;
index 096c729b6dd10860617aaaed4df8d090caba525b..7136d07a30fa66390b1d591a3ce13c21e340271b 100644 (file)
@@ -35,6 +35,7 @@
 class AssetPopup;
 class AssetPopupInfo;
 class AssetPopupOpenEDL;
+class AssetPopupCloseEDL;
 class AssetPopupToClip;
 class AssetPopupSort;
 class AssetPopupBuildIndex;
index c38efd99d71584d035c451b8ef6453c197463638..cbff1d707a9bc80530051bb188bf2bc77126c98b 100644 (file)
@@ -67,6 +67,7 @@ void ClipPopup::create_objects()
        add_item(format = new AWindowListFormat(mwindow, gui));
        add_item(sort = new ClipPopupSort(mwindow, this));
        add_item(open_edl = new ClipPopupOpenEDL(mwindow, this));
+       add_item(close_edl = new ClipPopupCloseEDL(mwindow, gui));
        add_item(to_media = new ClipPopupToMedia(mwindow, this));
        add_item(view = new ClipPopupView(mwindow, this));
        add_item(view_window = new ClipPopupViewWindow(mwindow, this));
@@ -406,6 +407,7 @@ ClipListMenu::~ClipListMenu()
 void ClipListMenu::create_objects()
 {
        add_item(format = new AWindowListFormat(mwindow, gui));
+       add_item(close_edl = new ClipPopupCloseEDL(mwindow, gui));
        add_item(new AWindowListSort(mwindow, gui));
        add_item(new ClipPasteToFolder(mwindow));
        update();
@@ -460,3 +462,23 @@ int ClipPopupOpenEDL::handle_event()
        return 1;
 }
 
+ClipPopupCloseEDL::ClipPopupCloseEDL(MWindow *mwindow, AWindowGUI *gui)
+ : BC_MenuItem(_("Close EDL"))
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+}
+ClipPopupCloseEDL::~ClipPopupCloseEDL()
+{
+}
+
+int ClipPopupCloseEDL::handle_event()
+{
+       gui->unlock_window();
+       mwindow->gui->lock_window("ClipPopupCloseEDL::handle_event");
+       mwindow->stack_pop();
+       mwindow->gui->unlock_window();
+       gui->lock_window("ClipPopupCloseEDL::handle_event");
+       return 1;
+}
+
index c09508aacf0b9bf28b675464442d10627245bf00..6f09598ea6786a330215a06df9e6b185cd1395b5 100644 (file)
@@ -54,6 +54,7 @@ public:
        AWindowListFormat *format;
        ClipPopupSort *sort;
        ClipPopupOpenEDL *open_edl;
+       ClipPopupCloseEDL *close_edl;
        ClipPopupView *view;
        ClipPopupViewWindow *view_window;
        ClipPopupCopy *copy;
@@ -209,6 +210,7 @@ public:
        void create_objects();
        void update();
        AWindowListFormat *format;
+       ClipPopupCloseEDL *close_edl;
        MWindow *mwindow;
        AWindowGUI *gui;
 };
@@ -237,4 +239,16 @@ public:
        ClipPopup *popup;
 };
 
+class ClipPopupCloseEDL : public BC_MenuItem
+{
+public:
+       ClipPopupCloseEDL(MWindow *mwindow, AWindowGUI *gui);
+       ~ClipPopupCloseEDL();
+
+       int handle_event();
+
+       MWindow *mwindow;
+       AWindowGUI *gui;
+};
+
 #endif
index 21399eaf613eba3a2239321deb37407efc7e356e..8932c9a10d0099aba81706c3beec845b091de1be 100644 (file)
@@ -38,5 +38,6 @@ class ClipListFormat;
 class ClipListMenu;
 class ClipPopupToMedia;
 class ClipPopupOpenEDL;
+class ClipPopupCloseEDL;
 
 #endif
index 7943108949682fd287a621eb4e1915b9fec80aba..d7bc60b8d06791c7082a0ec09e950676731eb699 100644 (file)
@@ -488,7 +488,7 @@ int DeviceDVBInput::dvb_status()
        signal_ber = ioctl(fe, FE_READ_BER, &rate) ? -1 : rate;
        uint32_t errs = 0;
        signal_unc = ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &errs) ? -1 : errs;
-       if( signal_lck && signal_ber >= 0 && signal_ber < 255 ) locked = 1;
+       if( signal_lck && signal_ber < 255 ) locked = 1;
        if( dvb_locked != locked ) {
                printf(_("** %scarrier, dvb_locked %s\n"),
                         signal_crr ? "" : _("no "), locked ? _("lock") : _("lost") );
index dbda78c10612085bb960d17727ae60bf2fe7b4a3..b46a4102d35b5abae035e4d3d2fdf1f710950c1c 100644 (file)
@@ -664,14 +664,19 @@ void EDL::create_nested(EDL *nested)
 void EDL::overwrite_clip(EDL *clip)
 {
        int folder = folder_no;
-       char clip_title[BCTEXTLEN];  strcpy(clip_title, local_session->clip_title);
-       char clip_notes[BCTEXTLEN];  strcpy(clip_notes, local_session->clip_notes);
-       char clip_icon[BCSTRLEN];    strcpy(clip_icon,  local_session->clip_icon);
+       char clip_title[BCTEXTLEN], clip_notes[BCTEXTLEN], clip_icon[BCSTRLEN];
+       if( parent_edl ) {
+               strcpy(clip_title, local_session->clip_title);
+               strcpy(clip_notes, local_session->clip_notes);
+               strcpy(clip_icon,  local_session->clip_icon);
+       }
        copy_all(clip);
        folder_no = folder;
-       strcpy(local_session->clip_title, clip_title);
-       strcpy(local_session->clip_notes, clip_notes);
-       strcpy(local_session->clip_icon, clip_icon);
+       if( parent_edl ) {
+               strcpy(local_session->clip_title, clip_title);
+               strcpy(local_session->clip_notes, clip_notes);
+               strcpy(local_session->clip_icon, clip_icon);
+       }
        if( !clip_icon[0] ) return;
 // discard old clip icon to reconstruct 
        char clip_icon_path[BCTEXTLEN];
index 8d27ff96c603cfad465ab33b760a9d4d78192bc9..39c996433da4473abcbfeea39961dcfe64d6dc64 100644 (file)
@@ -3761,7 +3761,7 @@ void MWindow::stack_pop()
        forget_nested_edl(edl);
        StackItem &item = stack.last();
 // session edl replaced, overwrite and save clip data
-       if( item.new_edl != edl && item.new_edl->parent_edl )
+       if( item.new_edl != edl )
                item.new_edl->overwrite_clip(edl);
        edl->remove_user();
        edl = item.edl;
@@ -3802,11 +3802,14 @@ void MWindow::clip_to_media()
                EDL *clip = session->drag_clips->values[i];
                time_t dt;      time(&dt);
                struct tm dtm;  localtime_r(&dt, &dtm);
-               char path[BCSTRLEN], *cp = path, *ep = cp+sizeof(path)-1;
+               char path[BCTEXTLEN], *cp = path, *ep = cp+sizeof(path)-1;
+// path_basename = "Nested_<date>-<time>_<basename>"
                cp += snprintf(cp, ep-cp, _("Nested_%02d%02d%02d-%02d%02d%02d_"),
                        dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
                        dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
-               cp += snprintf(cp, ep-cp, clip->local_session->clip_title);
+               char *bp = strrchr(clip->local_session->clip_title, '/');
+               bp = bp ? bp+1 : clip->local_session->clip_title;
+               cp += snprintf(cp, ep-cp, "%s", bp);
                EDL *nested = edl->new_nested_edl(clip, path);
                edl->clips.remove(clip);
                clip->remove_user();
index e295c1508a6e1827518a3db5ef3dbf071285ceb2..65ad9750f480bef49432a8b825fa94fd57c152a7 100644 (file)
@@ -2306,11 +2306,12 @@ StackButton::StackButton(MWindow *mwindow, int x, int y)
  : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
 {
        this->mwindow = mwindow;
-       set_tooltip(_("Return to previous EDL"));
+       set_tooltip(_("Close EDL"));
 }
 
 int StackButton::handle_event()
 {
+       mwindow->save_backup();
        mwindow->stack_pop();
        return 1;
 }
@@ -2322,11 +2323,6 @@ void StackButton::update()
        sprintf(text, "%d", i);
        set_text(text);
        draw_face();
-       int hidden = is_hidden();
-       if( !i && !hidden )
-               hide_window();
-       else if( hidden )
-               show_window();
 }
 
 
index dd587a5e568a514089b53df1eff24f893d1e2409..c788340eb2eba04c21a51aca5f4985caf29290ef 100644 (file)
@@ -160,6 +160,7 @@ Record::Record(MWindow *mwindow, RecordMenuItem *menu_item)
        cutads_status = new RecordCutAdsStatus(this);
        blink_status = new RecordBlinkStatus(this);
 #endif
+       deinterlace = RECORD_LACE_ODD;
 }
 
 Record::~Record()
@@ -234,6 +235,7 @@ int Record::load_defaults()
        video_zoom = defaults->get("RECORD_VIDEO_Z", (float)1);
        picture->load_defaults();
        reverse_interlace = defaults->get("REVERSE_INTERLACE", 0);
+       deinterlace = defaults->get("DEINTERLACE", RECORD_LACE_ODD);
        do_cursor = defaults->get("RECORD_CURSOR", 0);
        do_big_cursor = defaults->get("RECORD_BIG_CURSOR", 0);
        for( int i=0; i<MAXCHANNELS; ++i ) {
@@ -272,6 +274,7 @@ int Record::save_defaults()
        defaults->update("RECORD_VIDEO_Z", video_zoom);
        picture->save_defaults();
        defaults->update("REVERSE_INTERLACE", reverse_interlace);
+       defaults->update("DEINTERLACE", deinterlace);
        defaults->update("RECORD_CURSOR", do_cursor);
        defaults->update("RECORD_BIG_CURSOR", do_big_cursor);
        for( int i=0; i<MAXCHANNELS; ++i ) {
index d8fb0102cb2d5e9384ed3b813028abdea278837b..76e1bd52876ab4c169dec76cfe28b79e0e9503da 100644 (file)
 
 #define SESSION (mwindow->edl->session)
 
+#define RECORD_LACE_NONE 0
+#define RECORD_LACE_ODD 1
+#define RECORD_LACE_EVEN 2
+
 class Record;
 
 class RecordMenuItem : public BC_MenuItem
@@ -328,6 +332,7 @@ public:
        int video_window_w;       // Width of record video window
        int dropped, behind;
        int input_threads_pausing;
+       int deinterlace;
 };
 
 class RecordScheduleItem {
index 1f5b392153591117e63353d3d4bf7d82a8680768..c2fbe0ecf2c2a1bc7ba6c4c096feb0ee65bfacbe 100644 (file)
@@ -385,6 +385,11 @@ void RecordGUI::create_objects()
        add_subwindow(power_off = new RecordGUIPowerOff(this, x1, y1));
        x1 += power_off->get_w() + xs10;
        add_subwindow(commercial_check = new RecordGUICommCheck(this, x1, y1));
+       x1 += commercial_check->get_w() + xs30;
+       add_subwindow(deinterlace = new RecordGUIDeinterlace(this, x1, y1));
+       deinterlace->create_objects();
+       x1 += deinterlace->get_w() + xs5;
+       add_subwindow(new BC_Title(x1, y1, _("deinterlace")));
 
 // Batches
        x = xs10;
@@ -424,6 +429,7 @@ void RecordGUI::create_objects()
                batch_duration->enable();
        else
                batch_duration->disable();
+       show_window(1);
        unlock_window();
 }
 
@@ -729,7 +735,6 @@ int RecordGUICommCheck::handle_event()
        return 1;
 }
 
-
 int RecordGUICommCheck::keypress_event()
 {
        if( get_keypress() == caption[0] ) {
@@ -742,6 +747,44 @@ int RecordGUICommCheck::keypress_event()
 }
 
 
+RecordGUIDelaceItem::RecordGUIDelaceItem(RecordGUIDeinterlace *popup,
+               const char *text, int id)
+ : BC_MenuItem(text)
+{
+       this->popup = popup;
+       this->id = id;
+}
+int RecordGUIDelaceItem::handle_event()
+{
+       popup->gui->record->deinterlace = id;
+       popup->update();
+       return 1;
+}
+
+RecordGUIDeinterlace::RecordGUIDeinterlace(RecordGUI *gui, int x, int y)
+ : BC_PopupMenu(x, y, xS(24), "", 1, 0, xS(3))
+{
+       this->gui = gui;
+}
+
+void RecordGUIDeinterlace::create_objects()
+{
+       add_item(new RecordGUIDelaceItem(this, _("None"), RECORD_LACE_NONE));
+       add_item(new RecordGUIDelaceItem(this, _("Even"), RECORD_LACE_EVEN));
+       add_item(new RecordGUIDelaceItem(this, _("Odd"), RECORD_LACE_ODD));
+       update();
+}
+
+void RecordGUIDeinterlace::update()
+{
+       int v = gui->record->deinterlace;
+       for( int i=0,n=total_items(); i<n; ++i ) {
+               RecordGUIDelaceItem *item = (RecordGUIDelaceItem *)get_item(i);
+               item->set_checked(item->id == v);
+       }
+}
+
+
 RecordGUIMonitorVideo::RecordGUIMonitorVideo(RecordGUI *gui, int x, int y)
  : BC_CheckBox(x, y, gui->record->monitor_video, _("Monitor video"))
 {
index 4b506bd4a204d928a935b35c512923958264fc29..763b167e674825073ecec08417ba661e231026e5 100644 (file)
@@ -51,6 +51,8 @@ class RecordGUIDropFrames;
 class RecordGUIFillFrames;
 class RecordGUIPowerOff;
 class RecordGUICommCheck;
+class RecordGUIDelaceItem;
+class RecordGUIDeinterlace;
 class RecordGUILabel;
 class RecordGUIClearLabels;
 class RecordGUILoop;
@@ -132,6 +134,7 @@ public:
        RecordGUIFillFrames *fill_frames;
        RecordGUIPowerOff *power_off;
        RecordGUICommCheck *commercial_check;
+       RecordGUIDeinterlace *deinterlace;
        RecordGUIMonitorVideo *monitor_video;
        RecordGUIMonitorAudio *monitor_audio;
        RecordGUIAudioMeters *meter_audio;
@@ -360,6 +363,26 @@ public:
        RecordGUI *gui;
 };
 
+class RecordGUIDelaceItem : public BC_MenuItem
+{
+public:
+       RecordGUIDelaceItem(RecordGUIDeinterlace *popup, const char *text, int id);
+       int handle_event();
+
+       RecordGUIDeinterlace *popup;
+       int id;
+};
+
+class RecordGUIDeinterlace : public BC_PopupMenu
+{
+public:
+       RecordGUIDeinterlace(RecordGUI *gui, int x, int y);
+       void create_objects();
+       void update();
+
+       RecordGUI *gui;
+};
+
 class RecordGUIMonitorVideo : public BC_CheckBox
 {
 public:
@@ -551,10 +574,4 @@ public:
        RecordGUI *gui;
 };
 
-
-
-
-
-
-
 #endif
index 983f53e306180424329fc1ad6aefaab4827544b0..9c4bf5eeff52c64ca51823eea7e6cae546ee9220 100644 (file)
@@ -21,6 +21,7 @@
 #include "asset.h"
 #include "bcdialog.h"
 #include "bcsignals.h"
+#include "xfer/xfer.h"
 #include "channelpicker.h"
 #include "condition.h"
 #include "cursors.h"
@@ -1067,9 +1068,74 @@ int RecordMonitorThread::render_dv()
        return 0;
 }
 
+// VFrame xfer all/odd/even inputs
 void RecordMonitorThread::render_uncompressed()
 {
-       output_frame->transfer_from(input_frame);
+       VFrame *in = input_frame, *out = output_frame;
+       out->set_timestamp(in->get_timestamp());
+       out->copy_params(in);
+
+       unsigned char *in_ptrs[4], *out_ptrs[4];
+       unsigned char **inp, **outp;
+       if( BC_CModels::is_planar(in->get_color_model()) ) {
+               in_ptrs[0] = in->get_y();
+               in_ptrs[1] = in->get_u();
+               in_ptrs[2] = in->get_v();
+               in_ptrs[3] = in->get_a();
+               inp = in_ptrs;
+       }
+       else
+               inp = in->get_rows();
+       if( BC_CModels::is_planar(out->get_color_model()) ) {
+               out_ptrs[0] = out->get_y();
+               out_ptrs[1] = out->get_u();
+               out_ptrs[2] = out->get_v();
+               out_ptrs[3] = out->get_a();
+               outp = out_ptrs;
+       }
+       else
+               outp = out->get_rows();
+
+        int out_colormodel = out->get_color_model();
+       int out_x = 0, out_y = 0;
+       int out_w = out->get_w(), out_h = out->get_h();
+       int out_rowspan = out->get_bytes_per_line();
+        int inp_colormodel = in->get_color_model();
+       int inp_x = 0, inp_y = 0;
+       int inp_w = in->get_w(), inp_h = in->get_h();
+       int inp_rowspan = in->get_bytes_per_line();
+       int bg_color = 0;
+
+        int ret = 1;
+        if( inp_w > 0 && inp_h > 0 && out_w > 0 && out_h > 0 ) {
+                BC_Xfer xfer(outp, out_colormodel, out_x, out_y, out_w, out_h, out_rowspan,
+                        inp, inp_colormodel, inp_x, inp_y, inp_w, inp_h, inp_rowspan,
+                        bg_color,0xff);
+                int *row_table = xfer.row_table;
+               switch( record->deinterlace ) {
+               case RECORD_LACE_NONE:
+                       break;
+               case RECORD_LACE_EVEN: {
+                       int inp_y1 = inp_y;
+                       for( int i=0; i<out_h; ++i ) {
+                               if( (row_table[i] &= ~1) < inp_y1 )
+                                       row_table[i] = inp_y1;
+                       }
+                       break; }
+               case RECORD_LACE_ODD: {
+                       int inp_y2 = inp_y + inp_h-1;
+                       for( int i=0; i<out_h; ++i ) {
+                               if( (row_table[i] |= 1) > inp_y2 )
+                                       row_table[i] = inp_y2;
+                       }
+                       break; }
+               }
+                ret = xfer.xfer();
+        }
+        if( ret )
+                printf("RecordMonitorThread::render_uncompressed failed: "
+                       "%d %d(%dx%d) to %d(%dx%d)\n", __LINE__,
+                        inp_colormodel, inp_w, inp_h, out_colormodel, out_w, out_h);
 }
 
 void RecordMonitorThread::show_output_frame()